Loading metricsd/metrics_client.cc +51 −2 Original line number Diff line number Diff line Loading @@ -17,9 +17,15 @@ #include <cstdio> #include <cstdlib> #include <base/memory/scoped_vector.h> #include "constants.h" #include "metrics/metrics_library.h" #include "serialization/metric_sample.h" #include "serialization/serialization_utils.h" enum Mode { kModeDumpLogs, kModeSendSample, kModeSendEnumSample, kModeSendSparseSample, Loading @@ -36,12 +42,13 @@ void ShowUsage() { " metrics_client -s name sample\n" " metrics_client -v event\n" " metrics_client -u action\n" " metrics_client [-cg]\n" " metrics_client [-cdg]\n" "\n" " default: send metric with integer values \n" " |min| > 0, |min| <= sample < |max|\n" " -c: return exit status 0 if user consents to stats, 1 otherwise,\n" " in guest mode always return 1\n" " -d: dump cached logs to the console\n" " -e: send linear/enumeration histogram data\n" " -g: return exit status 0 if machine in guest mode, 1 otherwise\n" " -s: send a sparse histogram sample\n" Loading Loading @@ -132,17 +139,57 @@ static int IsGuestMode() { return metrics_lib.IsGuestMode() ? 0 : 1; } static int DumpLogs() { printf("Metrics from %s\n\n", metrics::kMetricsEventsFilePath); ScopedVector<metrics::MetricSample> metrics; metrics::SerializationUtils::ReadMetricsFromFile( metrics::kMetricsEventsFilePath, &metrics); for (ScopedVector<metrics::MetricSample>::const_iterator i = metrics.begin(); i != metrics.end(); ++i) { const metrics::MetricSample* sample = *i; printf("name: %s\t", sample->name().c_str()); printf("type: "); switch (sample->type()) { case metrics::MetricSample::CRASH: printf("CRASH"); break; case metrics::MetricSample::HISTOGRAM: printf("HISTOGRAM"); break; case metrics::MetricSample::LINEAR_HISTOGRAM: printf("LINEAR_HISTOGRAM"); break; case metrics::MetricSample::SPARSE_HISTOGRAM: printf("SPARSE_HISTOGRAM"); break; case metrics::MetricSample::USER_ACTION: printf("USER_ACTION"); break; } printf("\n"); } return 0; } int main(int argc, char** argv) { enum Mode mode = kModeSendSample; bool secs_to_msecs = false; // Parse arguments int flag; while ((flag = getopt(argc, argv, "abcegstuv")) != -1) { while ((flag = getopt(argc, argv, "abcdegstuv")) != -1) { switch (flag) { case 'c': mode = kModeHasConsent; break; case 'd': mode = kModeDumpLogs; break; case 'e': mode = kModeSendEnumSample; break; Loading Loading @@ -203,6 +250,8 @@ int main(int argc, char** argv) { return HasConsent(); case kModeIsGuestMode: return IsGuestMode(); case kModeDumpLogs: return DumpLogs(); default: ShowUsage(); return 0; Loading metricsd/serialization/serialization_utils.cc +60 −28 Original line number Diff line number Diff line Loading @@ -96,6 +96,50 @@ bool ReadMessage(int fd, std::string* message) { return true; } // Opens the metrics log file at |filename| in the given |mode|. // // Returns the file descriptor wrapped in a valid ScopedFD on success. base::ScopedFD OpenMetricsFile(const std::string& filename, mode_t mode) { struct stat stat_buf; int result; result = stat(filename.c_str(), &stat_buf); if (result < 0) { if (errno != ENOENT) DPLOG(ERROR) << filename << ": bad metrics file stat"; // Nothing to collect---try later. return base::ScopedFD(); } if (stat_buf.st_size == 0) { // Also nothing to collect. return base::ScopedFD(); } base::ScopedFD fd(open(filename.c_str(), mode)); if (fd.get() < 0) { DPLOG(ERROR) << filename << ": cannot open"; return base::ScopedFD(); } return fd.Pass(); } // Parses the contents of the metrics log file descriptor |fd| into |metrics|. void ReadAllMetricsFromFd(int fd, ScopedVector<MetricSample>* metrics) { for (;;) { std::string message; if (!ReadMessage(fd, &message)) break; scoped_ptr<MetricSample> sample = SerializationUtils::ParseSample(message); if (sample) metrics->push_back(sample.release()); } } } // namespace scoped_ptr<MetricSample> SerializationUtils::ParseSample( Loading Loading @@ -131,30 +175,27 @@ scoped_ptr<MetricSample> SerializationUtils::ParseSample( return scoped_ptr<MetricSample>(); } void SerializationUtils::ReadAndTruncateMetricsFromFile( void SerializationUtils::ReadMetricsFromFile( const std::string& filename, ScopedVector<MetricSample>* metrics) { struct stat stat_buf; int result; result = stat(filename.c_str(), &stat_buf); if (result < 0) { if (errno != ENOENT) DPLOG(ERROR) << filename << ": bad metrics file stat"; // Nothing to collect---try later. base::ScopedFD fd(OpenMetricsFile(filename, O_RDONLY)); if (!fd.is_valid()) { return; } if (stat_buf.st_size == 0) { // Also nothing to collect. return; // This processes all messages in the log. ReadAllMetricsFromFd(fd.get(), metrics); } base::ScopedFD fd(open(filename.c_str(), O_RDWR)); if (fd.get() < 0) { DPLOG(ERROR) << filename << ": cannot open"; void SerializationUtils::ReadAndTruncateMetricsFromFile( const std::string& filename, ScopedVector<MetricSample>* metrics) { base::ScopedFD fd(OpenMetricsFile(filename, O_RDWR)); if (!fd.is_valid()) { return; } result = flock(fd.get(), LOCK_EX); int result = flock(fd.get(), LOCK_EX); if (result < 0) { DPLOG(ERROR) << filename << ": cannot lock"; return; Loading @@ -162,16 +203,7 @@ void SerializationUtils::ReadAndTruncateMetricsFromFile( // This processes all messages in the log. When all messages are // read and processed, or an error occurs, truncate the file to zero size. for (;;) { std::string message; if (!ReadMessage(fd.get(), &message)) break; scoped_ptr<MetricSample> sample = ParseSample(message); if (sample) metrics->push_back(sample.release()); } ReadAllMetricsFromFd(fd.get(), metrics); result = ftruncate(fd.get(), 0); if (result < 0) Loading metricsd/serialization/serialization_utils.h +5 −1 Original line number Diff line number Diff line Loading @@ -35,7 +35,11 @@ namespace SerializationUtils { // deserialization was successful) or a NULL scoped_ptr. scoped_ptr<MetricSample> ParseSample(const std::string& sample); // Reads all samples from a file and truncate the file when done. // Reads all samples from a file. The file contents remain unchanged. void ReadMetricsFromFile(const std::string& filename, ScopedVector<MetricSample>* metrics); // Reads all samples from a file and truncates the file when done. void ReadAndTruncateMetricsFromFile(const std::string& filename, ScopedVector<MetricSample>* metrics); Loading Loading
metricsd/metrics_client.cc +51 −2 Original line number Diff line number Diff line Loading @@ -17,9 +17,15 @@ #include <cstdio> #include <cstdlib> #include <base/memory/scoped_vector.h> #include "constants.h" #include "metrics/metrics_library.h" #include "serialization/metric_sample.h" #include "serialization/serialization_utils.h" enum Mode { kModeDumpLogs, kModeSendSample, kModeSendEnumSample, kModeSendSparseSample, Loading @@ -36,12 +42,13 @@ void ShowUsage() { " metrics_client -s name sample\n" " metrics_client -v event\n" " metrics_client -u action\n" " metrics_client [-cg]\n" " metrics_client [-cdg]\n" "\n" " default: send metric with integer values \n" " |min| > 0, |min| <= sample < |max|\n" " -c: return exit status 0 if user consents to stats, 1 otherwise,\n" " in guest mode always return 1\n" " -d: dump cached logs to the console\n" " -e: send linear/enumeration histogram data\n" " -g: return exit status 0 if machine in guest mode, 1 otherwise\n" " -s: send a sparse histogram sample\n" Loading Loading @@ -132,17 +139,57 @@ static int IsGuestMode() { return metrics_lib.IsGuestMode() ? 0 : 1; } static int DumpLogs() { printf("Metrics from %s\n\n", metrics::kMetricsEventsFilePath); ScopedVector<metrics::MetricSample> metrics; metrics::SerializationUtils::ReadMetricsFromFile( metrics::kMetricsEventsFilePath, &metrics); for (ScopedVector<metrics::MetricSample>::const_iterator i = metrics.begin(); i != metrics.end(); ++i) { const metrics::MetricSample* sample = *i; printf("name: %s\t", sample->name().c_str()); printf("type: "); switch (sample->type()) { case metrics::MetricSample::CRASH: printf("CRASH"); break; case metrics::MetricSample::HISTOGRAM: printf("HISTOGRAM"); break; case metrics::MetricSample::LINEAR_HISTOGRAM: printf("LINEAR_HISTOGRAM"); break; case metrics::MetricSample::SPARSE_HISTOGRAM: printf("SPARSE_HISTOGRAM"); break; case metrics::MetricSample::USER_ACTION: printf("USER_ACTION"); break; } printf("\n"); } return 0; } int main(int argc, char** argv) { enum Mode mode = kModeSendSample; bool secs_to_msecs = false; // Parse arguments int flag; while ((flag = getopt(argc, argv, "abcegstuv")) != -1) { while ((flag = getopt(argc, argv, "abcdegstuv")) != -1) { switch (flag) { case 'c': mode = kModeHasConsent; break; case 'd': mode = kModeDumpLogs; break; case 'e': mode = kModeSendEnumSample; break; Loading Loading @@ -203,6 +250,8 @@ int main(int argc, char** argv) { return HasConsent(); case kModeIsGuestMode: return IsGuestMode(); case kModeDumpLogs: return DumpLogs(); default: ShowUsage(); return 0; Loading
metricsd/serialization/serialization_utils.cc +60 −28 Original line number Diff line number Diff line Loading @@ -96,6 +96,50 @@ bool ReadMessage(int fd, std::string* message) { return true; } // Opens the metrics log file at |filename| in the given |mode|. // // Returns the file descriptor wrapped in a valid ScopedFD on success. base::ScopedFD OpenMetricsFile(const std::string& filename, mode_t mode) { struct stat stat_buf; int result; result = stat(filename.c_str(), &stat_buf); if (result < 0) { if (errno != ENOENT) DPLOG(ERROR) << filename << ": bad metrics file stat"; // Nothing to collect---try later. return base::ScopedFD(); } if (stat_buf.st_size == 0) { // Also nothing to collect. return base::ScopedFD(); } base::ScopedFD fd(open(filename.c_str(), mode)); if (fd.get() < 0) { DPLOG(ERROR) << filename << ": cannot open"; return base::ScopedFD(); } return fd.Pass(); } // Parses the contents of the metrics log file descriptor |fd| into |metrics|. void ReadAllMetricsFromFd(int fd, ScopedVector<MetricSample>* metrics) { for (;;) { std::string message; if (!ReadMessage(fd, &message)) break; scoped_ptr<MetricSample> sample = SerializationUtils::ParseSample(message); if (sample) metrics->push_back(sample.release()); } } } // namespace scoped_ptr<MetricSample> SerializationUtils::ParseSample( Loading Loading @@ -131,30 +175,27 @@ scoped_ptr<MetricSample> SerializationUtils::ParseSample( return scoped_ptr<MetricSample>(); } void SerializationUtils::ReadAndTruncateMetricsFromFile( void SerializationUtils::ReadMetricsFromFile( const std::string& filename, ScopedVector<MetricSample>* metrics) { struct stat stat_buf; int result; result = stat(filename.c_str(), &stat_buf); if (result < 0) { if (errno != ENOENT) DPLOG(ERROR) << filename << ": bad metrics file stat"; // Nothing to collect---try later. base::ScopedFD fd(OpenMetricsFile(filename, O_RDONLY)); if (!fd.is_valid()) { return; } if (stat_buf.st_size == 0) { // Also nothing to collect. return; // This processes all messages in the log. ReadAllMetricsFromFd(fd.get(), metrics); } base::ScopedFD fd(open(filename.c_str(), O_RDWR)); if (fd.get() < 0) { DPLOG(ERROR) << filename << ": cannot open"; void SerializationUtils::ReadAndTruncateMetricsFromFile( const std::string& filename, ScopedVector<MetricSample>* metrics) { base::ScopedFD fd(OpenMetricsFile(filename, O_RDWR)); if (!fd.is_valid()) { return; } result = flock(fd.get(), LOCK_EX); int result = flock(fd.get(), LOCK_EX); if (result < 0) { DPLOG(ERROR) << filename << ": cannot lock"; return; Loading @@ -162,16 +203,7 @@ void SerializationUtils::ReadAndTruncateMetricsFromFile( // This processes all messages in the log. When all messages are // read and processed, or an error occurs, truncate the file to zero size. for (;;) { std::string message; if (!ReadMessage(fd.get(), &message)) break; scoped_ptr<MetricSample> sample = ParseSample(message); if (sample) metrics->push_back(sample.release()); } ReadAllMetricsFromFd(fd.get(), metrics); result = ftruncate(fd.get(), 0); if (result < 0) Loading
metricsd/serialization/serialization_utils.h +5 −1 Original line number Diff line number Diff line Loading @@ -35,7 +35,11 @@ namespace SerializationUtils { // deserialization was successful) or a NULL scoped_ptr. scoped_ptr<MetricSample> ParseSample(const std::string& sample); // Reads all samples from a file and truncate the file when done. // Reads all samples from a file. The file contents remain unchanged. void ReadMetricsFromFile(const std::string& filename, ScopedVector<MetricSample>* metrics); // Reads all samples from a file and truncates the file when done. void ReadAndTruncateMetricsFromFile(const std::string& filename, ScopedVector<MetricSample>* metrics); Loading