Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Side by Side Diff: components/metrics/chromeos/metrics_utils.cc

Issue 227873002: Create a histogram serialization mechanism in components/metrics (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Simplify the code to only one metric sample class. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/metrics/chromeos/metrics_utils.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/file_util.h"
11 #include "base/files/file_path.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/scoped_vector.h"
15 #include "base/strings/string_split.h"
16 #include "base/strings/string_util.h"
17 #include "components/metrics/chromeos/metric_sample.h"
18
19 namespace metrics {
20
21 scoped_ptr<MetricSample> MetricsUtils::ReadSample(const std::string& sample) {
22 std::vector<std::string> parts;
23 base::SplitString(sample, '\0', &parts);
24 // We should have two null terminated strings so split should produce
25 // three chunks.
26 if (parts.size() != 3) {
27 DLOG(ERROR) << "splitting message on \\0 produced " << parts.size()
28 << " parts (expected 3)";
29 return scoped_ptr<MetricSample>();
30 }
31 const std::string& name = parts[0];
32 const std::string& value = parts[1];
33
34 if (LowerCaseEqualsASCII(name, "crash")) {
35 return MetricSample::CrashSample(name);
36 } else if (LowerCaseEqualsASCII(name, "histogram")) {
37 return MetricSample::ReadHistogram(value);
38 } else if (LowerCaseEqualsASCII(name, "linearhistogram")) {
39 return MetricSample::ReadLinearHistogram(value);
40 } else if (LowerCaseEqualsASCII(name, "sparsehistogram")) {
41 return MetricSample::ReadSparseHistogram(value);
42 } else if (LowerCaseEqualsASCII(name, "useraction")) {
43 return MetricSample::UserActionSample(name);
44 } else {
45 DLOG(ERROR) << "invalid event type: " << name << ", value: " << value;
46 }
47 return scoped_ptr<MetricSample>();
48 }
49
50 bool MetricsUtils::WriteMetricToFile(MetricSample* sample,
51 const std::string& filename) {
52 if (!sample->IsValid())
53 return false;
54 base::File file(base::FilePath(filename),
55 base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_APPEND);
56 base::File::Error err = file.Lock();
Luigi Semenzato 2014/05/12 23:04:48 I assume file.Lock() waits for a lock to be releas
bsimonnet 2014/05/13 00:13:59 I thought it did but it does not (it is using fcnt
57 if (err != base::File::FILE_OK) {
58 DLOG(ERROR) << "could not lock the file";
Luigi Semenzato 2014/05/12 23:04:48 Is it possible to print the errno here? Or maybe
59 return false;
60 }
61
62 const std::string msg = sample->ToString();
63 int32_t size = msg.length() + sizeof(int32_t);
64 if (msg.length() > size_t(kMessageMaxLength)) {
65 DLOG(ERROR) << "cannot write message: too long";
66 return false;
67 }
68 file.WriteAtCurrentPos(reinterpret_cast<char*>(&size), sizeof(int32_t));
69 file.WriteAtCurrentPos(msg.c_str(), msg.length());
70
71 return true;
72 }
73
74 void MetricsUtils::ReadAndTruncateMetricsFromFile(
75 const std::string& filename,
76 ScopedVector<MetricSample>* metrics) {
77 base::File file(
78 base::FilePath(filename),
79 base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE);
80 base::File::Error err = file.Lock();
81 if (err != base::File::FILE_OK) {
82 DLOG(ERROR) << "could not lock the file";
83 return;
84 }
85 for (;;) {
86 int32 message_length;
87 int read = file.ReadAtCurrentPos(reinterpret_cast<char*>(&message_length),
88 sizeof(message_length));
89 if (read != sizeof(message_length))
90 break;
91
92 message_length -= sizeof(message_length);
93 if (message_length > kMessageMaxLength) {
94 DLOG(ERROR) << "cannot read message: too long";
95
96 // Skip the invalid message and continue reading.
97 if (file.Seek(base::File::FROM_CURRENT, message_length) != -1)
98 continue;
99
100 DLOG(ERROR) << "cannot skip long message";
101 // We do not know the size of the message. The rest of the file is not
102 // readable. Truncate the file and exit.
103 break;
104 }
105 char serialized_sample[kMessageMaxLength];
106 read = file.ReadAtCurrentPos(serialized_sample, message_length);
107 if (read != message_length) {
108 DLOG(ERROR) << "could not read message" << read;
109 break;
110 }
111 metrics->push_back(
112 ReadSample(std::string(serialized_sample, message_length)).release());
113 }
114 file.SetLength(0);
Luigi Semenzato 2014/05/12 23:04:48 Where is the file unlocked? Is it possible to unl
bsimonnet 2014/05/13 00:13:59 The file is closed when |file| is destroyed which
115 }
116
117 } // namespace metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698