Add support for user actions to the metrics library and the metrics clients.

BUG=10696
TEST=unit tests, tested on the device through metrics_client and inspecting
the uma-events file.

Change-Id: Ie39dd8b5ab968c328993076369a4ba14cb7fcd81

Review URL: http://codereview.chromium.org/6094010
This commit is contained in:
Darin Petkov 2011-01-06 10:51:47 -08:00
parent b9b05e6047
commit ed82485c3b
7 changed files with 91 additions and 23 deletions

View File

@ -29,19 +29,9 @@ UMA. In order to use the library in a module, you need to do the following:
<metrics/metrics_library.h> header file. The file is installed in
$SYSROOT/usr/include/ when the metrics library is built and installed.
- The API includes two methods:
bool MetricsLibrary::SendToUMA(const std::string& name, int sample,
int min, int max, int nbuckets)
sends a sample for a regular (exponential) histogram.
bool MetricsLibrary::SendEnumToUMA(const std::string& name, int sample,
int max)
sends a sample for an enumeration (linear) histogram.
Before using these methods, a MetricsLibrary object needs to be constructed
and initialized through its Init method. See the complete API documentation in
metrics_library.h under src/platform/metrics/.
- The API is documented in metrics_library.h under src/platform/metrics/. Before
using the API methods, a MetricsLibrary object needs to be constructed and
initialized through its Init method.
For more information on the C API see c_metrics_library.h.
@ -88,9 +78,9 @@ The Metrics Client: metrics_client
================================================================================
metrics_client is a simple shell command-line utility for sending histogram
samples. It's installed under /usr/bin on the target platform and uses
libmetrics to send the data to Chrome. The utility is useful for generating
metrics from shell scripts.
samples and user actions. It's installed under /usr/bin on the target platform
and uses libmetrics to send the data to Chrome. The utility is useful for
generating metrics from shell scripts.
For usage information and command-line options, run "metrics_client" on the
target platform or look for "Usage:" in metrics_client.cc.

View File

@ -43,6 +43,14 @@ extern "C" int CMetricsLibrarySendEnumToUMA(CMetricsLibrary handle,
return lib->SendEnumToUMA(std::string(name), sample, max);
}
extern "C" int CMetricsLibrarySendUserActionToUMA(CMetricsLibrary handle,
const char* action) {
MetricsLibrary* lib = reinterpret_cast<MetricsLibrary*>(handle);
if (lib == NULL)
return 0;
return lib->SendUserActionToUMA(std::string(action));
}
extern "C" int CMetricsLibraryAreMetricsEnabled(CMetricsLibrary handle) {
MetricsLibrary* lib = reinterpret_cast<MetricsLibrary*>(handle);
if (lib == NULL)

View File

@ -28,6 +28,10 @@ int CMetricsLibrarySendToUMA(CMetricsLibrary handle,
int CMetricsLibrarySendEnumToUMA(CMetricsLibrary handle,
const char* name, int sample, int max);
// C wrapper for MetricsLibrary::SendUserActionToUMA.
int CMetricsLibrarySendUserActionToUMA(CMetricsLibrary handle,
const char* action);
// C wrapper for MetricsLibrary::AreMetricsEnabled.
int CMetricsLibraryAreMetricsEnabled(CMetricsLibrary handle);

View File

@ -11,6 +11,7 @@ void ShowUsage() {
fprintf(stderr,
"Usage: metrics_client [-ab] [-t] name sample min max nbuckets\n"
" metrics_client [-ab] -e name sample max\n"
" metrics_client -u action\n"
" metrics_client [-cg]\n"
"\n"
" default: send metric with integer values to Chrome only\n"
@ -20,7 +21,8 @@ void ShowUsage() {
" -c: return exit status 0 if user consents to stats, 1 otherwise\n"
" -e: send linear/enumeration histogram data\n"
" -g: return exit status 0 if machine in guest mode, 1 otherwise\n"
" -t: convert sample from double seconds to int milliseconds\n");
" -t: convert sample from double seconds to int milliseconds\n"
" -u: send a user action to Chrome\n");
exit(1);
}
@ -59,6 +61,14 @@ static int SendStats(char* argv[],
return 0;
}
static int SendUserAction(char* argv[], int action_index) {
const char* action = argv[action_index];
MetricsLibrary metrics_lib;
metrics_lib.Init();
metrics_lib.SendUserActionToUMA(action);
return 0;
}
static int HasConsent() {
MetricsLibrary metrics_lib;
metrics_lib.Init();
@ -74,6 +84,7 @@ static int IsGuestMode() {
int main(int argc, char** argv) {
enum Mode {
kModeSendStats,
kModeSendUserAction,
kModeHasConsent,
kModeIsGuestMode
} mode = kModeSendStats;
@ -85,7 +96,7 @@ int main(int argc, char** argv) {
// Parse arguments
int flag;
while ((flag = getopt(argc, argv, "abcegt")) != -1) {
while ((flag = getopt(argc, argv, "abcegtu")) != -1) {
switch (flag) {
case 'a':
mode = kModeSendStats;
@ -109,18 +120,23 @@ int main(int argc, char** argv) {
case 't':
secs_to_msecs = true;
break;
case 'u':
mode = kModeSendUserAction;
break;
default:
print_usage = true;
break;
}
}
int name_index = optind;
int arg_index = optind;
int expected_args = 0;
if (mode == kModeSendStats)
expected_args = send_enum ? 3 : 5;
else if (mode == kModeSendUserAction)
expected_args = 1;
if ((name_index + expected_args) != argc) {
if ((arg_index + expected_args) != argc) {
ShowUsage();
}
@ -130,11 +146,13 @@ int main(int argc, char** argv) {
ShowUsage();
}
return SendStats(argv,
name_index,
arg_index,
send_enum,
secs_to_msecs,
send_to_autotest,
send_to_chrome);
case kModeSendUserAction:
return SendUserAction(argv, arg_index);
case kModeHasConsent:
return HasConsent();
case kModeIsGuestMode:

View File

@ -221,7 +221,6 @@ bool MetricsLibrary::SendToUMA(const string& name, int sample,
FormatChromeMessage(kBufferSize, message,
"histogram%c%s %d %d %d %d", '\0',
name.c_str(), sample, min, max, nbuckets);
if (message_length < 0)
return false;
@ -237,7 +236,19 @@ bool MetricsLibrary::SendEnumToUMA(const std::string& name, int sample,
FormatChromeMessage(kBufferSize, message,
"linearhistogram%c%s %d %d", '\0',
name.c_str(), sample, max);
if (message_length < 0)
return false;
// Send the message.
return SendMessageToChrome(message_length, message);
}
bool MetricsLibrary::SendUserActionToUMA(const std::string& action) {
// Format the message.
char message[kBufferSize];
int32_t message_length =
FormatChromeMessage(kBufferSize, message,
"useraction%c%s", '\0', action.c_str());
if (message_length < 0)
return false;

View File

@ -69,6 +69,15 @@ class MetricsLibrary : public MetricsLibraryInterface {
// normal, while 100 is high).
bool SendEnumToUMA(const std::string& name, int sample, int max);
// Sends a user action to Chrome for transport to UMA and returns true on
// success. This method results in the equivalent of an asynchronous
// non-blocking RPC to UserMetrics::RecordAction (see the comments in
// chrome/browser/chromeos/external_metrics.cc and
// chrome/browser/metrics/user_metrics.h on how to register new user actions).
//
// |action| is the user-generated event (e.g., "MuteKeyPressed").
bool SendUserActionToUMA(const std::string& action);
// Sends to Autotest and returns true on success.
static bool SendToAutotest(const std::string& name, int value);

View File

@ -214,6 +214,23 @@ TEST_F(MetricsLibraryTest, SendToUMANotEnabled) {
EXPECT_FALSE(file_util::PathExists(kTestUMAEventsFile));
}
TEST_F(MetricsLibraryTest, SendUserActionToUMA) {
char buf[100];
const int kLen = 30;
EXPECT_TRUE(lib_.SendUserActionToUMA("SomeKeyPressed"));
EXPECT_EQ(kLen, file_util::ReadFile(kTestUMAEventsFile, buf, 100));
char exp[kLen];
sprintf(exp, "%c%c%c%cuseraction%cSomeKeyPressed", kLen, 0, 0, 0, 0);
EXPECT_EQ(0, memcmp(exp, buf, kLen));
}
TEST_F(MetricsLibraryTest, SendUserActionToUMANotEnabled) {
SetMetricsEnabled(false);
EXPECT_TRUE(lib_.SendUserActionToUMA("SomeOtherKeyPressed"));
EXPECT_FALSE(file_util::PathExists(kTestUMAEventsFile));
}
class CMetricsLibraryTest : public testing::Test {
protected:
virtual void SetUp() {
@ -268,6 +285,17 @@ TEST_F(CMetricsLibraryTest, SendToUMA) {
EXPECT_EQ(0, memcmp(exp, buf, kLen));
}
TEST_F(CMetricsLibraryTest, SendUserActionToUMA) {
char buf[100];
const int kLen = 30;
EXPECT_TRUE(CMetricsLibrarySendUserActionToUMA(lib_, "SomeKeyPressed"));
EXPECT_EQ(kLen, file_util::ReadFile(kTestUMAEventsFile, buf, 100));
char exp[kLen];
sprintf(exp, "%c%c%c%cuseraction%cSomeKeyPressed", kLen, 0, 0, 0, 0);
EXPECT_EQ(0, memcmp(exp, buf, kLen));
}
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();