doc: Add developer documentation for JUL logging
[deliverable/tracecompass.git] / doc / org.eclipse.tracecompass.doc.dev / doc / Developer-Guide.mediawiki
index 281bb3b3235be7863ce35d4cf0fcbca363708d82..4e1772f6b9265e643a8d1e1571720f9f6cbebe18 100644 (file)
@@ -683,6 +683,36 @@ Several features in TMF and the Eclipse LTTng integration are using this framewo
 ** ''org.eclipse.tracecompass.tmf.ui.views.statesystem.TmfStateSystemExplorer.java''
 ** ''org.eclipse.tracecompass.analysis.os.linux.ui.views.cpuusage.CpuUsageComposite.java''
 
+== Timing Analysis Views and Viewers ==
+
+Trace Compass provides base implementations for timing views and viewers for generating Latency Tables, Scatter Charts, Density Graphs and Statistics Tables. They are well integrated with various Trace Compass features such as reading traces and time synchronization with other views. They also handle mouse events for navigating the trace and view, zooming or presenting detailed information at mouse position. The code can be found in the Analysis Timing plug-in ''org.eclipse.tracecompass.analysis.timing.ui''. See below for a list of relevant java packages:
+
+* Latency Table
+** ''org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.table'': Base classes for Latency Tables
+* Scatter Chart
+** ''org.eclipse.tracecompass.tmf.ui.views.tmfChartView.java'': Common base classes for X-Y-Chart viewers based on SWTChart
+** ''org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.scatter'': Base classes for Scatter Charts
+* Density Graph
+** ''org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.density'': Base classes for Density Graphs
+* Statistics Table
+** ''org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.statistics'': Base classes for Statistics Tables
+
+Several features in Trace Compass are using this framework and can be used as example for further development:
+
+* Latency Table
+** ''org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency.SystemCallLatencyView.java''
+** ''org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.latency.PatternLatencyTableView.java''
+* Scatter Chart
+** ''org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency.SystemCallLatencyScatterView.java''
+** ''org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.latency.PatternScatterGraphView.java''
+* Density Graph
+** ''org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency.SystemCallLatencyDensityView.java''
+** ''org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.latency.PatternDensityView.java''
+
+* Statistics Table
+** ''org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.latency.statistics.SystemCallLatencyStatisticsView.java''
+** ''org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.latency.PatternStatisticsView.java''
+
 = Component Interaction =
 
 TMF provides a mechanism for different components to interact with each other using signals. The signals can carry information that is specific to each signal.
@@ -961,6 +991,77 @@ Sent by the Stream List View when the user selects a new packet stream.
 
 Received by views that analyze packet streams.
 
+=== TmfStartAnalysisSignal ===
+
+''Purpose''
+
+This signal is used to indicate that an analysis has started.
+
+''Senders''
+
+Sent by an analysis module when it starts to execute the analyis.
+
+''Receivers''
+
+Received by components that need to be notified of the start of an analysis
+or that need to receive the analysis module.
+
+=== TmfCpuSelectedSignal ===
+
+''Purpose''
+
+This signal is used to indicate that the user has selected a CPU core.
+
+''Senders''
+
+Sent by any component that allows the user to select a CPU.
+
+''Receivers''
+
+Received by viewers that show information specific to a selected CPU.
+
+=== TmfThreadSelectedSignal ===
+
+''Purpose''
+
+This signal is used to indicate that the user has selected a thread.
+
+''Senders''
+
+Sent by any component that allows the user to select a thread.
+
+''Receivers''
+
+Received by viewers that show information specific to a selected thread.
+
+=== TmfTraceSynchronizedSignal ===
+
+''Purpose''
+
+This signal is used to indicate that trace synchronization has been completed.
+
+''Senders''
+
+Sent by the experiment after trace synchronization.
+
+''Receivers''
+
+Received by any component that needs to be notified of trace synchronization.
+
+=== TmfMarkerEventSourceUpdatedSignal ===
+
+''Purpose''
+
+This signal is used to indicate that a marker event source has been updated.
+
+''Senders''
+
+Sent by a component that has triggered a change in a marker event source.
+
+''Receivers''
+
+Received by any component that needs to refresh the markers due to the change in marker event source.
+
 == Debugging ==
 
 TMF has built-in Eclipse tracing support for the debugging of signal interaction between components. To enable it, open the '''Run/Debug Configuration...''' dialog, select a configuration, click the '''Tracing''' tab, select the plug-in '''org.eclipse.tracecompass.tmf.core''', and check the '''signal''' item.
@@ -1296,6 +1397,23 @@ analysis plugin will normally ship both the state provider and the view, and
 they will have been written by the same person. In other cases, it's possible to
 use getSubAttributes() to explore the organization of the attribute tree first.
 
+===== optQuarkAbsolute()/optQuarkRelative() =====
+
+These two methods are similar to their counterparts getQuarkAbsolute() and
+getQuarkRelative(). The only difference is that if the referenced attribute does
+not exist, the value ITmfStateSystem#INVALID_ATTRIBUTE (-2) is returned instead
+of throwing an exception.
+
+These methods should be used when the presence of the referenced attribute is
+known to be optional, to avoid the performance cost of generating exceptions.
+
+===== getQuarks() =====
+
+This method (with or without a starting node quark) takes an attribute path
+array which may contain wildcard "*" or parent ".." elements, and returns the
+list of matching attribute quarks. If no matching attribute is found, an empty
+list is returned.
+
 ===== waitUntilBuilt() =====
 
 This is a simple method used to block the caller until the construction phase of
@@ -1394,7 +1512,7 @@ state system activities.
 
 ==== AttributeNotFoundException ====
 
-This is thrown by getQuarkRelative() and getQuarkAbsolute() (but not byt the
+This is thrown by getQuarkRelative() and getQuarkAbsolute() (but not by the
 -AndAdd versions!) when passing an attribute path that is not present in the
 state system. This is to ensure that no new attribute is created when using
 these versions of the methods.
@@ -4406,3 +4524,45 @@ This analysis tracks the state of the virtual CPUs in conjunction with the physi
 * A way to differentiate between hypervisor mode and normal mode for the virtual CPU. A virtual CPU usually runs within a process on the host, but sometimes that process may need to run hypervisor-specific code. That is called '''hypervisor mode'''. During that time, no code from the guest itself is run. Typically, the process is running on the host (not preempted), but from the guest's point of view, the virtual CPU should be preempted.
 
 A model implementation for a new hypervisor will need to implement class '''IVirtualMachineModel''', that can be found in package '''org.eclipse.tracecompass.internal.lttng2.kernel.core.analysis.vm.model'''. See the javadoc in the class itself for more information on what each method does.
+
+= JUL Logging =
+
+Logging can be quite useful to debug a class, see its interactions with other components and understand the behavior of the system. TraceCompass uses JUL to log various events in the code, which can then be used to model and analyze the system's workflow. Here are some guidelines to use logging efficiently in Trace Compass. See the User Documentation for instructions on how to enable logging and obtain traces.
+
+=== Use a static logger for each class ===
+
+Each class should define and use their own static logger like this:
+
+    private static final Logger LOGGER = TraceCompassLog.getLogger(StateSystem.class);
+
+It is then easy to filter the components to log by their full class name. The ''TraceCompassLog#getLogger'' method is a wrapper for ''java.util.logging.Logger#getLogger'', but the Trace Compass's logging initialization (overriding the default's ConsoleHandler and INFO level for the org.eclipse.tracecompass namespace when logging is not enabled) is done in the static initializer of this class. Using the wrapper method ensures that this code is called and the user will not see Console message all over the place.
+
+'''Note on abstract classes''': It is debatable whether to use a static logger with the abstract class name or a logger with the concrete class's name.
+
+In the former case, logging for this class uses the classes's own namespace, but it is impossible to discriminate logging statement by concrete classes unless the concrete class name is added as parameter to the statement (when necessary).
+
+The latter case has the advantage that one can log only the concrete class and see all that goes on in the abstract class as well, but the concrete class may be in another namespace and will not benefit from the ''TraceCompassLog'' logging initialization and the user will see console logging happen.
+
+Both methods have their advantages and there is no clear good answer.
+
+=== Use a message supplier ===
+
+A logging statement, to be meaningful, will usually log a string that contains data from the context and will thus do string concatenation. This has a non-negligible overhead. To avoid having to do the costly string concatenation when the statement is not logged, java provides method taking a ''Supplier<String>'' as argument and that method should be used for all logging statements
+
+    LOGGER.info(() -> "[Component:Action] param1=" + myParam1 + ", param2=" + myParam2);
+
+=== Choose the appropriate log level ===
+
+The available log levels for JUL are SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST. The default level when not specified is INFO.
+
+* As a rule of thumb, enabling all INFO level statements should have a near zero impact on the execution, so log parameters that require some computations, or methods that are called very often should not be logged at INFO level.
+* CONFIG level should provide more detailed information than the INFO level, but still not impact the execution too much. It should be possible for a component to use up to CONFIG level statements and make meaningful analyses using the timestamps of the events.
+* FINE, FINER and FINEST are for statements that will not be used with the timestamps. Enabling them may have a visible effect on the performance of Trace Compass. They will typically be used with a purpose in mind, like debugging a component or getting data on caches for examples.
+
+=== Log message format ===
+
+JUL logging will produce trace data and unless one wants to visually parse a trace one event at a time, it will typically be used with an analysis to produce a result. To do so, the log messages should have a format that can then be associated with a trace type.
+
+Third party plugins provide a custom trace parser and LTTng trace type for JUL statements that use the following format
+
+    [EventName:MayContainSemiColon] paramName1=paramValue1, paramName2=paramValue2
This page took 0.029409 seconds and 5 git commands to generate.