Commit | Line | Data |
---|---|---|
6151d86c PT |
1 | /******************************************************************************* |
2 | * Copyright (c) 2012 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.linuxtools.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.linuxtools.tmf.core.component.ITmfComponent; | |
21 | import org.eclipse.linuxtools.tmf.core.component.ITmfDataProvider; | |
22 | import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; | |
23 | import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest; | |
24 | import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; | |
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 | * </ul> | |
40 | * | |
41 | * @version 1.0 | |
42 | * @author Francois Chouinard | |
43 | */ | |
44 | @SuppressWarnings("nls") | |
45 | public class TmfCoreTracer { | |
46 | ||
47 | // ------------------------------------------------------------------------ | |
48 | // Constants | |
49 | // ------------------------------------------------------------------------ | |
50 | ||
51 | private static final String PLUGIN_ID = Activator.PLUGIN_ID; | |
52 | ||
53 | // Tracing keys (in .options) | |
54 | private static final String COMPONENT_TRACE_KEY = PLUGIN_ID + "/component"; | |
55 | private static final String REQUEST_TRACE_KEY = PLUGIN_ID + "/request"; | |
56 | private static final String SIGNAL_TRACE_KEY = PLUGIN_ID + "/signal"; | |
57 | private static final String EVENT_TRACE_KEY = PLUGIN_ID + "/event"; | |
58 | ||
59 | private static final String TRACE_FILE_NAME = "TmfTrace.log"; | |
60 | ||
61 | // ------------------------------------------------------------------------ | |
62 | // Attributes | |
63 | // ------------------------------------------------------------------------ | |
64 | ||
65 | // Classes tracing flags | |
66 | static Boolean COMPONENT_CLASS_ENABLED = Boolean.FALSE; | |
67 | static Boolean REQUEST_CLASS_ENABLED = Boolean.FALSE; | |
68 | static Boolean SIGNAL_CLASS_ENABLED = Boolean.FALSE; | |
69 | static Boolean EVENT_CLASS_ENABLED = Boolean.FALSE; | |
70 | ||
71 | // Trace log file | |
72 | private static BufferedWriter fTraceFile; | |
73 | ||
74 | // ------------------------------------------------------------------------ | |
75 | // Start/stop tracing - controlled by the plug-in | |
76 | // ------------------------------------------------------------------------ | |
77 | ||
78 | /** | |
79 | * Set the tracing flags according to the launch configuration | |
80 | */ | |
81 | public static void init() { | |
82 | ||
83 | String traceKey; | |
84 | boolean isTracing = false; | |
85 | ||
86 | traceKey = Platform.getDebugOption(COMPONENT_TRACE_KEY); | |
87 | if (traceKey != null) { | |
88 | COMPONENT_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue(); | |
89 | isTracing |= COMPONENT_CLASS_ENABLED; | |
90 | } | |
91 | ||
92 | traceKey = Platform.getDebugOption(REQUEST_TRACE_KEY); | |
93 | if (traceKey != null) { | |
94 | REQUEST_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue(); | |
95 | isTracing |= REQUEST_CLASS_ENABLED; | |
96 | } | |
97 | ||
98 | traceKey = Platform.getDebugOption(SIGNAL_TRACE_KEY); | |
99 | if (traceKey != null) { | |
100 | SIGNAL_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue(); | |
101 | isTracing |= SIGNAL_CLASS_ENABLED; | |
102 | } | |
103 | ||
104 | traceKey = Platform.getDebugOption(EVENT_TRACE_KEY); | |
105 | if (traceKey != null) { | |
106 | EVENT_CLASS_ENABLED = (Boolean.valueOf(traceKey)).booleanValue(); | |
107 | isTracing |= EVENT_CLASS_ENABLED; | |
108 | } | |
109 | ||
110 | // Create trace log file if any of the flags was set | |
111 | if (isTracing) { | |
112 | try { | |
113 | fTraceFile = new BufferedWriter(new FileWriter(TRACE_FILE_NAME)); | |
114 | } catch (IOException e) { | |
115 | Activator.logError("Error opening log file " + TRACE_FILE_NAME, e); | |
116 | fTraceFile = null; | |
117 | } | |
118 | } | |
119 | } | |
120 | ||
121 | /** | |
122 | * Close the trace log file | |
123 | */ | |
124 | public static void stop() { | |
125 | if (fTraceFile != null) { | |
126 | try { | |
127 | fTraceFile.close(); | |
128 | fTraceFile = null; | |
129 | } catch (IOException e) { | |
130 | Activator.logError("Error closing log file", e); | |
131 | } | |
132 | } | |
133 | } | |
134 | ||
135 | // ------------------------------------------------------------------------ | |
136 | // Predicates | |
137 | // ------------------------------------------------------------------------ | |
138 | ||
139 | @SuppressWarnings("javadoc") | |
140 | public static boolean isComponentTraced() { | |
141 | return COMPONENT_CLASS_ENABLED; | |
142 | } | |
143 | ||
144 | @SuppressWarnings("javadoc") | |
145 | public static boolean isRequestTraced() { | |
146 | return REQUEST_CLASS_ENABLED; | |
147 | } | |
148 | ||
149 | @SuppressWarnings("javadoc") | |
150 | public static boolean isSignalTraced() { | |
151 | return SIGNAL_CLASS_ENABLED; | |
152 | } | |
153 | ||
154 | @SuppressWarnings("javadoc") | |
155 | public static boolean isEventTraced() { | |
156 | return EVENT_CLASS_ENABLED; | |
157 | } | |
158 | ||
159 | // ------------------------------------------------------------------------ | |
160 | // Tracing methods | |
161 | // ------------------------------------------------------------------------ | |
162 | ||
163 | /** | |
164 | * The central tracing method. Prepends the timestamp and the thread id | |
165 | * to the trace message. | |
166 | * | |
167 | * @param msg the trace message to log | |
168 | */ | |
169 | public static synchronized void trace(String msg) { | |
170 | ||
171 | // Set the timestamp (ms resolution) | |
172 | long currentTime = System.currentTimeMillis(); | |
173 | StringBuilder message = new StringBuilder("["); | |
174 | message.append(currentTime / 1000); | |
175 | message.append("."); | |
176 | message.append(String.format("%1$03d", currentTime % 1000)); | |
177 | message.append("] "); | |
178 | ||
179 | // Set the thread id | |
180 | message.append("[TID="); | |
181 | message.append(String.format("%1$03d", Thread.currentThread().getId())); | |
182 | message.append("] "); | |
183 | ||
184 | // Append the trace message | |
185 | message.append(msg); | |
186 | ||
187 | // Write to file | |
188 | if (fTraceFile != null) { | |
189 | try { | |
190 | fTraceFile.write(message.toString()); | |
191 | fTraceFile.newLine(); | |
192 | fTraceFile.flush(); | |
193 | } catch (IOException e) { | |
194 | Activator.logError("Error writing to log file", e); | |
195 | } | |
196 | } | |
197 | } | |
198 | ||
199 | // ------------------------------------------------------------------------ | |
200 | // TMF Core specific trace formatters | |
201 | // ------------------------------------------------------------------------ | |
202 | ||
203 | @SuppressWarnings("javadoc") | |
204 | public static void traceComponent(ITmfComponent component, String msg) { | |
205 | if (COMPONENT_CLASS_ENABLED) { | |
206 | String message = ("[CMP] Cmp=" + component.getName() + " " + msg); | |
207 | trace(message); | |
208 | } | |
209 | } | |
210 | ||
211 | @SuppressWarnings("javadoc") | |
212 | public static void traceRequest(ITmfDataRequest request, String msg) { | |
213 | if (REQUEST_CLASS_ENABLED) { | |
214 | String message = ("[REQ] Req=" + request.getRequestId() + " " + msg); | |
215 | trace(message); | |
216 | } | |
217 | } | |
218 | ||
219 | @SuppressWarnings("javadoc") | |
220 | public static void traceSignal(TmfSignal signal, String msg) { | |
221 | if (SIGNAL_CLASS_ENABLED) { | |
222 | String message = ("[SIG] Sig=" + signal.getClass().getSimpleName() | |
223 | + " Target=" + msg); | |
224 | trace(message); | |
225 | } | |
226 | } | |
227 | ||
228 | @SuppressWarnings("javadoc") | |
229 | public static void traceEvent(ITmfDataProvider provider, ITmfDataRequest request, ITmfEvent event) { | |
230 | if (EVENT_CLASS_ENABLED) { | |
231 | String message = ("[EVT] Provider=" + provider.toString() | |
232 | + ", Req=" + request.getRequestId() + ", Event=" + event.getTimestamp()); | |
233 | trace(message); | |
234 | } | |
235 | } | |
236 | ||
237 | } |