LCOV - code coverage report
Current view: top level - toolkit/components/telemetry - Telemetry.h (source / functions) Hit Total Coverage
Test: output.info Lines: 33 39 84.6 %
Date: 2017-07-14 16:53:18 Functions: 43 130 33.1 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #include "nsXULAppAPI.h"
      15             : 
      16             : #include "mozilla/TelemetryHistogramEnums.h"
      17             : #include "mozilla/TelemetryScalarEnums.h"
      18             : 
      19             : /******************************************************************************
      20             :  * This implements the Telemetry system.
      21             :  * It allows recording into histograms as well some more specialized data
      22             :  * points and gives access to the data.
      23             :  *
      24             :  * For documentation on how to add and use new Telemetry probes, see:
      25             :  * https://developer.mozilla.org/en-US/docs/Mozilla/Performance/Adding_a_new_Telemetry_probe
      26             :  *
      27             :  * For more general information on Telemetry see:
      28             :  * https://wiki.mozilla.org/Telemetry
      29             :  *****************************************************************************/
      30             : 
      31             : namespace mozilla {
      32             : namespace HangMonitor {
      33             :   class HangAnnotations;
      34             : } // namespace HangMonitor
      35             : namespace Telemetry {
      36             : 
      37             : struct Accumulation;
      38             : struct KeyedAccumulation;
      39             : struct ScalarAction;
      40             : struct KeyedScalarAction;
      41             : struct ChildEventData;
      42             : 
      43             : enum TimerResolution {
      44             :   Millisecond,
      45             :   Microsecond
      46             : };
      47             : 
      48             : /**
      49             :  * Create and destroy the underlying base::StatisticsRecorder singleton.
      50             :  * Creation has to be done very early in the startup sequence.
      51             :  */
      52             : void CreateStatisticsRecorder();
      53             : void DestroyStatisticsRecorder();
      54             : 
      55             : /**
      56             :  * Initialize the Telemetry service on the main thread at startup.
      57             :  */
      58             : void Init();
      59             : 
      60             : /**
      61             :  * Adds sample to a histogram defined in TelemetryHistogramEnums.h
      62             :  *
      63             :  * @param id - histogram id
      64             :  * @param sample - value to record.
      65             :  */
      66             : void Accumulate(HistogramID id, uint32_t sample);
      67             : 
      68             : /**
      69             :  * Adds sample to a keyed histogram defined in TelemetryHistogramEnums.h
      70             :  *
      71             :  * @param id - keyed histogram id
      72             :  * @param key - the string key
      73             :  * @param sample - (optional) value to record, defaults to 1.
      74             :  */
      75             : void Accumulate(HistogramID id, const nsCString& key, uint32_t sample = 1);
      76             : 
      77             : /**
      78             :  * Adds a sample to a histogram defined in TelemetryHistogramEnums.h.
      79             :  * This function is here to support telemetry measurements from Java,
      80             :  * where we have only names and not numeric IDs.  You should almost
      81             :  * certainly be using the by-enum-id version instead of this one.
      82             :  *
      83             :  * @param name - histogram name
      84             :  * @param sample - value to record
      85             :  */
      86             : void Accumulate(const char* name, uint32_t sample);
      87             : 
      88             : /**
      89             :  * Adds a sample to a histogram defined in TelemetryHistogramEnums.h.
      90             :  * This function is here to support telemetry measurements from Java,
      91             :  * where we have only names and not numeric IDs.  You should almost
      92             :  * certainly be using the by-enum-id version instead of this one.
      93             :  *
      94             :  * @param name - histogram name
      95             :  * @param key - the string key
      96             :  * @param sample - sample - (optional) value to record, defaults to 1.
      97             :  */
      98             : void Accumulate(const char *name, const nsCString& key, uint32_t sample = 1);
      99             : 
     100             : /**
     101             :  * Adds sample to a categorical histogram defined in TelemetryHistogramEnums.h
     102             :  * This is the typesafe - and preferred - way to use the categorical histograms
     103             :  * by passing values from the corresponding Telemetry::LABELS_* enum.
     104             :  *
     105             :  * @param enumValue - Label value from one of the Telemetry::LABELS_* enums.
     106             :  */
     107             : template<class E>
     108           0 : void AccumulateCategorical(E enumValue) {
     109             :   static_assert(IsCategoricalLabelEnum<E>::value,
     110             :                 "Only categorical label enum types are supported.");
     111           0 :   Accumulate(static_cast<HistogramID>(CategoricalLabelId<E>::value),
     112             :              static_cast<uint32_t>(enumValue));
     113           0 : };
     114             : 
     115             : /**
     116             :  * Adds sample to a categorical histogram defined in TelemetryHistogramEnums.h
     117             :  * This string will be matched against the labels defined in Histograms.json.
     118             :  * If the string does not match a label defined for the histogram, nothing will
     119             :  * be recorded.
     120             :  *
     121             :  * @param id - The histogram id.
     122             :  * @param label - A string label value that is defined in Histograms.json for this histogram.
     123             :  */
     124             : void AccumulateCategorical(HistogramID id, const nsCString& label);
     125             : 
     126             : /**
     127             :  * Adds time delta in milliseconds to a histogram defined in TelemetryHistogramEnums.h
     128             :  *
     129             :  * @param id - histogram id
     130             :  * @param start - start time
     131             :  * @param end - end time
     132             :  */
     133             : void AccumulateTimeDelta(HistogramID id, TimeStamp start, TimeStamp end = TimeStamp::Now());
     134             : 
     135             : /**
     136             :  * Enable/disable recording for this histogram at runtime.
     137             :  * Recording is enabled by default, unless listed at kRecordingInitiallyDisabledIDs[].
     138             :  * id must be a valid telemetry enum, otherwise an assertion is triggered.
     139             :  *
     140             :  * @param id - histogram id
     141             :  * @param enabled - whether or not to enable recording from now on.
     142             :  */
     143             : void SetHistogramRecordingEnabled(HistogramID id, bool enabled);
     144             : 
     145             : const char* GetHistogramName(HistogramID id);
     146             : 
     147             : /**
     148             :  * Those wrappers are needed because the VS versions we use do not support free
     149             :  * functions with default template arguments.
     150             :  */
     151             : template<TimerResolution res>
     152             : struct AccumulateDelta_impl
     153             : {
     154             :   static void compute(HistogramID id, TimeStamp start, TimeStamp end = TimeStamp::Now());
     155             :   static void compute(HistogramID id, const nsCString& key, TimeStamp start, TimeStamp end = TimeStamp::Now());
     156             : };
     157             : 
     158             : template<>
     159             : struct AccumulateDelta_impl<Millisecond>
     160             : {
     161          62 :   static void compute(HistogramID id, TimeStamp start, TimeStamp end = TimeStamp::Now()) {
     162          62 :     Accumulate(id, static_cast<uint32_t>((end - start).ToMilliseconds()));
     163          62 :   }
     164        1161 :   static void compute(HistogramID id, const nsCString& key, TimeStamp start, TimeStamp end = TimeStamp::Now()) {
     165        1161 :     Accumulate(id, key, static_cast<uint32_t>((end - start).ToMilliseconds()));
     166        1161 :   }
     167             : };
     168             : 
     169             : template<>
     170             : struct AccumulateDelta_impl<Microsecond>
     171             : {
     172          26 :   static void compute(HistogramID id, TimeStamp start, TimeStamp end = TimeStamp::Now()) {
     173          26 :     Accumulate(id, static_cast<uint32_t>((end - start).ToMicroseconds()));
     174          26 :   }
     175           0 :   static void compute(HistogramID id, const nsCString& key, TimeStamp start, TimeStamp end = TimeStamp::Now()) {
     176           0 :     Accumulate(id, key, static_cast<uint32_t>((end - start).ToMicroseconds()));
     177           0 :   }
     178             : };
     179             : 
     180             : 
     181             : template<HistogramID id, TimerResolution res = Millisecond>
     182             : class MOZ_RAII AutoTimer {
     183             : public:
     184          87 :   explicit AutoTimer(TimeStamp aStart = TimeStamp::Now() MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     185          87 :      : start(aStart)
     186             :   {
     187          87 :     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     188          87 :   }
     189             : 
     190        3478 :   explicit AutoTimer(const nsCString& aKey, TimeStamp aStart = TimeStamp::Now() MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     191             :     : start(aStart)
     192        1164 :     , key(aKey)
     193             :   {
     194        1164 :     MOZ_ASSERT(!aKey.IsEmpty(), "The key must not be empty.");
     195        1164 :     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     196        1164 :   }
     197             : 
     198        1248 :   ~AutoTimer() {
     199        1248 :     if (key.IsEmpty()) {
     200          87 :       AccumulateDelta_impl<res>::compute(id, start);
     201             :     } else {
     202        1161 :       AccumulateDelta_impl<res>::compute(id, key, start);
     203             :     }
     204        1248 :   }
     205             : 
     206             : private:
     207             :   const TimeStamp start;
     208             :   const nsCString key;
     209             :   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     210             : };
     211             : 
     212             : template<HistogramID id>
     213             : class MOZ_RAII AutoCounter {
     214             : public:
     215           8 :   explicit AutoCounter(uint32_t counterStart = 0 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     216           8 :     : counter(counterStart)
     217             :   {
     218           8 :     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     219           8 :   }
     220             : 
     221           8 :   ~AutoCounter() {
     222           8 :     Accumulate(id, counter);
     223           8 :   }
     224             : 
     225             :   // Prefix increment only, to encourage good habits.
     226           4 :   void operator++() {
     227           4 :     ++counter;
     228           4 :   }
     229             : 
     230             :   // Chaining doesn't make any sense, don't return anything.
     231             :   void operator+=(int increment) {
     232             :     counter += increment;
     233             :   }
     234             : 
     235             : private:
     236             :   uint32_t counter;
     237             :   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     238             : };
     239             : 
     240             : /**
     241             :  * Indicates whether Telemetry base data recording is turned on. Added for future uses.
     242             :  */
     243             : bool CanRecordBase();
     244             : 
     245             : /**
     246             :  * Indicates whether Telemetry extended data recording is turned on.  This is intended
     247             :  * to guard calls to Accumulate when the statistic being recorded is expensive to compute.
     248             :  */
     249             : bool CanRecordExtended();
     250             : 
     251             : /**
     252             :  * Records slow SQL statements for Telemetry reporting.
     253             :  *
     254             :  * @param statement - offending SQL statement to record
     255             :  * @param dbName - DB filename
     256             :  * @param delay - execution time in milliseconds
     257             :  */
     258             : void RecordSlowSQLStatement(const nsACString &statement,
     259             :                             const nsACString &dbName,
     260             :                             uint32_t delay);
     261             : 
     262             : /**
     263             :  * Record Webrtc ICE candidate type combinations in a 17bit bitmask
     264             :  *
     265             :  * @param iceCandidateBitmask - the bitmask representing local and remote ICE
     266             :  *                              candidate types present for the connection
     267             :  * @param success - did the peer connection connected
     268             :  */
     269             : void
     270             : RecordWebrtcIceCandidates(const uint32_t iceCandidateBitmask,
     271             :                           const bool success);
     272             : /**
     273             :  * Initialize I/O Reporting
     274             :  * Initially this only records I/O for files in the binary directory.
     275             :  *
     276             :  * @param aXreDir - XRE directory
     277             :  */
     278             : void InitIOReporting(nsIFile* aXreDir);
     279             : 
     280             : /**
     281             :  * Set the profile directory. Once called, files in the profile directory will
     282             :  * be included in I/O reporting. We can't use the directory
     283             :  * service to obtain this information because it isn't running yet.
     284             :  */
     285             : void SetProfileDir(nsIFile* aProfD);
     286             : 
     287             : /**
     288             :  * Called to inform Telemetry that startup has completed.
     289             :  */
     290             : void LeavingStartupStage();
     291             : 
     292             : /**
     293             :  * Called to inform Telemetry that shutdown is commencing.
     294             :  */
     295             : void EnteringShutdownStage();
     296             : 
     297             : /**
     298             :  * Thresholds for a statement to be considered slow, in milliseconds
     299             :  */
     300             : const uint32_t kSlowSQLThresholdForMainThread = 50;
     301             : const uint32_t kSlowSQLThresholdForHelperThreads = 100;
     302             : 
     303             : class ProcessedStack;
     304             : 
     305             : /**
     306             :  * Record the main thread's call stack after it hangs.
     307             :  *
     308             :  * @param aDuration - Approximate duration of main thread hang, in seconds
     309             :  * @param aStack - Array of PCs from the hung call stack
     310             :  * @param aSystemUptime - System uptime at the time of the hang, in minutes
     311             :  * @param aFirefoxUptime - Firefox uptime at the time of the hang, in minutes
     312             :  * @param aAnnotations - Any annotations to be added to the report
     313             :  */
     314             : #if defined(MOZ_GECKO_PROFILER)
     315             : void RecordChromeHang(uint32_t aDuration,
     316             :                       ProcessedStack &aStack,
     317             :                       int32_t aSystemUptime,
     318             :                       int32_t aFirefoxUptime,
     319             :                       mozilla::UniquePtr<mozilla::HangMonitor::HangAnnotations>
     320             :                               aAnnotations);
     321             : 
     322             : /**
     323             :  * Record the current thread's call stack on demand. Note that, the stack is
     324             :  * only captured once. Subsequent calls result in incrementing the capture
     325             :  * counter.
     326             :  *
     327             :  * @param aKey - A user defined key associated with the captured stack.
     328             :  *
     329             :  * NOTE: Unwinding call stacks is an expensive operation performance-wise.
     330             :  */
     331             : void CaptureStack(const nsCString& aKey);
     332             : #endif
     333             : 
     334             : class ThreadHangStats;
     335             : 
     336             : /**
     337             :  * Move a ThreadHangStats to Telemetry storage. Normally Telemetry queries
     338             :  * for active ThreadHangStats through BackgroundHangMonitor, but once a
     339             :  * thread exits, the thread's copy of ThreadHangStats needs to be moved to
     340             :  * inside Telemetry using this function.
     341             :  *
     342             :  * @param aStats ThreadHangStats to save; the data inside aStats
     343             :  *               will be moved and aStats should be treated as
     344             :  *               invalid after this function returns
     345             :  */
     346             : void RecordThreadHangStats(ThreadHangStats&& aStats);
     347             : 
     348             : /**
     349             :  * Record a failed attempt at locking the user's profile.
     350             :  *
     351             :  * @param aProfileDir The profile directory whose lock attempt failed
     352             :  */
     353             : void WriteFailedProfileLock(nsIFile* aProfileDir);
     354             : 
     355             : /**
     356             :  * Adds the value to the given scalar.
     357             :  *
     358             :  * @param aId The scalar enum id.
     359             :  * @param aValue The value to add to the scalar.
     360             :  */
     361             : void ScalarAdd(mozilla::Telemetry::ScalarID aId, uint32_t aValue);
     362             : 
     363             : /**
     364             :  * Sets the scalar to the given value.
     365             :  *
     366             :  * @param aId The scalar enum id.
     367             :  * @param aValue The value to set the scalar to.
     368             :  */
     369             : void ScalarSet(mozilla::Telemetry::ScalarID aId, uint32_t aValue);
     370             : 
     371             : /**
     372             :  * Sets the scalar to the given value.
     373             :  *
     374             :  * @param aId The scalar enum id.
     375             :  * @param aValue The value to set the scalar to.
     376             :  */
     377             : void ScalarSet(mozilla::Telemetry::ScalarID aId, bool aValue);
     378             : 
     379             : /**
     380             :  * Sets the scalar to the given value.
     381             :  *
     382             :  * @param aId The scalar enum id.
     383             :  * @param aValue The value to set the scalar to, truncated to
     384             :  *        50 characters if exceeding that length.
     385             :  */
     386             : void ScalarSet(mozilla::Telemetry::ScalarID aId, const nsAString& aValue);
     387             : 
     388             : /**
     389             :  * Sets the scalar to the maximum of the current and the passed value.
     390             :  *
     391             :  * @param aId The scalar enum id.
     392             :  * @param aValue The value the scalar is set to if its greater
     393             :  *        than the current value.
     394             :  */
     395             : void ScalarSetMaximum(mozilla::Telemetry::ScalarID aId, uint32_t aValue);
     396             : 
     397             : /**
     398             :  * Adds the value to the given scalar.
     399             :  *
     400             :  * @param aId The scalar enum id.
     401             :  * @param aKey The scalar key.
     402             :  * @param aValue The value to add to the scalar.
     403             :  */
     404             : void ScalarAdd(mozilla::Telemetry::ScalarID aId, const nsAString& aKey, uint32_t aValue);
     405             : 
     406             : /**
     407             :  * Sets the scalar to the given value.
     408             :  *
     409             :  * @param aId The scalar enum id.
     410             :  * @param aKey The scalar key.
     411             :  * @param aValue The value to set the scalar to.
     412             :  */
     413             : void ScalarSet(mozilla::Telemetry::ScalarID aId, const nsAString& aKey, uint32_t aValue);
     414             : 
     415             : /**
     416             :  * Sets the scalar to the given value.
     417             :  *
     418             :  * @param aId The scalar enum id.
     419             :  * @param aKey The scalar key.
     420             :  * @param aValue The value to set the scalar to.
     421             :  */
     422             : void ScalarSet(mozilla::Telemetry::ScalarID aId, const nsAString& aKey, bool aValue);
     423             : 
     424             : /**
     425             :  * Sets the scalar to the maximum of the current and the passed value.
     426             :  *
     427             :  * @param aId The scalar enum id.
     428             :  * @param aKey The scalar key.
     429             :  * @param aValue The value the scalar is set to if its greater
     430             :  *        than the current value.
     431             :  */
     432             : void ScalarSetMaximum(mozilla::Telemetry::ScalarID aId, const nsAString& aKey, uint32_t aValue);
     433             : 
     434             : } // namespace Telemetry
     435             : } // namespace mozilla
     436             : 
     437             : #endif // Telemetry_h__

Generated by: LCOV version 1.13