OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/metrics/metrics_log.h" | 5 #include "chrome/browser/metrics/metrics_log.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/time.h" | 8 #include "base/time.h" |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
11 #include "base/file_version_info.h" | 11 #include "base/file_version_info.h" |
12 #include "base/md5.h" | 12 #include "base/md5.h" |
| 13 #include "base/perftimer.h" |
13 #include "base/scoped_ptr.h" | 14 #include "base/scoped_ptr.h" |
14 #include "base/string_util.h" | 15 #include "base/string_util.h" |
15 #include "base/sys_info.h" | 16 #include "base/sys_info.h" |
16 #include "base/utf_string_conversions.h" | 17 #include "base/utf_string_conversions.h" |
17 #include "base/third_party/nspr/prtime.h" | 18 #include "base/third_party/nspr/prtime.h" |
18 #include "chrome/app/chrome_version_info.h" | 19 #include "chrome/app/chrome_version_info.h" |
19 #include "chrome/browser/autocomplete/autocomplete.h" | 20 #include "chrome/browser/autocomplete/autocomplete.h" |
20 #include "chrome/browser/browser_process.h" | 21 #include "chrome/browser/browser_process.h" |
21 #include "chrome/browser/pref_service.h" | 22 #include "chrome/browser/pref_service.h" |
22 #include "chrome/common/logging_chrome.h" | 23 #include "chrome/common/logging_chrome.h" |
(...skipping 21 matching lines...) Expand all Loading... |
44 // static | 45 // static |
45 void MetricsLog::RegisterPrefs(PrefService* local_state) { | 46 void MetricsLog::RegisterPrefs(PrefService* local_state) { |
46 local_state->RegisterListPref(prefs::kStabilityPluginStats); | 47 local_state->RegisterListPref(prefs::kStabilityPluginStats); |
47 } | 48 } |
48 | 49 |
49 MetricsLog::MetricsLog(const std::string& client_id, int session_id) | 50 MetricsLog::MetricsLog(const std::string& client_id, int session_id) |
50 : start_time_(Time::Now()), | 51 : start_time_(Time::Now()), |
51 client_id_(client_id), | 52 client_id_(client_id), |
52 session_id_(IntToString(session_id)), | 53 session_id_(IntToString(session_id)), |
53 locked_(false), | 54 locked_(false), |
| 55 doc_(NULL), |
54 buffer_(NULL), | 56 buffer_(NULL), |
55 writer_(NULL), | 57 writer_(NULL), |
56 num_events_(0) { | 58 num_events_(0) { |
57 | 59 |
58 buffer_ = xmlBufferCreate(); | 60 buffer_ = xmlBufferCreate(); |
59 DCHECK(buffer_); | 61 DCHECK(buffer_); |
60 | 62 |
61 writer_ = xmlNewTextWriterMemory(buffer_, 0); | 63 #if defined(OS_CHROMEOS) |
| 64 writer_ = xmlNewTextWriterDoc(&doc_, /* compression */ 0); |
| 65 #else |
| 66 writer_ = xmlNewTextWriterMemory(buffer_, /* compression */ 0); |
| 67 #endif // OS_CHROMEOS |
62 DCHECK(writer_); | 68 DCHECK(writer_); |
63 | 69 |
64 int result = xmlTextWriterSetIndent(writer_, 2); | 70 int result = xmlTextWriterSetIndent(writer_, 2); |
65 DCHECK_EQ(0, result); | 71 DCHECK_EQ(0, result); |
66 | 72 |
67 StartElement("log"); | 73 StartElement("log"); |
68 WriteAttribute("clientid", client_id_); | 74 WriteAttribute("clientid", client_id_); |
69 WriteInt64Attribute("buildtime", GetBuildTime()); | 75 WriteInt64Attribute("buildtime", GetBuildTime()); |
70 WriteAttribute("appversion", GetVersionString()); | 76 WriteAttribute("appversion", GetVersionString()); |
71 | |
72 DCHECK_GE(result, 0); | |
73 } | 77 } |
74 | 78 |
75 MetricsLog::~MetricsLog() { | 79 MetricsLog::~MetricsLog() { |
76 if (writer_) | 80 FreeDocWriter(); |
77 xmlFreeTextWriter(writer_); | |
78 | 81 |
79 if (buffer_) | 82 if (buffer_) { |
80 xmlBufferFree(buffer_); | 83 xmlBufferFree(buffer_); |
| 84 buffer_ = NULL; |
| 85 } |
81 } | 86 } |
82 | 87 |
83 void MetricsLog::CloseLog() { | 88 void MetricsLog::CloseLog() { |
84 DCHECK(!locked_); | 89 DCHECK(!locked_); |
85 locked_ = true; | 90 locked_ = true; |
86 | 91 |
87 int result = xmlTextWriterEndDocument(writer_); | 92 int result = xmlTextWriterEndDocument(writer_); |
88 DCHECK_GE(result, 0); | 93 DCHECK_GE(result, 0); |
89 | 94 |
90 result = xmlTextWriterFlush(writer_); | 95 result = xmlTextWriterFlush(writer_); |
91 DCHECK_GE(result, 0); | 96 DCHECK_GE(result, 0); |
| 97 |
| 98 #if defined(OS_CHROMEOS) |
| 99 xmlNodePtr root = xmlDocGetRootElement(doc_); |
| 100 if (!hardware_class_.empty()) { |
| 101 // The hardware class is determined after the first ongoing log is |
| 102 // constructed, so this adds the root element's "hardwareclass" |
| 103 // attribute when the log is closed instead. |
| 104 xmlNewProp(root, UnsignedChar("hardwareclass"), |
| 105 UnsignedChar(hardware_class_.c_str())); |
| 106 } |
| 107 |
| 108 // Flattens the XML tree into a character buffer. |
| 109 PerfTimer dump_timer; |
| 110 result = xmlNodeDump(buffer_, doc_, root, /* level */ 0, /* format */ 1); |
| 111 DCHECK_GE(result, 0); |
| 112 UMA_HISTOGRAM_TIMES("UMA.XMLNodeDumpTime", dump_timer.Elapsed()); |
| 113 |
| 114 PerfTimer free_timer; |
| 115 FreeDocWriter(); |
| 116 UMA_HISTOGRAM_TIMES("UMA.XMLWriterDestructionTime", free_timer.Elapsed()); |
| 117 #endif // OS_CHROMEOS |
92 } | 118 } |
93 | 119 |
94 int MetricsLog::GetEncodedLogSize() { | 120 int MetricsLog::GetEncodedLogSize() { |
95 DCHECK(locked_); | 121 DCHECK(locked_); |
96 return buffer_->use; | 122 return buffer_->use; |
97 } | 123 } |
98 | 124 |
99 bool MetricsLog::GetEncodedLog(char* buffer, int buffer_size) { | 125 bool MetricsLog::GetEncodedLog(char* buffer, int buffer_size) { |
100 DCHECK(locked_); | 126 DCHECK(locked_); |
101 if (buffer_size < GetEncodedLogSize()) | 127 if (buffer_size < GetEncodedLogSize()) |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 case WINDOW_CLOSE: return "close"; | 304 case WINDOW_CLOSE: return "close"; |
279 case WINDOW_DESTROY: return "destroy"; | 305 case WINDOW_DESTROY: return "destroy"; |
280 | 306 |
281 default: | 307 default: |
282 NOTREACHED(); | 308 NOTREACHED(); |
283 return "unknown"; // Can't return NULL as this is used in a required | 309 return "unknown"; // Can't return NULL as this is used in a required |
284 // attribute. | 310 // attribute. |
285 } | 311 } |
286 } | 312 } |
287 | 313 |
| 314 void MetricsLog::FreeDocWriter() { |
| 315 if (writer_) { |
| 316 xmlFreeTextWriter(writer_); |
| 317 writer_ = NULL; |
| 318 } |
| 319 |
| 320 if (doc_) { |
| 321 xmlFreeDoc(doc_); |
| 322 doc_ = NULL; |
| 323 } |
| 324 } |
| 325 |
288 void MetricsLog::StartElement(const char* name) { | 326 void MetricsLog::StartElement(const char* name) { |
289 DCHECK(!locked_); | 327 DCHECK(!locked_); |
290 DCHECK(name); | 328 DCHECK(name); |
291 | 329 |
292 int result = xmlTextWriterStartElement(writer_, UnsignedChar(name)); | 330 int result = xmlTextWriterStartElement(writer_, UnsignedChar(name)); |
293 DCHECK_GE(result, 0); | 331 DCHECK_GE(result, 0); |
294 } | 332 } |
295 | 333 |
296 void MetricsLog::EndElement() { | 334 void MetricsLog::EndElement() { |
297 DCHECK(!locked_); | 335 DCHECK(!locked_); |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 | 773 |
736 for (size_t i = 0; i < histogram.bucket_count(); i++) { | 774 for (size_t i = 0; i < histogram.bucket_count(); i++) { |
737 if (snapshot.counts(i)) { | 775 if (snapshot.counts(i)) { |
738 OPEN_ELEMENT_FOR_SCOPE("histogrambucket"); | 776 OPEN_ELEMENT_FOR_SCOPE("histogrambucket"); |
739 WriteIntAttribute("min", histogram.ranges(i)); | 777 WriteIntAttribute("min", histogram.ranges(i)); |
740 WriteIntAttribute("max", histogram.ranges(i + 1)); | 778 WriteIntAttribute("max", histogram.ranges(i + 1)); |
741 WriteIntAttribute("count", snapshot.counts(i)); | 779 WriteIntAttribute("count", snapshot.counts(i)); |
742 } | 780 } |
743 } | 781 } |
744 } | 782 } |
OLD | NEW |