146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file defines a set of user experience metrics data recorded by 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the MetricsService. This is the unit of data that is sent to the server. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#ifndef COMPONENTS_METRICS_METRICS_LOG_H_ 946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#define COMPONENTS_METRICS_METRICS_LOG_H_ 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/time/time.h" 1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/metrics/proto/chrome_user_metrics_extension.pb.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class PrefRegistrySimple; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PrefService; 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DictionaryValue; 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class HistogramSamples; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace content { 27ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochstruct WebPluginInfo; 28ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 29ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace tracked_objects { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ProcessDataSnapshot; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace variations { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ActiveGroupId; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace metrics { 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass MetricsProvider; 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass MetricsServiceClient; 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class MetricsLog { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) enum LogType { 4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) INITIAL_STABILITY_LOG, // The initial log containing stability stats. 4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ONGOING_LOG, // Subsequent logs in a session. 4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) }; 4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Creates a new metrics log of the specified type. 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // |client_id| is the identifier for this profile on this installation 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // |session_id| is an integer that's incremented on each application launch 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // |client| is used to interact with the embedder. 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // |local_state| is the PrefService that this instance should use. 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Note: |this| instance does not take ownership of the |client|, but rather 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // stores a weak pointer to it. The caller should ensure that the |client| is 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // valid for the lifetime of this class. 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MetricsLog(const std::string& client_id, 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int session_id, 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LogType log_type, 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MetricsServiceClient* client, 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PrefService* local_state); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~MetricsLog(); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Registers local state prefs used by this class. 6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) static void RegisterPrefs(PrefRegistrySimple* registry); 6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Computes the MD5 hash of the given string, and returns the first 8 bytes of 6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // the hash. 7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) static uint64 Hash(const std::string& value); 7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Get the GMT buildtime for the current binary, expressed in seconds since 7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // January 1, 1970 GMT. 7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // The value is used to identify when a new build is run, so that previous 7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // reliability stats, from other builds, can be abandoned. 7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) static int64 GetBuildTime(); 7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Convenience function to return the current time at a resolution in seconds. 7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // This wraps base::TimeTicks, and hence provides an abstract time that is 8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // always incrementing for use in measuring time durations. 8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) static int64 GetCurrentTime(); 8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Records a user-initiated action. 8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void RecordUserAction(const std::string& key); 8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Record any changes in a given histogram for transmission. 8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void RecordHistogramDelta(const std::string& histogram_name, 8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const base::HistogramSamples& snapshot); 8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Records the current operating environment, including metrics provided by 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the specified set of |metrics_providers|. Takes the list of installed 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // plugins, Google Update statistics, and synthetic trial IDs as parameters 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // because those can't be obtained synchronously from the UI thread. 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // A synthetic trial is one that is set up dynamically by code in Chrome. For 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // example, a pref may be mapped to a synthetic trial such that the group 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // is determined by the pref value. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RecordEnvironment( 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::vector<MetricsProvider*>& metrics_providers, 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<variations::ActiveGroupId>& synthetic_trials, 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int64 install_date); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Loads the environment proto that was saved by the last RecordEnvironment() 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // call from prefs and clears the pref value. Returns true on success or false 104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // if there was no saved environment in prefs or it could not be decoded. 105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool LoadSavedEnvironmentFromPrefs(); 106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Writes application stability metrics, including stability metrics provided 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // by the specified set of |metrics_providers|. The system profile portion of 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the log must have already been filled in by a call to RecordEnvironment() 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // or LoadSavedEnvironmentFromPrefs(). 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // NOTE: Has the side-effect of clearing the stability prefs.. 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // 113c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // If this log is of type INITIAL_STABILITY_LOG, records additional info such 114c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // as number of incomplete shutdowns as well as extra breakpad and debugger 115c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // stats. 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void RecordStabilityMetrics( 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::vector<MetricsProvider*>& metrics_providers, 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeDelta incremental_uptime, 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeDelta uptime); 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Records general metrics based on the specified |metrics_providers|. 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void RecordGeneralMetrics( 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::vector<MetricsProvider*>& metrics_providers); 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Stop writing to this record and generate the encoded representation. 12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // None of the Record* methods can be called after this is called. 12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void CloseLog(); 12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 12946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Fills |encoded_log| with the serialized protobuf representation of the 13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // record. Must only be called after CloseLog() has been called. 13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void GetEncodedLog(std::string* encoded_log); 13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const base::TimeTicks& creation_time() const { 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return creation_time_; 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int num_events() const { 13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return uma_proto_.omnibox_event_size() + 13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) uma_proto_.user_action_event_size(); 14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) LogType log_type() const { return log_type_; } 14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Exposed for the sake of mocking/accessing in test code. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fills |field_trial_ids| with the list of initialized field trials name and 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // group ids. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void GetFieldTrialIds( 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<variations::ActiveGroupId>* field_trial_ids) const; 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ChromeUserMetricsExtension* uma_proto() { return &uma_proto_; } 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ChromeUserMetricsExtension* uma_proto() const { 15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return &uma_proto_; 15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private: 158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Returns true if the environment has already been filled in by a call to 159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // RecordEnvironment() or LoadSavedEnvironmentFromPrefs(). 160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool HasEnvironment() const; 161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Returns true if the stability metrics have already been filled in by a 163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // call to RecordStabilityMetrics(). 164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool HasStabilityMetrics() const; 165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Within the stability group, write required attributes. 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WriteRequiredStabilityAttributes(PrefService* pref); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Within the stability group, write attributes that need to be updated asap 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and can't be delayed until the user decides to restart chromium. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delaying these stats would bias metrics away from happy long lived 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // chromium processes (ones that don't crash, and keep on running). 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void WriteRealtimeStabilityAttributes(PrefService* pref, 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeDelta incremental_uptime, 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeDelta uptime); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // closed_ is true when record has been packed up for sending, and should 17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // no longer be written to. It is only used for sanity checking. 17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool closed_; 18046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 18146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // The type of the log, i.e. initial or ongoing. 18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const LogType log_type_; 18346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 18446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Stores the protocol buffer representation for this log. 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ChromeUserMetricsExtension uma_proto_; 18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Used to interact with the embedder. Weak pointer; must outlive |this| 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // instance. 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MetricsServiceClient* const client_; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The time when the current log was created. 192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const base::TimeTicks creation_time_; 193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PrefService* local_state_; 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MetricsLog); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace metrics 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 20146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif // COMPONENTS_METRICS_METRICS_LOG_H_ 202