TMF: Add tracing capabilities for analyses
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / internal / tmf / core / TmfCoreTracer.java
1 /*******************************************************************************
2 * Copyright (c) 2012, 2014 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Francois Chouinard - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.tracecompass.internal.tmf.core;
14
15 import java.io.BufferedWriter;
16 import java.io.FileWriter;
17 import java.io.IOException;
18
19 import org.eclipse.core.runtime.Platform;
20 import org.eclipse.tracecompass.tmf.core.component.ITmfEventProvider;
21 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
22 import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
23 import org.eclipse.tracecompass.tmf.core.signal.TmfSignal;
24 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
25
26 /**
27 * The TMF Core tracer, used to trace TMF internal components.
28 * <p>
29 * The tracing classes are independently controlled (i.e no implicit inclusion)
30 * from the launch configuration's Tracing. The resulting trace is stored in a
31 * distinct file (TmfTrace.log) in a format that can later be analyzed by TMF.
32 * <p>
33 * The tracing classes are:
34 * <ul>
35 * <li><strong>Component</strong>: TMF components life-cycle
36 * <li><strong>Request</strong>: TMF requests life-cycle
37 * <li><strong>Signal</strong>: TMF signals triggering and distribution
38 * <li><strong>Event</strong>: TMF trace events
39 * <li><strong>Analysis</strong>: TMF analyzes
40 * </ul>
41 *
42 * @version 1.0
43 * @author Francois Chouinard
44 */
45 @SuppressWarnings("nls")
46 public class TmfCoreTracer {
47
48 // ------------------------------------------------------------------------
49 // Constants
50 // ------------------------------------------------------------------------
51
52 private static final String PLUGIN_ID = Activator.PLUGIN_ID;
53
54 // Tracing keys (in .options)
55 private static final String COMPONENT_TRACE_KEY = PLUGIN_ID + "/component";
56 private static final String REQUEST_TRACE_KEY = PLUGIN_ID + "/request";
57 private static final String SIGNAL_TRACE_KEY = PLUGIN_ID + "/signal";
58 private static final String EVENT_TRACE_KEY = PLUGIN_ID + "/event";
59 private static final String ANALYSIS_TRACE_KEY = PLUGIN_ID + "/analysis";
60
61 private static final String TRACE_FILE_NAME = "TmfTrace.log";
62
63 // ------------------------------------------------------------------------
64 // Attributes
65 // ------------------------------------------------------------------------
66
67 // Classes tracing flags
68 static boolean COMPONENT_CLASS_ENABLED = false;
69 static boolean REQUEST_CLASS_ENABLED = false;
70 static boolean SIGNAL_CLASS_ENABLED = false;
71 static boolean EVENT_CLASS_ENABLED = false;
72 static boolean ANALYSIS_CLASS_ENABLED = false;
73
74 // Trace log file
75 private static BufferedWriter fTraceFile;
76
77 // ------------------------------------------------------------------------
78 // Start/stop tracing - controlled by the plug-in
79 // ------------------------------------------------------------------------
80
81 /**
82 * Set the tracing flags according to the launch configuration
83 */
84 public static void init() {
85
86 String traceKey;
87 boolean isTracing = false;
88
89 traceKey = Platform.getDebugOption(COMPONENT_TRACE_KEY);
90 if (traceKey != null) {
91 COMPONENT_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue();
92 isTracing |= COMPONENT_CLASS_ENABLED;
93 }
94
95 traceKey = Platform.getDebugOption(REQUEST_TRACE_KEY);
96 if (traceKey != null) {
97 REQUEST_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue();
98 isTracing |= REQUEST_CLASS_ENABLED;
99 }
100
101 traceKey = Platform.getDebugOption(SIGNAL_TRACE_KEY);
102 if (traceKey != null) {
103 SIGNAL_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue();
104 isTracing |= SIGNAL_CLASS_ENABLED;
105 }
106
107 traceKey = Platform.getDebugOption(EVENT_TRACE_KEY);
108 if (traceKey != null) {
109 EVENT_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue();
110 isTracing |= EVENT_CLASS_ENABLED;
111 }
112
113 traceKey = Platform.getDebugOption(ANALYSIS_TRACE_KEY);
114 if (traceKey != null) {
115 ANALYSIS_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue();
116 isTracing |= ANALYSIS_CLASS_ENABLED;
117 }
118
119 // Create trace log file if any of the flags was set
120 if (isTracing) {
121 try {
122 fTraceFile = new BufferedWriter(new FileWriter(TRACE_FILE_NAME));
123 } catch (IOException e) {
124 Activator.logError("Error opening log file " + TRACE_FILE_NAME, e);
125 fTraceFile = null;
126 }
127 }
128 }
129
130 /**
131 * Close the trace log file
132 */
133 public static void stop() {
134 if (fTraceFile != null) {
135 try {
136 fTraceFile.close();
137 fTraceFile = null;
138 } catch (IOException e) {
139 Activator.logError("Error closing log file", e);
140 }
141 }
142 }
143
144 // ------------------------------------------------------------------------
145 // Predicates
146 // ------------------------------------------------------------------------
147
148 @SuppressWarnings("javadoc")
149 public static boolean isComponentTraced() {
150 return COMPONENT_CLASS_ENABLED;
151 }
152
153 @SuppressWarnings("javadoc")
154 public static boolean isRequestTraced() {
155 return REQUEST_CLASS_ENABLED;
156 }
157
158 @SuppressWarnings("javadoc")
159 public static boolean isSignalTraced() {
160 return SIGNAL_CLASS_ENABLED;
161 }
162
163 @SuppressWarnings("javadoc")
164 public static boolean isEventTraced() {
165 return EVENT_CLASS_ENABLED;
166 }
167
168 @SuppressWarnings("javadoc")
169 public static boolean isAnalysisTraced() {
170 return ANALYSIS_CLASS_ENABLED;
171 }
172
173 // ------------------------------------------------------------------------
174 // Tracing methods
175 // ------------------------------------------------------------------------
176
177 /**
178 * The central tracing method. Prepends the timestamp and the thread id to
179 * the trace message.
180 *
181 * @param msg
182 * the trace message to log
183 */
184 public static synchronized void trace(String msg) {
185 // Leave when there is no place to write the message.
186 if (fTraceFile == null) {
187 return;
188 }
189
190 // Set the timestamp (ms resolution)
191 long currentTime = System.currentTimeMillis();
192 StringBuilder message = new StringBuilder("[");
193 message.append(currentTime / 1000);
194 message.append(".");
195 message.append(String.format("%1$03d", currentTime % 1000));
196 message.append("] ");
197
198 // Set the thread id
199 message.append("[TID=");
200 message.append(String.format("%1$03d", Thread.currentThread().getId()));
201 message.append("] ");
202
203 // Append the trace message
204 message.append(msg);
205
206 // Write to file
207 try {
208 fTraceFile.write(message.toString());
209 fTraceFile.newLine();
210 fTraceFile.flush();
211 } catch (IOException e) {
212 Activator.logError("Error writing to log file", e);
213 }
214 }
215
216 // ------------------------------------------------------------------------
217 // TMF Core specific trace formatters
218 // ------------------------------------------------------------------------
219
220 /**
221 * Trace an event happening in a component.
222 *
223 * @param componentName
224 * The name of the component being traced
225 * @param msg
226 * The message to record for this component
227 */
228 public static void traceComponent(String componentName, String msg) {
229 if (COMPONENT_CLASS_ENABLED) {
230 String message = ("[CMP] Cmp=" + componentName + " " + msg);
231 trace(message);
232 }
233 }
234
235 /**
236 * Trace an event happening in an event request.
237 *
238 * @param requestId
239 * The request ID of the request being traced
240 * @param msg
241 * The message to record for this component
242 */
243 public static void traceRequest(int requestId, String msg) {
244 if (REQUEST_CLASS_ENABLED) {
245 String message = ("[REQ] Req=" + requestId + " " + msg);
246 trace(message);
247 }
248 }
249
250 @SuppressWarnings("javadoc")
251 public static void traceSignal(TmfSignal signal, String msg) {
252 if (SIGNAL_CLASS_ENABLED) {
253 String message = ("[SIG] Sig=" + signal.getClass().getSimpleName()
254 + " Target=" + msg);
255 trace(message);
256 }
257 }
258
259 @SuppressWarnings("javadoc")
260 public static void traceEvent(ITmfEventProvider provider, ITmfEventRequest request, ITmfEvent event) {
261 if (EVENT_CLASS_ENABLED) {
262 String message = ("[EVT] Provider=" + provider.toString()
263 + ", Req=" + request.getRequestId() + ", Event=" + event.getTimestamp());
264 trace(message);
265 }
266 }
267
268 /**
269 * Trace an event happening in an analysis
270 *
271 * @param analysisId
272 * The analysis ID of the analysis being run
273 * @param trace
274 * The trace this analysis is run on
275 * @param msg
276 * The message to record for this analysis
277 */
278 public static void traceAnalysis(String analysisId, ITmfTrace trace, String msg) {
279 if (ANALYSIS_CLASS_ENABLED) {
280 String traceName = (trace == null) ? "" : trace.getName();
281 String message = ("[ANL] Anl=" + analysisId + " for " + traceName + " " + msg);
282 trace(message);
283 }
284 }
285
286 }
This page took 0.039722 seconds and 5 git commands to generate.