|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef Telemetry_h__ |
|
7 #define Telemetry_h__ |
|
8 |
|
9 #include "mozilla/GuardObjects.h" |
|
10 #include "mozilla/TimeStamp.h" |
|
11 #include "mozilla/StartupTimeline.h" |
|
12 #include "nsTArray.h" |
|
13 #include "nsStringGlue.h" |
|
14 |
|
15 namespace base { |
|
16 class Histogram; |
|
17 } |
|
18 |
|
19 namespace mozilla { |
|
20 namespace Telemetry { |
|
21 |
|
22 #include "TelemetryHistogramEnums.h" |
|
23 |
|
24 enum TimerResolution { |
|
25 Millisecond, |
|
26 Microsecond |
|
27 }; |
|
28 |
|
29 /** |
|
30 * Initialize the Telemetry service on the main thread at startup. |
|
31 */ |
|
32 void Init(); |
|
33 |
|
34 /** |
|
35 * Adds sample to a histogram defined in TelemetryHistograms.h |
|
36 * |
|
37 * @param id - histogram id |
|
38 * @param sample - value to record. |
|
39 */ |
|
40 void Accumulate(ID id, uint32_t sample); |
|
41 |
|
42 /** |
|
43 * Adds a sample to a histogram defined in TelemetryHistograms.h. |
|
44 * This function is here to support telemetry measurements from Java, |
|
45 * where we have only names and not numeric IDs. You should almost |
|
46 * certainly be using the by-enum-id version instead of this one. |
|
47 * |
|
48 * @param name - histogram name |
|
49 * @param sample - value to record |
|
50 */ |
|
51 void Accumulate(const char* name, uint32_t sample); |
|
52 |
|
53 /** |
|
54 * Adds time delta in milliseconds to a histogram defined in TelemetryHistograms.h |
|
55 * |
|
56 * @param id - histogram id |
|
57 * @param start - start time |
|
58 * @param end - end time |
|
59 */ |
|
60 void AccumulateTimeDelta(ID id, TimeStamp start, TimeStamp end = TimeStamp::Now()); |
|
61 |
|
62 /** |
|
63 * Return a raw Histogram for direct manipulation for users who can not use Accumulate(). |
|
64 */ |
|
65 base::Histogram* GetHistogramById(ID id); |
|
66 |
|
67 /** |
|
68 * Those wrappers are needed because the VS versions we use do not support free |
|
69 * functions with default template arguments. |
|
70 */ |
|
71 template<TimerResolution res> |
|
72 struct AccumulateDelta_impl |
|
73 { |
|
74 static void compute(ID id, TimeStamp start, TimeStamp end = TimeStamp::Now()); |
|
75 }; |
|
76 |
|
77 template<> |
|
78 struct AccumulateDelta_impl<Millisecond> |
|
79 { |
|
80 static void compute(ID id, TimeStamp start, TimeStamp end = TimeStamp::Now()) { |
|
81 Accumulate(id, static_cast<uint32_t>((end - start).ToMilliseconds())); |
|
82 } |
|
83 }; |
|
84 |
|
85 template<> |
|
86 struct AccumulateDelta_impl<Microsecond> |
|
87 { |
|
88 static void compute(ID id, TimeStamp start, TimeStamp end = TimeStamp::Now()) { |
|
89 Accumulate(id, static_cast<uint32_t>((end - start).ToMicroseconds())); |
|
90 } |
|
91 }; |
|
92 |
|
93 |
|
94 template<ID id, TimerResolution res = Millisecond> |
|
95 class AutoTimer { |
|
96 public: |
|
97 AutoTimer(TimeStamp aStart = TimeStamp::Now() MOZ_GUARD_OBJECT_NOTIFIER_PARAM) |
|
98 : start(aStart) |
|
99 { |
|
100 MOZ_GUARD_OBJECT_NOTIFIER_INIT; |
|
101 } |
|
102 |
|
103 ~AutoTimer() { |
|
104 AccumulateDelta_impl<res>::compute(id, start); |
|
105 } |
|
106 |
|
107 private: |
|
108 const TimeStamp start; |
|
109 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER |
|
110 }; |
|
111 |
|
112 template<ID id> |
|
113 class AutoCounter { |
|
114 public: |
|
115 AutoCounter(uint32_t counterStart = 0 MOZ_GUARD_OBJECT_NOTIFIER_PARAM) |
|
116 : counter(counterStart) |
|
117 { |
|
118 MOZ_GUARD_OBJECT_NOTIFIER_INIT; |
|
119 } |
|
120 |
|
121 ~AutoCounter() { |
|
122 Accumulate(id, counter); |
|
123 } |
|
124 |
|
125 // Prefix increment only, to encourage good habits. |
|
126 void operator++() { |
|
127 ++counter; |
|
128 } |
|
129 |
|
130 // Chaining doesn't make any sense, don't return anything. |
|
131 void operator+=(int increment) { |
|
132 counter += increment; |
|
133 } |
|
134 |
|
135 private: |
|
136 uint32_t counter; |
|
137 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER |
|
138 }; |
|
139 |
|
140 /** |
|
141 * Indicates whether Telemetry recording is turned on. This is intended |
|
142 * to guard calls to Accumulate when the statistic being recorded is |
|
143 * expensive to compute. |
|
144 */ |
|
145 bool CanRecord(); |
|
146 |
|
147 /** |
|
148 * Records slow SQL statements for Telemetry reporting. |
|
149 * |
|
150 * @param statement - offending SQL statement to record |
|
151 * @param dbName - DB filename |
|
152 * @param delay - execution time in milliseconds |
|
153 */ |
|
154 void RecordSlowSQLStatement(const nsACString &statement, |
|
155 const nsACString &dbName, |
|
156 uint32_t delay); |
|
157 |
|
158 /** |
|
159 * Initialize I/O Reporting |
|
160 * Initially this only records I/O for files in the binary directory. |
|
161 * |
|
162 * @param aXreDir - XRE directory |
|
163 */ |
|
164 void InitIOReporting(nsIFile* aXreDir); |
|
165 |
|
166 /** |
|
167 * Set the profile directory. Once called, files in the profile directory will |
|
168 * be included in I/O reporting. We can't use the directory |
|
169 * service to obtain this information because it isn't running yet. |
|
170 */ |
|
171 void SetProfileDir(nsIFile* aProfD); |
|
172 |
|
173 /** |
|
174 * Called to inform Telemetry that startup has completed. |
|
175 */ |
|
176 void LeavingStartupStage(); |
|
177 |
|
178 /** |
|
179 * Called to inform Telemetry that shutdown is commencing. |
|
180 */ |
|
181 void EnteringShutdownStage(); |
|
182 |
|
183 /** |
|
184 * Thresholds for a statement to be considered slow, in milliseconds |
|
185 */ |
|
186 const uint32_t kSlowSQLThresholdForMainThread = 50; |
|
187 const uint32_t kSlowSQLThresholdForHelperThreads = 100; |
|
188 |
|
189 class ProcessedStack; |
|
190 |
|
191 /** |
|
192 * Record the main thread's call stack after it hangs. |
|
193 * |
|
194 * @param aDuration - Approximate duration of main thread hang, in seconds |
|
195 * @param aStack - Array of PCs from the hung call stack |
|
196 * @param aSystemUptime - System uptime at the time of the hang, in minutes |
|
197 * @param aFirefoxUptime - Firefox uptime at the time of the hang, in minutes |
|
198 */ |
|
199 #if defined(MOZ_ENABLE_PROFILER_SPS) |
|
200 void RecordChromeHang(uint32_t aDuration, |
|
201 ProcessedStack &aStack, |
|
202 int32_t aSystemUptime, |
|
203 int32_t aFirefoxUptime); |
|
204 #endif |
|
205 |
|
206 class ThreadHangStats; |
|
207 |
|
208 /** |
|
209 * Move a ThreadHangStats to Telemetry storage. Normally Telemetry queries |
|
210 * for active ThreadHangStats through BackgroundHangMonitor, but once a |
|
211 * thread exits, the thread's copy of ThreadHangStats needs to be moved to |
|
212 * inside Telemetry using this function. |
|
213 * |
|
214 * @param aStats ThreadHangStats to save; the data inside aStats |
|
215 * will be moved and aStats should be treated as |
|
216 * invalid after this function returns |
|
217 */ |
|
218 void RecordThreadHangStats(ThreadHangStats& aStats); |
|
219 |
|
220 /** |
|
221 * Record a failed attempt at locking the user's profile. |
|
222 * |
|
223 * @param aProfileDir The profile directory whose lock attempt failed |
|
224 */ |
|
225 void WriteFailedProfileLock(nsIFile* aProfileDir); |
|
226 |
|
227 } // namespace Telemetry |
|
228 } // namespace mozilla |
|
229 #endif // Telemetry_h__ |