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

Side by Side Diff: src/platform/metrics/metrics_library.cc

Issue 2079007: Add metrics library tests. Some metrics daemon API cleanup. (Closed) Base URL: ssh://git@chromiumos-git/chromeos
Patch Set: A bit more cleanup. Created 10 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
« no previous file with comments | « src/platform/metrics/metrics_library.h ('k') | src/platform/metrics/metrics_library_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS 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 "metrics_library.h" 5 #include "metrics_library.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <sys/file.h> 8 #include <sys/file.h>
9 9
10 #include <cstdarg> 10 #include <cstdarg>
11 #include <cstdio> 11 #include <cstdio>
12 #include <cstring> 12 #include <cstring>
13 13
14 #define READ_WRITE_ALL_FILE_FLAGS \ 14 #define READ_WRITE_ALL_FILE_FLAGS \
15 (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) 15 (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
16 16
17 static const char kAutotestPath[] = 17 static const char kAutotestPath[] =
18 "/var/log/metrics/autotest-events"; 18 "/var/log/metrics/autotest-events";
19 static const char kChromePath[] = 19 static const char kUMAEventsPath[] =
20 "/var/log/metrics/uma-events"; 20 "/var/log/metrics/uma-events";
21 static const int32_t kBufferSize = 1024; 21 static const int32_t kBufferSize = 1024;
22 22
23 using namespace std; 23 using namespace std;
24 24
25 // TODO(sosa@chromium.org) - use Chromium logger instead of stderr 25 // TODO(sosa@chromium.org) - use Chromium logger instead of stderr
26 static void PrintError(const char *message, const char *file, 26 static void PrintError(const char* message, const char* file,
27 int code) { 27 int code) {
28 const char *kProgramName = "metrics_library"; 28 static const char *kProgramName = "libmetrics";
29 if (code == 0) { 29 if (code == 0) {
30 fprintf(stderr, "%s: %s\n", kProgramName, message); 30 fprintf(stderr, "%s: %s\n", kProgramName, message);
31 } else if (file == NULL) { 31 } else if (file == NULL) {
32 fprintf(stderr, "%s: ", kProgramName); 32 fprintf(stderr, "%s: ", kProgramName);
33 perror(message); 33 perror(message);
34 } else { 34 } else {
35 fprintf(stderr, "%s: %s: ", kProgramName, file); 35 fprintf(stderr, "%s: %s: ", kProgramName, file);
36 perror(message); 36 perror(message);
37 } 37 }
38 } 38 }
39 39
40 // Sends message of size |length| to Chrome and returns true on success. 40 MetricsLibrary::MetricsLibrary()
41 static bool SendMessageToChrome(int32_t length, const char *message) { 41 : uma_events_file_(NULL) {}
42 int chrome_fd = open(kChromePath, 42
43 bool MetricsLibrary::SendMessageToChrome(int32_t length, const char* message) {
44 int chrome_fd = open(uma_events_file_,
43 O_WRONLY | O_APPEND | O_CREAT, 45 O_WRONLY | O_APPEND | O_CREAT,
44 READ_WRITE_ALL_FILE_FLAGS); 46 READ_WRITE_ALL_FILE_FLAGS);
45 // If we failed to open it, return. 47 // If we failed to open it, return.
46 if (chrome_fd < 0) { 48 if (chrome_fd < 0) {
47 PrintError("open", kChromePath, errno); 49 PrintError("open", uma_events_file_, errno);
48 return false; 50 return false;
49 } 51 }
50 52
51 // Need to chmod because open flags are anded with umask. Ignore the 53 // Need to chmod because open flags are anded with umask. Ignore the
52 // exit code -- a chronos process may fail chmoding because the file 54 // exit code -- a chronos process may fail chmoding because the file
53 // has been created by a root process but that should be OK. 55 // has been created by a root process but that should be OK.
54 fchmod(chrome_fd, READ_WRITE_ALL_FILE_FLAGS); 56 fchmod(chrome_fd, READ_WRITE_ALL_FILE_FLAGS);
55 57
56 // Grab an exclusive lock to protect Chrome from truncating 58 // Grab an exclusive lock to protect Chrome from truncating
57 // underneath us. Keep the file locked as briefly as possible. 59 // underneath us. Keep the file locked as briefly as possible.
58 if (flock(chrome_fd, LOCK_EX) < 0) { 60 if (flock(chrome_fd, LOCK_EX) < 0) {
59 PrintError("flock", kChromePath, errno); 61 PrintError("flock", uma_events_file_, errno);
60 close(chrome_fd); 62 close(chrome_fd);
61 return false; 63 return false;
62 } 64 }
63 65
64 bool success = true; 66 bool success = true;
65 if (write(chrome_fd, message, length) != length) { 67 if (write(chrome_fd, message, length) != length) {
66 PrintError("write", kChromePath, errno); 68 PrintError("write", uma_events_file_, errno);
67 success = false; 69 success = false;
68 } 70 }
69 71
70 // Release the file lock and close file. 72 // Release the file lock and close file.
71 if (flock(chrome_fd, LOCK_UN) < 0) { 73 if (flock(chrome_fd, LOCK_UN) < 0) {
72 PrintError("unlock", kChromePath, errno); 74 PrintError("unlock", uma_events_file_, errno);
73 success = false; 75 success = false;
74 } 76 }
75 close(chrome_fd); 77 close(chrome_fd);
76 return success; 78 return success;
77 } 79 }
78 80
79 // Formats a name/value message for Chrome in |buffer| and returns the 81 int32_t MetricsLibrary::FormatChromeMessage(int32_t buffer_size, char* buffer,
80 // length of the message or a negative value on error. 82 const char* format, ...) {
81 //
82 // Message format is: | LENGTH(binary) | NAME | \0 | VALUE | \0 |
83 //
84 // The arbitrary |format| argument covers the non-LENGTH portion of the
85 // message. The caller is responsible to store the \0 character
86 // between NAME and VALUE (e.g. "%s%c%d", name, '\0', value).
87 static int32_t FormatChromeMessage(int32_t buffer_size, char *buffer,
88 const char *format, ...) {
89 int32_t message_length; 83 int32_t message_length;
90 size_t len_size = sizeof(message_length); 84 size_t len_size = sizeof(message_length);
91 85
92 // Format the non-LENGTH contents in the buffer by leaving space for 86 // Format the non-LENGTH contents in the buffer by leaving space for
93 // LENGTH at the start of the buffer. 87 // LENGTH at the start of the buffer.
94 va_list args; 88 va_list args;
95 va_start(args, format); 89 va_start(args, format);
96 message_length = vsnprintf(&buffer[len_size], buffer_size - len_size, 90 message_length = vsnprintf(&buffer[len_size], buffer_size - len_size,
97 format, args); 91 format, args);
98 va_end(args); 92 va_end(args);
99 93
100 if (message_length < 0) { 94 if (message_length < 0) {
101 PrintError("chrome message format error", NULL, 0); 95 PrintError("chrome message format error", NULL, 0);
102 return -1; 96 return -1;
103 } 97 }
104 98
105 // +1 to account for the trailing \0. 99 // +1 to account for the trailing \0.
106 message_length += len_size + 1; 100 message_length += len_size + 1;
107 if (message_length > buffer_size) { 101 if (message_length > buffer_size) {
108 PrintError("chrome message too long", NULL, 0); 102 PrintError("chrome message too long", NULL, 0);
109 return -1; 103 return -1;
110 } 104 }
111 105
112 // Prepend LENGTH to the message. 106 // Prepend LENGTH to the message.
113 memcpy(buffer, &message_length, len_size); 107 memcpy(buffer, &message_length, len_size);
114 return message_length; 108 return message_length;
115 } 109 }
116 110
117 void MetricsLibrary::Init() { 111 void MetricsLibrary::Init() {
112 uma_events_file_ = kUMAEventsPath;
118 } 113 }
119 114
120 // static
121 bool MetricsLibrary::SendToAutotest(const string& name, int value) { 115 bool MetricsLibrary::SendToAutotest(const string& name, int value) {
122 FILE *autotest_file = fopen(kAutotestPath, "a+"); 116 FILE *autotest_file = fopen(kAutotestPath, "a+");
123 if (autotest_file == NULL) { 117 if (autotest_file == NULL) {
124 PrintError("fopen", kAutotestPath, errno); 118 PrintError("fopen", kAutotestPath, errno);
125 return false; 119 return false;
126 } 120 }
127 121
128 fprintf(autotest_file, "%s=%d\n", name.c_str(), value); 122 fprintf(autotest_file, "%s=%d\n", name.c_str(), value);
129 fclose(autotest_file); 123 fclose(autotest_file);
130 return true; 124 return true;
(...skipping 23 matching lines...) Expand all
154 FormatChromeMessage(kBufferSize, message, 148 FormatChromeMessage(kBufferSize, message,
155 "linearhistogram%c%s %d %d", '\0', 149 "linearhistogram%c%s %d %d", '\0',
156 name.c_str(), sample, max); 150 name.c_str(), sample, max);
157 151
158 if (message_length < 0) 152 if (message_length < 0)
159 return false; 153 return false;
160 154
161 // Send the message. 155 // Send the message.
162 return SendMessageToChrome(message_length, message); 156 return SendMessageToChrome(message_length, message);
163 } 157 }
OLDNEW
« no previous file with comments | « src/platform/metrics/metrics_library.h ('k') | src/platform/metrics/metrics_library_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698