Here you will find implementations details

Projects

Tracing functionality consists of following projects:

  • org.erlide.tracing - represents tracing “feature” that groups other plugins
  • org.erlide.tracing.core - plugin that provides all Java classes that interact with Eclipse through its extension points
  • org.erlide.tracing.erlang - plugin that provides Erlang helper functions for this feature (mainly used for interaction with ttb)
  • org.erlide.tracing.help - plugin that provides help pages for this feature (it contributes to Eclipse’s help system)
  • org.erlide.tracing.site - project that is used for creating update site content
  • org.erlide.tracing.ttbe - plugin that contains ttbe code (extended version of ttb that is not included in OTP yet)

Feature architecture

This feature provides three new views:

  • Erlang tracing control panel - UI for ttb, using it user can select processes and nodes that should be traced, set flags, create trace patterns,
  • Erlang trace browser - displays tracing results, using it user can load tracing results from disk
  • Erlang tracing tree viewer - displays all events from selected trace in trace browser

Those views are grouped under a new perspective called Erlang Tracing. To provide communication between all views an Observer pattern was used. Each view is represented by class that implements org.erlide.tracing.core.ITraceNodeObserver. This interface must be implemented by every class that want be notified by org.erlide.tracing.core.TraceBackend whenever some event occurs. org.erlide.tracing.core.TraceBackend is a singleton class that is responsible for creating tracing node and running tracing tool (ttb) on it. When a view is created it registers itself in org.erlide.tracing.core.TraceBackend as an listener. Following diagram shows relations between those classes: listeners

Such design makes it easy to add a new view (in future there should be added view that represents trace events in a form of sequence diagram). Every view performs action on org.erlide.tracing.core.TraceBackend (e.g. starting/stopping tracing) and this class after performing action, notifies all views (listeners) so they can update themselves.

Tree viewer

Erlang trace browser and Erlang tracing tree viewer views use JFace TreeViewer to display data. TreeViewer provides mvc architecture to raw SWT Tree class. To create a tree view you need:

  1. Create it, e.g.: new TreeViewer(container, SWT.SINGLE);
  2. Assign content provider using setContentProvider() method (Content provider is a class that provides data to be displayed).
  3. Assign label provider using setLabelProvider() method (Label provider is a class that tells tree viewer how to display each element).

You can find good example of creating tree viewer here:

Model

In tracing plugin there is an org.erlide.tracing.core.mvc.model.treenodes.ITreeNode interface which should be implemented by class that represents concrete tree node. Following class diagram shows those classes: treenodes

Most of the nodes in Erlang tracing tree viewer view are represented by TreeNode class. However nodes representing functions and modules are represented by FunctionNode and ModuleNode classes. It is because when user double-clicks on them some action should be invoked (classes are used to distinguish type of node that was selected). In Erlang trace browser view are nodes are instances of TracingResultsNode because they contain some additional information, such as path, dates and number of events. Data for each tree viewer is stored in different list. You can obtain those list from org.erlide.tracing.core.mvc.model.TraceCollections using static methods:

  • getFilesList() - data displayed in Erlang trace browser (all tracing results loaded into Eclipse)
  • getTracesList() - data displayed in Erlang tracing tree viewer (content of selected tracing result)

View

TreeContentProvider and TreeLabelProvider provide data to be displayed.

Controller

All listeners assigned to tree viewer act as controllers.

Table viewer

TableViewer is a JFace class that provides mvc architecture to raw SWT Table class. It works very similar to TreeViewer, i.e. you also have to provide label and content providers. Only difference is that some fields can be edited. In such situation you have to provide two extra classes:

  • CellEditor for each column - it allows you to modify cell’s value
  • Implementation of ICellModifier - it acts as controller for cell’s editor: reads cell’s value from model when you activate editor and saves data when you finish editing

Displaying busy dialogs

To show busy dialog you can use following code (from wikipedia):

   IRunnableWithProgress op = new IRunnableWithProgress() {
      public void run(IProgressMonitor monitor) {
         runDecathlon(monitor);
      }
   };
   IWorkbench wb = PlatformUI.getWorkbench();
   IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
   Shell shell = win != null ? win.getShell() : null;
   new ProgressMonitorDialog(shell).run(true, true, op);

In this way job is executed in new thread while execution of UI thread pauses until run method is finished (i.e. work is done). However, in tracing feature sometimes we need to show busy dialog when calling one method and hide it when another method is called. It is because of design which uses observer pattern: one view invokes an action and when this action is finished its “notify” method is invoked to signal that action is done. Consider loading files:

  1. In Erlang trace browser view user opens dialog, selects folder with tracing results and clicks ok.
  2. Browser view displays busy dialog which should be visible until loading is finished. It is to prevent user from performing other operations.
  3. TraceBackend creates listener which will receive all data from tracing node (one on which ttb runs) and tells ttb to start reading files
  4. After reading is finished TraceBackend notifies all listeners (in this case views) that it is done by calling finishLoadingFile method so each view can refresh itself if it is needed. In case of browser view it should hide busy dialog.

Similar use case is when stopping tracing.

To provide this functionality org.erlide.tracing.core.ui.dialogs.RunnableWithProgress abstract class was implemented. All work (e.g. initialize loading file) you implement in abstract method doAction() of extending class. Then you pass instance of this class to ProgressMonitorDialog.run() method and after it you put code which has to be executed when busy dialog is hidden. In method which will be called when job is done you have to call RunnableWithProgress.finish(). Here is an example:

    //create variable that represents task    
    private RunnableWithProgress task;

    //................

            public void widgetSelected(SelectionEvent e) {
                task = new RunnableWithProgress("Loading trace results...") {
                    @Override
                    public void doAction() {
                        //initialize loading
                    }
                };
                //show busy dialog
                Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
                new ProgressMonitorDialog(shell).run(true, false, task);
                //execute when dialog is hidden:
                doAfterLoadingTraces();
            }

    //................

    //called to notify that loading is finished
    public void notify() {
        if (task != null)
            task.finish();
    }

Actions

This section describes main use cases.

Starting tracing

start tracing

Stop tracing

stop tracing

Loading tracing results

load files

Activating tracing result to display in tree viewer

select results

Loading data from files to display in tree viewer

load results

UML diagrams

All UML diagrams were created using Eclipse UMLet plugin. Sources of diagrams are available in doc/uml directory of org.erlide.tracing.core project.

Did you find errors in the documentation? Do you have improvements to suggest? Suggest edits!