| 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 |