1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file defines a set of user experience metrics data recorded by
// the MetricsService. This is the unit of data that is sent to the server.
#ifndef CHROME_BROWSER_METRICS_LOG_H__
#define CHROME_BROWSER_METRICS_LOG_H__
#include <libxml/xmlwriter.h>
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/histogram.h"
#include "base/time.h"
#include "chrome/common/page_transition_types.h"
#include "webkit/glue/webplugin.h"
struct AutocompleteLog;
class DictionaryValue;
class GURL;
class PrefService;
class MetricsLog {
public:
// Creates a new metrics log
// client_id is the identifier for this profile on this installation
// session_id is an integer that's incremented on each application launch
MetricsLog(const std::string& client_id, int session_id);
virtual ~MetricsLog();
static void RegisterPrefs(PrefService* prefs);
// Records a user-initiated action.
void RecordUserAction(const wchar_t* key);
enum WindowEventType {
WINDOW_CREATE = 0,
WINDOW_OPEN,
WINDOW_CLOSE,
WINDOW_DESTROY
};
void RecordWindowEvent(WindowEventType type, int window_id, int parent_id);
// Records a page load.
// window_id - the index of the tab in which the load took place
// url - which URL was loaded
// origin - what kind of action initiated the load
// load_time - how long it took to load the page
void RecordLoadEvent(int window_id,
const GURL& url,
PageTransition::Type origin,
int session_index,
base::TimeDelta load_time);
// Records the current operating environment. Takes the list of installed
// plugins as a parameter because that can't be obtained synchronously
// from the UI thread.
// profile_metrics, if non-null, gives a dictionary of all profile metrics
// that are to be recorded. Each value in profile_metrics should be a
// dictionary giving the metrics for the profile.
void RecordEnvironment(const std::vector<WebPluginInfo>& plugin_list,
const DictionaryValue* profile_metrics);
// Records the input text, available choices, and selected entry when the
// user uses the Omnibox to open a URL.
void RecordOmniboxOpenedURL(const AutocompleteLog& log);
// Record any changes in a given histogram for transmission.
void RecordHistogramDelta(const Histogram& histogram,
const Histogram::SampleSet& snapshot);
// Record recent delta for critical stability metrics. We can't wait for a
// restart to gather these, as that delay biases our observation away from
// users that run happily for a looooong time. We send increments with each
// uma log upload, just as we send histogram data.
void RecordIncrementalStabilityElements();
// Stop writing to this record and generate the encoded representation.
// None of the Record* methods can be called after this is called.
void CloseLog();
// These methods allow retrieval of the encoded representation of the
// record. They can only be called after CloseLog() has been called.
// GetEncodedLog returns false if buffer_size is less than
// GetEncodedLogSize();
int GetEncodedLogSize();
bool GetEncodedLog(char* buffer, int buffer_size);
// Returns the amount of time in seconds that this log has been in use.
int GetElapsedSeconds();
int num_events() { return num_events_; }
// Creates an MD5 hash of the given value, and returns hash as a byte
// buffer encoded as a std::string.
static std::string CreateHash(const std::string& value);
// Return a base64-encoded MD5 hash of the given string.
static std::string CreateBase64Hash(const std::string& string);
// Get the current version of the application as a string.
static std::string GetVersionString();
protected:
// Returns a string containing the current time.
// Virtual so that it can be overridden for testing.
virtual std::string GetCurrentTimeString();
private:
// Helper class that invokes StartElement from constructor, and EndElement
// from destructor.
//
// Use the macro OPEN_ELEMENT_FOR_SCOPE to help avoid usage problems.
class ScopedElement {
public:
ScopedElement(MetricsLog* log, const std::string& name) : log_(log) {
DCHECK(log);
log->StartElement(name.c_str());
}
ScopedElement(MetricsLog* log, const char* name) : log_(log) {
DCHECK(log);
log->StartElement(name);
}
~ScopedElement() {
log_->EndElement();
}
private:
MetricsLog* log_;
};
friend class ScopedElement;
static const char* WindowEventTypeToString(WindowEventType type);
// Convenience versions of xmlWriter functions
void StartElement(const char* name);
void EndElement();
void WriteAttribute(const std::string& name, const std::string& value);
void WriteIntAttribute(const std::string& name, int value);
void WriteInt64Attribute(const std::string& name, int64 value);
// Write the attributes that are common to every metrics event type.
void WriteCommonEventAttributes();
// Returns the date at which the current metrics client ID was created as
// a string containing milliseconds since the epoch, or "0" if none was found.
std::string GetInstallDate() const;
// Writes application stability metrics (as part of the profile log).
// NOTE: Has the side-effect of clearing those counts.
void WriteStabilityElement();
// Within stability group, write plugin crash stats.
void WritePluginStabilityElements(PrefService* pref);
// Within the stability group, write required attributes.
void WriteRequiredStabilityAttributes(PrefService* pref);
// Within the stability group, write attributes that need to be updated asap
// and can't be delayed until the user decides to restart chromium.
// Delaying these stats would bias metrics away from happy long lived
// chromium processes (ones that don't crash, and keep on running).
void WriteRealtimeStabilityAttributes(PrefService* pref);
// Writes the list of installed plugins.
void WritePluginList(const std::vector<WebPluginInfo>& plugin_list);
// Within the profile group, write basic install info including appversion.
void WriteInstallElement();
// Writes all profile metrics. This invokes WriteProfileMetrics for each key
// in all_profiles_metrics that starts with kProfilePrefix.
void WriteAllProfilesMetrics(const DictionaryValue& all_profiles_metrics);
// Writes metrics for the profile identified by key. This writes all
// key/value pairs in profile_metrics.
void WriteProfileMetrics(const std::wstring& key,
const DictionaryValue& profile_metrics);
base::Time start_time_;
base::Time end_time_;
std::string client_id_;
std::string session_id_;
// locked_ is true when record has been packed up for sending, and should
// no longer be written to. It is only used for sanity checking and is
// not a real lock.
bool locked_;
xmlBufferPtr buffer_;
xmlTextWriterPtr writer_;
int num_events_; // the number of events recorded in this log
DISALLOW_EVIL_CONSTRUCTORS(MetricsLog);
};
#endif // CHROME_BROWSER_METRICS_LOG_H__
|