blob: 78174efba651a6fc3c6097311d298afe93d93f3e [file] [log] [blame]
Bertrand SIMONNET52e5b992015-08-10 15:18:00 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Darin Petkov65b01462010-04-14 13:32:20 -070016
Darin Petkov4fcb2ac2010-04-15 16:40:23 -070017#include <cstdio>
Darin Petkov65b01462010-04-14 13:32:20 -070018#include <cstdlib>
Darin Petkov65b01462010-04-14 13:32:20 -070019
James Hawkins5f646002015-09-08 15:18:17 -070020#include <base/memory/scoped_vector.h>
21
22#include "constants.h"
Bertrand SIMONNETe6cfd642014-07-09 16:35:23 -070023#include "metrics/metrics_library.h"
James Hawkins5f646002015-09-08 15:18:17 -070024#include "serialization/metric_sample.h"
25#include "serialization/serialization_utils.h"
Darin Petkov65b01462010-04-14 13:32:20 -070026
Luigi Semenzatoa7ebeb32013-03-19 15:02:42 -070027enum Mode {
James Hawkins5f646002015-09-08 15:18:17 -070028 kModeDumpLogs,
Luigi Semenzatoa7ebeb32013-03-19 15:02:42 -070029 kModeSendSample,
30 kModeSendEnumSample,
31 kModeSendSparseSample,
32 kModeSendUserAction,
33 kModeSendCrosEvent,
34 kModeHasConsent,
35 kModeIsGuestMode,
36};
37
Ken Mixtereafbbdf2010-10-01 15:38:42 -070038void ShowUsage() {
39 fprintf(stderr,
Bertrand SIMONNET475dfa62015-08-04 14:10:10 -070040 "Usage: metrics_client [-t] name sample min max nbuckets\n"
41 " metrics_client -e name sample max\n"
42 " metrics_client -s name sample\n"
43 " metrics_client -v event\n"
Darin Petkoved824852011-01-06 10:51:47 -080044 " metrics_client -u action\n"
James Hawkins5f646002015-09-08 15:18:17 -070045 " metrics_client [-cdg]\n"
Ken Mixtereafbbdf2010-10-01 15:38:42 -070046 "\n"
Bertrand SIMONNET475dfa62015-08-04 14:10:10 -070047 " default: send metric with integer values \n"
Ken Mixtereafbbdf2010-10-01 15:38:42 -070048 " |min| > 0, |min| <= sample < |max|\n"
Thiemo Nagel0b8cc1c2014-08-21 15:00:50 +020049 " -c: return exit status 0 if user consents to stats, 1 otherwise,\n"
50 " in guest mode always return 1\n"
James Hawkins5f646002015-09-08 15:18:17 -070051 " -d: dump cached logs to the console\n"
Ken Mixtereafbbdf2010-10-01 15:38:42 -070052 " -e: send linear/enumeration histogram data\n"
53 " -g: return exit status 0 if machine in guest mode, 1 otherwise\n"
Luigi Semenzatoa7ebeb32013-03-19 15:02:42 -070054 " -s: send a sparse histogram sample\n"
Darin Petkoved824852011-01-06 10:51:47 -080055 " -t: convert sample from double seconds to int milliseconds\n"
Luigi Semenzato32684222013-03-13 10:53:55 -070056 " -u: send a user action to Chrome\n"
Bertrand SIMONNETe6cfd642014-07-09 16:35:23 -070057 " -v: send a Platform.CrOSEvent enum histogram sample\n");
Ken Mixtereafbbdf2010-10-01 15:38:42 -070058 exit(1);
59}
Darin Petkov65b01462010-04-14 13:32:20 -070060
Luigi Semenzatod8abf552014-03-27 14:19:06 -070061static int ParseInt(const char *arg) {
62 char *endptr;
63 int value = strtol(arg, &endptr, 0);
64 if (*endptr != '\0') {
65 fprintf(stderr, "metrics client: bad integer \"%s\"\n", arg);
66 ShowUsage();
67 }
68 return value;
69}
70
71static double ParseDouble(const char *arg) {
72 char *endptr;
73 double value = strtod(arg, &endptr);
74 if (*endptr != '\0') {
75 fprintf(stderr, "metrics client: bad double \"%s\"\n", arg);
76 ShowUsage();
77 }
78 return value;
79}
80
Ken Mixtereafbbdf2010-10-01 15:38:42 -070081static int SendStats(char* argv[],
82 int name_index,
Luigi Semenzatoa7ebeb32013-03-19 15:02:42 -070083 enum Mode mode,
Bertrand SIMONNET475dfa62015-08-04 14:10:10 -070084 bool secs_to_msecs) {
Darin Petkovc2526a12010-04-21 14:24:04 -070085 const char* name = argv[name_index];
86 int sample;
Darin Petkov4fcb2ac2010-04-15 16:40:23 -070087 if (secs_to_msecs) {
Luigi Semenzatod8abf552014-03-27 14:19:06 -070088 sample = static_cast<int>(ParseDouble(argv[name_index + 1]) * 1000.0);
Darin Petkov4fcb2ac2010-04-15 16:40:23 -070089 } else {
Luigi Semenzatod8abf552014-03-27 14:19:06 -070090 sample = ParseInt(argv[name_index + 1]);
Darin Petkov4fcb2ac2010-04-15 16:40:23 -070091 }
92
Bertrand SIMONNET475dfa62015-08-04 14:10:10 -070093 MetricsLibrary metrics_lib;
94 metrics_lib.Init();
95 if (mode == kModeSendSparseSample) {
96 metrics_lib.SendSparseToUMA(name, sample);
97 } else if (mode == kModeSendEnumSample) {
98 int max = ParseInt(argv[name_index + 2]);
99 metrics_lib.SendEnumToUMA(name, sample, max);
100 } else {
101 int min = ParseInt(argv[name_index + 2]);
102 int max = ParseInt(argv[name_index + 3]);
103 int nbuckets = ParseInt(argv[name_index + 4]);
104 metrics_lib.SendToUMA(name, sample, min, max, nbuckets);
Darin Petkov65b01462010-04-14 13:32:20 -0700105 }
106 return 0;
107}
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700108
Darin Petkoved824852011-01-06 10:51:47 -0800109static int SendUserAction(char* argv[], int action_index) {
110 const char* action = argv[action_index];
111 MetricsLibrary metrics_lib;
112 metrics_lib.Init();
113 metrics_lib.SendUserActionToUMA(action);
114 return 0;
115}
116
Luigi Semenzato32684222013-03-13 10:53:55 -0700117static int SendCrosEvent(char* argv[], int action_index) {
118 const char* event = argv[action_index];
119 bool result;
120 MetricsLibrary metrics_lib;
121 metrics_lib.Init();
122 result = metrics_lib.SendCrosEventToUMA(event);
123 if (!result) {
124 fprintf(stderr, "metrics_client: could not send event %s\n", event);
125 return 1;
126 }
127 return 0;
128}
129
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700130static int HasConsent() {
131 MetricsLibrary metrics_lib;
132 metrics_lib.Init();
133 return metrics_lib.AreMetricsEnabled() ? 0 : 1;
134}
135
136static int IsGuestMode() {
137 MetricsLibrary metrics_lib;
138 metrics_lib.Init();
139 return metrics_lib.IsGuestMode() ? 0 : 1;
140}
141
James Hawkins5f646002015-09-08 15:18:17 -0700142static int DumpLogs() {
Bertrand SIMONNET2765d0a2015-09-09 10:38:20 -0700143 base::FilePath events_file = base::FilePath(
144 metrics::kMetricsDirectory).Append(metrics::kMetricsEventsFileName);
145 printf("Metrics from %s\n\n", events_file.value().data());
James Hawkins5f646002015-09-08 15:18:17 -0700146
147 ScopedVector<metrics::MetricSample> metrics;
Bertrand SIMONNET2765d0a2015-09-09 10:38:20 -0700148 metrics::SerializationUtils::ReadMetricsFromFile(events_file.value(),
149 &metrics);
James Hawkins5f646002015-09-08 15:18:17 -0700150
151 for (ScopedVector<metrics::MetricSample>::const_iterator i = metrics.begin();
152 i != metrics.end(); ++i) {
153 const metrics::MetricSample* sample = *i;
154 printf("name: %s\t", sample->name().c_str());
155 printf("type: ");
156
157 switch (sample->type()) {
158 case metrics::MetricSample::CRASH:
159 printf("CRASH");
160 break;
161 case metrics::MetricSample::HISTOGRAM:
162 printf("HISTOGRAM");
163 break;
164 case metrics::MetricSample::LINEAR_HISTOGRAM:
165 printf("LINEAR_HISTOGRAM");
166 break;
167 case metrics::MetricSample::SPARSE_HISTOGRAM:
168 printf("SPARSE_HISTOGRAM");
169 break;
170 case metrics::MetricSample::USER_ACTION:
171 printf("USER_ACTION");
172 break;
173 }
174
175 printf("\n");
176 }
177
178 return 0;
179}
180
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700181int main(int argc, char** argv) {
Luigi Semenzatoa7ebeb32013-03-19 15:02:42 -0700182 enum Mode mode = kModeSendSample;
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700183 bool secs_to_msecs = false;
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700184
185 // Parse arguments
186 int flag;
James Hawkins5f646002015-09-08 15:18:17 -0700187 while ((flag = getopt(argc, argv, "abcdegstuv")) != -1) {
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700188 switch (flag) {
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700189 case 'c':
190 mode = kModeHasConsent;
191 break;
James Hawkins5f646002015-09-08 15:18:17 -0700192 case 'd':
193 mode = kModeDumpLogs;
194 break;
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700195 case 'e':
Luigi Semenzatoa7ebeb32013-03-19 15:02:42 -0700196 mode = kModeSendEnumSample;
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700197 break;
198 case 'g':
199 mode = kModeIsGuestMode;
200 break;
Luigi Semenzatoa7ebeb32013-03-19 15:02:42 -0700201 case 's':
202 mode = kModeSendSparseSample;
203 break;
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700204 case 't':
205 secs_to_msecs = true;
206 break;
Darin Petkoved824852011-01-06 10:51:47 -0800207 case 'u':
208 mode = kModeSendUserAction;
209 break;
Luigi Semenzato32684222013-03-13 10:53:55 -0700210 case 'v':
211 mode = kModeSendCrosEvent;
212 break;
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700213 default:
Darin Petkov8032dd02011-05-09 16:33:19 -0700214 ShowUsage();
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700215 break;
216 }
217 }
Darin Petkoved824852011-01-06 10:51:47 -0800218 int arg_index = optind;
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700219
220 int expected_args = 0;
Luigi Semenzatoa7ebeb32013-03-19 15:02:42 -0700221 if (mode == kModeSendSample)
222 expected_args = 5;
223 else if (mode == kModeSendEnumSample)
224 expected_args = 3;
225 else if (mode == kModeSendSparseSample)
226 expected_args = 2;
Darin Petkoved824852011-01-06 10:51:47 -0800227 else if (mode == kModeSendUserAction)
228 expected_args = 1;
Luigi Semenzato32684222013-03-13 10:53:55 -0700229 else if (mode == kModeSendCrosEvent)
230 expected_args = 1;
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700231
Darin Petkoved824852011-01-06 10:51:47 -0800232 if ((arg_index + expected_args) != argc) {
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700233 ShowUsage();
234 }
235
Bertrand SIMONNETe6cfd642014-07-09 16:35:23 -0700236 switch (mode) {
Luigi Semenzatoa7ebeb32013-03-19 15:02:42 -0700237 case kModeSendSample:
238 case kModeSendEnumSample:
239 case kModeSendSparseSample:
240 if ((mode != kModeSendSample) && secs_to_msecs) {
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700241 ShowUsage();
242 }
243 return SendStats(argv,
Darin Petkoved824852011-01-06 10:51:47 -0800244 arg_index,
Luigi Semenzatoa7ebeb32013-03-19 15:02:42 -0700245 mode,
Bertrand SIMONNET475dfa62015-08-04 14:10:10 -0700246 secs_to_msecs);
Darin Petkoved824852011-01-06 10:51:47 -0800247 case kModeSendUserAction:
248 return SendUserAction(argv, arg_index);
Luigi Semenzato32684222013-03-13 10:53:55 -0700249 case kModeSendCrosEvent:
250 return SendCrosEvent(argv, arg_index);
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700251 case kModeHasConsent:
252 return HasConsent();
253 case kModeIsGuestMode:
254 return IsGuestMode();
James Hawkins5f646002015-09-08 15:18:17 -0700255 case kModeDumpLogs:
256 return DumpLogs();
Ken Mixtereafbbdf2010-10-01 15:38:42 -0700257 default:
258 ShowUsage();
259 return 0;
260 }
261}