OLD | NEW |
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 /* | 5 /* |
6 * metrics_library.cc | 6 * metrics_library.cc |
7 * | 7 * |
8 * Created on: Dec 1, 2009 | 8 * Created on: Dec 1, 2009 |
9 * Author: sosa | 9 * Author: sosa |
10 */ | 10 */ |
11 | 11 |
12 #include "metrics_library.h" | 12 #include "metrics_library.h" |
13 | 13 |
14 #include <errno.h> | 14 #include <errno.h> |
15 #include <sys/file.h> | 15 #include <sys/file.h> |
16 | 16 |
17 #include <cstdarg> | 17 #include <cstdarg> |
18 #include <cstdio> | 18 #include <cstdio> |
19 #include <cstring> | 19 #include <cstring> |
20 | 20 |
21 #define READ_WRITE_ALL_FILE_FLAGS \ | 21 #define READ_WRITE_ALL_FILE_FLAGS \ |
22 (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) | 22 (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) |
23 | 23 |
24 static const char kAutotestPath[] = "/tmp/.chromeos-metrics-autotest"; | 24 static const char kAutotestPath[] = |
25 static const char kChromePath[] = "/tmp/.chromeos-metrics"; | 25 "/var/log/metrics/autotest-events"; |
| 26 static const char kChromePath[] = |
| 27 "/var/log/metrics/uma-events"; |
26 static const int32_t kBufferSize = 1024; | 28 static const int32_t kBufferSize = 1024; |
27 | 29 |
28 using namespace std; | 30 using namespace std; |
29 | 31 |
30 // TODO(sosa@chromium.org) - use Chromium logger instead of stderr | 32 // TODO(sosa@chromium.org) - use Chromium logger instead of stderr |
31 static void PrintError(const char *message, const char *file, | 33 static void PrintError(const char *message, const char *file, |
32 int code) { | 34 int code) { |
33 const char *kProgramName = "metrics_library"; | 35 const char *kProgramName = "metrics_library"; |
34 if (code == 0) { | 36 if (code == 0) { |
35 fprintf(stderr, "%s: %s\n", kProgramName, message); | 37 fprintf(stderr, "%s: %s\n", kProgramName, message); |
36 } else if (file == NULL) { | 38 } else if (file == NULL) { |
37 fprintf(stderr, "%s: ", kProgramName); | 39 fprintf(stderr, "%s: ", kProgramName); |
38 perror(message); | 40 perror(message); |
39 } else { | 41 } else { |
40 fprintf(stderr, "%s: %s: ", kProgramName, file); | 42 fprintf(stderr, "%s: %s: ", kProgramName, file); |
41 perror(message); | 43 perror(message); |
42 } | 44 } |
43 } | 45 } |
44 | 46 |
45 // Sends message of size length to Chrome and returns true on success. | 47 // Sends message of size |length| to Chrome and returns true on success. |
46 static bool SendMessageToChrome(int32_t length, const char *message) { | 48 static bool SendMessageToChrome(int32_t length, const char *message) { |
47 int chrome_fd = open(kChromePath, | 49 int chrome_fd = open(kChromePath, |
48 O_WRONLY | O_APPEND | O_CREAT, | 50 O_WRONLY | O_APPEND | O_CREAT, |
49 READ_WRITE_ALL_FILE_FLAGS); | 51 READ_WRITE_ALL_FILE_FLAGS); |
50 // If we failed to open it, return. | 52 // If we failed to open it, return. |
51 if (chrome_fd < 0) { | 53 if (chrome_fd < 0) { |
52 PrintError("open", kChromePath, errno); | 54 PrintError("open", kChromePath, errno); |
53 return false; | 55 return false; |
54 } | 56 } |
55 | 57 |
(...skipping 18 matching lines...) Expand all Loading... |
74 | 76 |
75 // Release the file lock and close file. | 77 // Release the file lock and close file. |
76 if (flock(chrome_fd, LOCK_UN) < 0) { | 78 if (flock(chrome_fd, LOCK_UN) < 0) { |
77 PrintError("unlock", kChromePath, errno); | 79 PrintError("unlock", kChromePath, errno); |
78 success = false; | 80 success = false; |
79 } | 81 } |
80 close(chrome_fd); | 82 close(chrome_fd); |
81 return success; | 83 return success; |
82 } | 84 } |
83 | 85 |
84 // Formats a name/value message for Chrome in buffer and returns the | 86 // Formats a name/value message for Chrome in |buffer| and returns the |
85 // length of the message or a negative value on error. | 87 // length of the message or a negative value on error. |
86 // | 88 // |
87 // Message format is: | LENGTH(binary) | NAME | \0 | VALUE | \0 | | 89 // Message format is: | LENGTH(binary) | NAME | \0 | VALUE | \0 | |
88 // | 90 // |
89 // The arbitrary format argument covers the non-LENGTH portion of the | 91 // The arbitrary |format| argument covers the non-LENGTH portion of the |
90 // message. The caller is responsible to store the \0 character | 92 // message. The caller is responsible to store the \0 character |
91 // between NAME and VALUE (e.g. "%s%c%d", name, '\0', value). | 93 // between NAME and VALUE (e.g. "%s%c%d", name, '\0', value). |
92 static int32_t FormatChromeMessage(int32_t buffer_size, char *buffer, | 94 static int32_t FormatChromeMessage(int32_t buffer_size, char *buffer, |
93 const char *format, ...) { | 95 const char *format, ...) { |
94 int32_t message_length; | 96 int32_t message_length; |
95 size_t len_size = sizeof(message_length); | 97 size_t len_size = sizeof(message_length); |
96 | 98 |
97 // Format the non-LENGTH contents in the buffer by leaving space for | 99 // Format the non-LENGTH contents in the buffer by leaving space for |
98 // LENGTH at the start of the buffer. | 100 // LENGTH at the start of the buffer. |
99 va_list args; | 101 va_list args; |
(...skipping 12 matching lines...) Expand all Loading... |
112 if (message_length > buffer_size) { | 114 if (message_length > buffer_size) { |
113 PrintError("chrome message too long", NULL, 0); | 115 PrintError("chrome message too long", NULL, 0); |
114 return -1; | 116 return -1; |
115 } | 117 } |
116 | 118 |
117 // Prepend LENGTH to the message. | 119 // Prepend LENGTH to the message. |
118 memcpy(buffer, &message_length, len_size); | 120 memcpy(buffer, &message_length, len_size); |
119 return message_length; | 121 return message_length; |
120 } | 122 } |
121 | 123 |
122 bool MetricsLibrary::SendToAutotest(string name, int value) { | 124 // static |
| 125 bool MetricsLibrary::SendToAutotest(const string& name, int value) { |
123 FILE *autotest_file = fopen(kAutotestPath, "a+"); | 126 FILE *autotest_file = fopen(kAutotestPath, "a+"); |
124 if (autotest_file == NULL) { | 127 if (autotest_file == NULL) { |
125 PrintError("fopen", kAutotestPath, errno); | 128 PrintError("fopen", kAutotestPath, errno); |
126 return false; | 129 return false; |
127 } | 130 } |
128 | 131 |
129 fprintf(autotest_file, "%s=%d\n", name.c_str(), value); | 132 fprintf(autotest_file, "%s=%d\n", name.c_str(), value); |
130 fclose(autotest_file); | 133 fclose(autotest_file); |
131 return true; | 134 return true; |
132 } | 135 } |
133 | 136 |
134 bool MetricsLibrary::SendToChrome(string name, int value) { | 137 // static |
| 138 bool MetricsLibrary::SendToChrome(const string& name, int sample, |
| 139 int min, int max, int nbuckets) { |
135 // Format the message. | 140 // Format the message. |
136 char message[kBufferSize]; | 141 char message[kBufferSize]; |
137 int32_t message_length = | 142 int32_t message_length = |
138 FormatChromeMessage(kBufferSize, message, | 143 FormatChromeMessage(kBufferSize, message, |
139 "%s%c%d", name.c_str(), '\0', value); | 144 "histogram%c%s %d %d %d %d", '\0', |
| 145 name.c_str(), sample, min, max, nbuckets); |
140 | 146 |
141 if (message_length < 0) | 147 if (message_length < 0) |
142 return false; | 148 return false; |
143 | 149 |
144 // Send the message. | 150 // Send the message. |
145 return SendMessageToChrome(message_length, message); | 151 return SendMessageToChrome(message_length, message); |
146 } | 152 } |
OLD | NEW |