summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/metrics/metrics_service.cc179
-rw-r--r--chrome/browser/metrics/metrics_service.h50
2 files changed, 7 insertions, 222 deletions
diff --git a/chrome/browser/metrics/metrics_service.cc b/chrome/browser/metrics/metrics_service.cc
index bac7155..cfe83f2 100644
--- a/chrome/browser/metrics/metrics_service.cc
+++ b/chrome/browser/metrics/metrics_service.cc
@@ -228,8 +228,8 @@ static const int kInitialInterlogDuration = 60; // one minute
// data.
static const int kMaxHistogramGatheringWaitDuration = 60000; // 60 seconds.
-// The default maximum number of events in a log uploaded to the UMA server.
-static const int kInitialEventLimit = 2400;
+// The maximum number of events in a log uploaded to the UMA server.
+static const int kEventLimit = 2400;
// If an upload fails, and the transmission was over this byte count, then we
// will discard the log, and not try to retransmit it. We also don't persist
@@ -445,7 +445,6 @@ MetricsService::MetricsService()
ALLOW_THIS_IN_INITIALIZER_LIST(log_sender_factory_(this)),
ALLOW_THIS_IN_INITIALIZER_LIST(state_saver_factory_(this)),
interlog_duration_(TimeDelta::FromSeconds(kInitialInterlogDuration)),
- log_event_limit_(kInitialEventLimit),
timer_pending_(false) {
DCHECK(IsSingleThreaded());
InitializeMetricsState();
@@ -852,7 +851,7 @@ void MetricsService::StopRecording(MetricsLogBase** log) {
// TODO(jar): Integrate bounds on log recording more consistently, so that we
// can stop recording logs that are too big much sooner.
- if (current_log_->num_events() > log_event_limit_) {
+ if (current_log_->num_events() > kEventLimit) {
UMA_HISTOGRAM_COUNTS("UMA.Discarded Log Events",
current_log_->num_events());
current_log_->CloseLog();
@@ -1398,16 +1397,13 @@ void MetricsService::OnURLFetchComplete(const URLFetcher* source,
if (local_state)
local_state->ScheduleSavePersistentPrefs();
- // Provide a default (free of exponetial backoff, other varances) in case
- // the server does not specify a value.
- interlog_duration_ = TimeDelta::FromSeconds(kMinSecondsPerLog);
-
- GetSettingsFromResponseData(data);
- // Override server specified interlog delay if there are unsent logs to
- // transmit.
+ // Override usual interlog delay if there are unsent logs to transmit,
+ // otherwise reset back to default.
if (unsent_logs()) {
DCHECK(state_ < SENDING_CURRENT_LOGS);
interlog_duration_ = TimeDelta::FromSeconds(kUnsentLogDelay);
+ } else {
+ interlog_duration_ = TimeDelta::FromSeconds(kMinSecondsPerLog);
}
}
@@ -1437,167 +1433,6 @@ void MetricsService::HandleBadResponseCode() {
}
}
-void MetricsService::GetSettingsFromResponseData(const std::string& data) {
- // We assume that the file is structured as a block opened by <response>
- // and that inside response, there is a block opened by tag <chrome_config>
- // other tags are ignored for now except the content of <chrome_config>.
- VLOG(1) << "METRICS: getting settings from response data: " << data;
-
- int data_size = static_cast<int>(data.size());
- if (data_size < 0) {
- VLOG(1) << "METRICS: server response data bad size: " << data_size
- << "; aborting extraction of settings";
- return;
- }
- xmlDocPtr doc = xmlReadMemory(data.c_str(), data_size, "", NULL, 0);
- // If the document is malformed, we just use the settings that were there.
- if (!doc) {
- VLOG(1) << "METRICS: reading xml from server response data failed";
- return;
- }
-
- xmlNodePtr top_node = xmlDocGetRootElement(doc), chrome_config_node = NULL;
- // Here, we find the chrome_config node by name.
- for (xmlNodePtr p = top_node->children; p; p = p->next) {
- if (xmlStrEqual(p->name, BAD_CAST "chrome_config")) {
- chrome_config_node = p;
- break;
- }
- }
- // If the server data is formatted wrong and there is no
- // config node where we expect, we just drop out.
- if (chrome_config_node != NULL)
- GetSettingsFromChromeConfigNode(chrome_config_node);
- xmlFreeDoc(doc);
-}
-
-void MetricsService::GetSettingsFromChromeConfigNode(
- xmlNodePtr chrome_config_node) {
- // Iterate through all children of the config node.
- for (xmlNodePtr current_node = chrome_config_node->children;
- current_node;
- current_node = current_node->next) {
- // If we find the upload tag, we appeal to another function
- // GetSettingsFromUploadNode to read all the data in it.
- if (xmlStrEqual(current_node->name, BAD_CAST "upload")) {
- GetSettingsFromUploadNode(current_node);
- continue;
- }
- }
-}
-
-void MetricsService::InheritedProperties::OverwriteWhereNeeded(
- xmlNodePtr node) {
- xmlChar* salt_value = xmlGetProp(node, BAD_CAST "salt");
- if (salt_value) // If the property isn't there, xmlGetProp returns NULL.
- salt = atoi(reinterpret_cast<char*>(salt_value));
- // If the property isn't there, we keep the value the property had before
-
- xmlChar* denominator_value = xmlGetProp(node, BAD_CAST "denominator");
- if (denominator_value)
- denominator = atoi(reinterpret_cast<char*>(denominator_value));
-}
-
-void MetricsService::GetSettingsFromUploadNode(xmlNodePtr upload_node) {
- InheritedProperties props;
- GetSettingsFromUploadNodeRecursive(upload_node, props, "", true);
-}
-
-void MetricsService::GetSettingsFromUploadNodeRecursive(
- xmlNodePtr node,
- InheritedProperties props,
- const std::string& path_prefix,
- bool uploadOn) {
- props.OverwriteWhereNeeded(node);
-
- // The bool uploadOn is set to true if the data represented by current
- // node should be uploaded. This gets inherited in the tree; the children
- // of a node that has already been rejected for upload get rejected for
- // upload.
- uploadOn = uploadOn && NodeProbabilityTest(node, props);
-
- // The path is a / separated list of the node names ancestral to the current
- // one. So, if you want to check if the current node has a certain name,
- // compare to name. If you want to check if it is a certan tag at a certain
- // place in the tree, compare to the whole path.
- std::string name = std::string(reinterpret_cast<const char*>(node->name));
- std::string path = path_prefix + "/" + name;
-
- if (path == "/upload") {
- xmlChar* upload_interval_val = xmlGetProp(node, BAD_CAST "interval");
- if (upload_interval_val) {
- interlog_duration_ = TimeDelta::FromSeconds(
- atoi(reinterpret_cast<char*>(upload_interval_val)));
- }
-
- server_permits_upload_ = uploadOn;
- } else if (path == "/upload/logs") {
- xmlChar* log_event_limit_val = xmlGetProp(node, BAD_CAST "event_limit");
- if (log_event_limit_val)
- log_event_limit_ = atoi(reinterpret_cast<char*>(log_event_limit_val));
- }
-
- // Recursive call. If the node is a leaf i.e. if it ends in a "/>", then it
- // doesn't have children, so node->children is NULL, and this loop doesn't
- // call (that's how the recursion ends).
- for (xmlNodePtr child_node = node->children;
- child_node;
- child_node = child_node->next) {
- GetSettingsFromUploadNodeRecursive(child_node, props, path, uploadOn);
- }
-}
-
-bool MetricsService::NodeProbabilityTest(xmlNodePtr node,
- InheritedProperties props) const {
- // Default value of probability on any node is 1, but recall that
- // its parents can already have been rejected for upload.
- double probability = 1;
-
- // If a probability is specified in the node, we use it instead.
- xmlChar* probability_value = xmlGetProp(node, BAD_CAST "probability");
- if (probability_value)
- probability = atoi(reinterpret_cast<char*>(probability_value));
-
- return ProbabilityTest(probability, props.salt, props.denominator);
-}
-
-bool MetricsService::ProbabilityTest(double probability,
- int salt,
- int denominator) const {
- // Okay, first we figure out how many of the digits of the
- // client_id_ we need in order to make a nice pseudorandomish
- // number in the range [0,denominator). Too many digits is
- // fine.
-
- // n is the length of the client_id_ string
- size_t n = client_id_.size();
-
- // idnumber is a positive integer generated from the client_id_.
- // It plus salt is going to give us our pseudorandom number.
- int idnumber = 0;
- const char* client_id_c_str = client_id_.c_str();
-
- // Here we hash the relevant digits of the client_id_
- // string somehow to get a big integer idnumber (could be negative
- // from wraparound)
- int big = 1;
- int last_pos = n - 1;
- for (size_t j = 0; j < n; ++j) {
- idnumber += static_cast<int>(client_id_c_str[last_pos - j]) * big;
- big *= 10;
- }
-
- // Mod id number by denominator making sure to get a non-negative
- // answer.
- idnumber = ((idnumber % denominator) + denominator) % denominator;
-
- // ((idnumber + salt) % denominator) / denominator is in the range [0,1]
- // if it's less than probability we call that an affirmative coin
- // toss.
- return static_cast<double>((idnumber + salt) % denominator) <
- probability * denominator;
-}
-
void MetricsService::LogWindowChange(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
diff --git a/chrome/browser/metrics/metrics_service.h b/chrome/browser/metrics/metrics_service.h
index b2add89..922cf38 100644
--- a/chrome/browser/metrics/metrics_service.h
+++ b/chrome/browser/metrics/metrics_service.h
@@ -266,51 +266,6 @@ class MetricsService : public NotificationObserver,
// a response code not equal to 200.
void HandleBadResponseCode();
- // Class to hold all attributes that gets inherited by children in the UMA
- // response data xml tree. This is to make it convenient in the
- // recursive function that does the tree traversal to pass all such
- // data in the recursive call. If you want to add more such attributes,
- // add them to this class.
- class InheritedProperties {
- public:
- InheritedProperties() : salt(123123), denominator(1000000) {}
- int salt, denominator;
- // Notice salt and denominator are inherited from parent nodes, but
- // not probability; the default value of probability is 1.
-
- // When a new node is reached it might have fields which overwrite inherited
- // properties for that node (and its children). Call this method to
- // overwrite those settings.
- void OverwriteWhereNeeded(xmlNodePtr node);
- };
-
- // Called by OnURLFetchComplete with data as the argument
- // parses the xml returned by the server in the call to OnURLFetchComplete
- // and extracts settings for subsequent frequency and content of log posts.
- void GetSettingsFromResponseData(const std::string& data);
-
- // This is a helper function for GetSettingsFromResponseData which iterates
- // through the xml tree at the level of the <chrome_config> node.
- void GetSettingsFromChromeConfigNode(xmlNodePtr chrome_config_node);
-
- // GetSettingsFromUploadNode handles iteration over the children of the
- // <upload> child of the <chrome_config> node. It calls the recursive
- // function GetSettingsFromUploadNodeRecursive which does the actual
- // tree traversal.
- void GetSettingsFromUploadNode(xmlNodePtr upload_node);
- void GetSettingsFromUploadNodeRecursive(xmlNodePtr node,
- InheritedProperties props,
- const std::string& path_prefix,
- bool uploadOn);
-
- // NodeProbabilityTest gets called at every node in the tree traversal
- // performed by GetSettingsFromUploadNodeRecursive. It determines from
- // the inherited attributes (salt, denominator) and the probability
- // assiciated with the node whether that node and its contents should
- // contribute to the upload.
- bool NodeProbabilityTest(xmlNodePtr node, InheritedProperties props) const;
- bool ProbabilityTest(double probability, int salt, int denominator) const;
-
// Records a window-related notification.
void LogWindowChange(NotificationType type,
const NotificationSource& source,
@@ -458,11 +413,6 @@ class MetricsService : public NotificationObserver,
// quickly transmit those unsent logs while we continue to build a log.
base::TimeDelta interlog_duration_;
- // The maximum number of events which get transmitted in a log. This defaults
- // to a constant and otherwise is provided by the UMA server in the server
- // response data.
- int log_event_limit_;
-
// Indicate that a timer for sending the next log has already been queued.
bool timer_pending_;