| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium 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 // Description of the life cycle of a instance of MetricsService. | 6 // Description of the life cycle of a instance of MetricsService. |
| 7 // | 7 // |
| 8 // OVERVIEW | 8 // OVERVIEW |
| 9 // | 9 // |
| 10 // A MetricsService instance is typically created at application startup. It is | 10 // A MetricsService instance is typically created at application startup. It is |
| 11 // the central controller for the acquisition of log data, and the automatic | 11 // the central controller for the acquisition of log data, and the automatic |
| 12 // transmission of that log data to an external server. Its major job is to | 12 // transmission of that log data to an external server. Its major job is to |
| 13 // manage logs, grouping them for transmission, and transmitting them. As part | 13 // manage logs, grouping them for transmission, and transmitting them. As part |
| 14 // of its grouping, MS finalizes logs by including some just-in-time gathered | 14 // of its grouping, MS finalizes logs by including some just-in-time gathered |
| 15 // memory statistics, snapshotting the current stats of numerous histograms, | 15 // memory statistics, snapshotting the current stats of numerous histograms, |
| 16 // closing the logs, translating to protocol buffer format, and compressing the | 16 // closing the logs, translating to protocol buffer format, and compressing the |
| 17 // results for transmission. Transmission includes submitting a compressed log | 17 // results for transmission. Transmission includes submitting a compressed log |
| 18 // as data in a URL-post, and retransmitting (or retaining at process | 18 // as data in a URL-post, and retransmitting (or retaining at process |
| 19 // termination) if the attempted transmission failed. Retention across process | 19 // termination) if the attempted transmission failed. Retention across process |
| 20 // terminations is done using the the PrefServices facilities. The retained logs | 20 // terminations is done using the the PrefServices facilities. The retained logs |
| 21 // (the ones that never got transmitted) are compressed and base64-encoded | 21 // (the ones that never got transmitted) are compressed and base64-encoded |
| 22 // before being persisted. | 22 // before being persisted. |
| 23 // | 23 // |
| 24 // Logs fall into one of two categories: "initial logs," and "ongoing logs." | 24 // Logs fall into one of two categories: "initial logs," and "ongoing logs." |
| 25 // There is at most one initial log sent for each complete run of the chromium | 25 // There is at most one initial log sent for each complete run of Chrome (from |
| 26 // product (from startup, to browser shutdown). An initial log is generally | 26 // startup, to browser shutdown). An initial log is generally transmitted some |
| 27 // transmitted some short time (1 minute?) after startup, and includes stats | 27 // short time (1 minute?) after startup, and includes stats such as recent crash |
| 28 // such as recent crash info, the number and types of plugins, etc. The | 28 // info, the number and types of plugins, etc. The external server's response |
| 29 // external server's response to the initial log conceptually tells this MS if | 29 // to the initial log conceptually tells this MS if it should continue |
| 30 // it should continue transmitting logs (during this session). The server | 30 // transmitting logs (during this session). The server response can actually be |
| 31 // response can actually be much more detailed, and always includes (at a | 31 // much more detailed, and always includes (at a minimum) how often additional |
| 32 // minimum) how often additional ongoing logs should be sent. | 32 // ongoing logs should be sent. |
| 33 // | 33 // |
| 34 // After the above initial log, a series of ongoing logs will be transmitted. | 34 // After the above initial log, a series of ongoing logs will be transmitted. |
| 35 // The first ongoing log actually begins to accumulate information stating when | 35 // The first ongoing log actually begins to accumulate information stating when |
| 36 // the MS was first constructed. Note that even though the initial log is | 36 // the MS was first constructed. Note that even though the initial log is |
| 37 // commonly sent a full minute after startup, the initial log does not include | 37 // commonly sent a full minute after startup, the initial log does not include |
| 38 // much in the way of user stats. The most common interlog period (delay) | 38 // much in the way of user stats. The most common interlog period (delay) |
| 39 // is 30 minutes. That time period starts when the first user action causes a | 39 // is 30 minutes. That time period starts when the first user action causes a |
| 40 // logging event. This means that if there is no user action, there may be long | 40 // logging event. This means that if there is no user action, there may be long |
| 41 // periods without any (ongoing) log transmissions. Ongoing logs typically | 41 // periods without any (ongoing) log transmissions. Ongoing logs typically |
| 42 // contain very detailed records of user activities (ex: opened tab, closed | 42 // contain very detailed records of user activities (ex: opened tab, closed |
| 43 // tab, fetched URL, maximized window, etc.) In addition, just before an | 43 // tab, fetched URL, maximized window, etc.) In addition, just before an |
| 44 // ongoing log is closed out, a call is made to gather memory statistics. Those | 44 // ongoing log is closed out, a call is made to gather memory statistics. Those |
| 45 // memory statistics are deposited into a histogram, and the log finalization | 45 // memory statistics are deposited into a histogram, and the log finalization |
| 46 // code is then called. In the finalization, a call to a Histogram server | 46 // code is then called. In the finalization, a call to a Histogram server |
| 47 // acquires a list of all local histograms that have been flagged for upload | 47 // acquires a list of all local histograms that have been flagged for upload |
| 48 // to the UMA server. The finalization also acquires a the most recent number | 48 // to the UMA server. The finalization also acquires the most recent number |
| 49 // of page loads, along with any counts of renderer or plugin crashes. | 49 // of page loads, along with any counts of renderer or plugin crashes. |
| 50 // | 50 // |
| 51 // When the browser shuts down, there will typically be a fragment of an ongoing | 51 // When the browser shuts down, there will typically be a fragment of an ongoing |
| 52 // log that has not yet been transmitted. At shutdown time, that fragment | 52 // log that has not yet been transmitted. At shutdown time, that fragment is |
| 53 // is closed (including snapshotting histograms), and persisted, for | 53 // closed (including snapshotting histograms), and persisted, for potential |
| 54 // potential transmission during a future run of the product. | 54 // transmission during a future run of the product. |
| 55 // | 55 // |
| 56 // There are two slightly abnormal shutdown conditions. There is a | 56 // There are two slightly abnormal shutdown conditions. There is a |
| 57 // "disconnected scenario," and a "really fast startup and shutdown" scenario. | 57 // "disconnected scenario," and a "really fast startup and shutdown" scenario. |
| 58 // In the "never connected" situation, the user has (during the running of the | 58 // In the "never connected" situation, the user has (during the running of the |
| 59 // process) never established an internet connection. As a result, attempts to | 59 // process) never established an internet connection. As a result, attempts to |
| 60 // transmit the initial log have failed, and a lot(?) of data has accumulated in | 60 // transmit the initial log have failed, and a lot(?) of data has accumulated in |
| 61 // the ongoing log (which didn't yet get closed, because there was never even a | 61 // the ongoing log (which didn't yet get closed, because there was never even a |
| 62 // contemplation of sending it). There is also a kindred "lost connection" | 62 // contemplation of sending it). There is also a kindred "lost connection" |
| 63 // situation, where a loss of connection prevented an ongoing log from being | 63 // situation, where a loss of connection prevented an ongoing log from being |
| 64 // transmitted, and a (still open) log was stuck accumulating a lot(?) of data, | 64 // transmitted, and a (still open) log was stuck accumulating a lot(?) of data, |
| 65 // while the earlier log retried its transmission. In both of these | 65 // while the earlier log retried its transmission. In both of these |
| 66 // disconnected situations, two logs need to be, and are, persistently stored | 66 // disconnected situations, two logs need to be, and are, persistently stored |
| 67 // for future transmission. | 67 // for future transmission. |
| 68 // | 68 // |
| 69 // The other unusual shutdown condition, termed "really fast startup and | 69 // The other unusual shutdown condition, termed "really fast startup and |
| 70 // shutdown," involves the deliberate user termination of the process before | 70 // shutdown," involves the deliberate user termination of the process before |
| 71 // the initial log is even formed or transmitted. In that situation, no logging | 71 // the initial log is even formed or transmitted. In that situation, no logging |
| 72 // is done, but the historical crash statistics remain (unlogged) for inclusion | 72 // is done, but the historical crash statistics remain (unlogged) for inclusion |
| 73 // in a future run's initial log. (i.e., we don't lose crash stats). | 73 // in a future run's initial log. (i.e., we don't lose crash stats). |
| 74 // | 74 // |
| 75 // With the above overview, we can now describe the state machine's various | 75 // With the above overview, we can now describe the state machine's various |
| 76 // stats, based on the State enum specified in the state_ member. Those states | 76 // states, based on the State enum specified in the state_ member. Those states |
| 77 // are: | 77 // are: |
| 78 // | 78 // |
| 79 // INITIALIZED, // Constructor was called. | 79 // INITIALIZED, // Constructor was called. |
| 80 // INIT_TASK_SCHEDULED, // Waiting for deferred init tasks to complete. | 80 // INIT_TASK_SCHEDULED, // Waiting for deferred init tasks to finish. |
| 81 // INIT_TASK_DONE, // Waiting for timer to send initial log. | 81 // INIT_TASK_DONE, // Waiting for timer to send initial log. |
| 82 // INITIAL_LOG_READY, // Initial log generated, and waiting for reply. | 82 // SENDING_INITIAL_STABILITY_LOG, // Initial stability log being sent. |
| 83 // SENDING_OLD_LOGS, // Sending unsent logs from previous session. | 83 // SENDING_INITIAL_METRICS_LOG, // Initial metrics log being sent. |
| 84 // SENDING_CURRENT_LOGS, // Sending standard current logs as they accrue. | 84 // SENDING_OLD_LOGS, // Sending unsent logs from previous session. |
| 85 // SENDING_CURRENT_LOGS, // Sending ongoing logs as they acrue. |
| 85 // | 86 // |
| 86 // In more detail, we have: | 87 // In more detail, we have: |
| 87 // | 88 // |
| 88 // INITIALIZED, // Constructor was called. | 89 // INITIALIZED, // Constructor was called. |
| 89 // The MS has been constructed, but has taken no actions to compose the | 90 // The MS has been constructed, but has taken no actions to compose the |
| 90 // initial log. | 91 // initial log. |
| 91 // | 92 // |
| 92 // INIT_TASK_SCHEDULED, // Waiting for deferred init tasks to complete. | 93 // INIT_TASK_SCHEDULED, // Waiting for deferred init tasks to finish. |
| 93 // Typically about 30 seconds after startup, a task is sent to a second thread | 94 // Typically about 30 seconds after startup, a task is sent to a second thread |
| 94 // (the file thread) to perform deferred (lower priority and slower) | 95 // (the file thread) to perform deferred (lower priority and slower) |
| 95 // initialization steps such as getting the list of plugins. That task will | 96 // initialization steps such as getting the list of plugins. That task will |
| 96 // (when complete) make an async callback (via a Task) to indicate the | 97 // (when complete) make an async callback (via a Task) to indicate the |
| 97 // completion. | 98 // completion. |
| 98 // | 99 // |
| 99 // INIT_TASK_DONE, // Waiting for timer to send initial log. | 100 // INIT_TASK_DONE, // Waiting for timer to send initial log. |
| 100 // The callback has arrived, and it is now possible for an initial log to be | 101 // The callback has arrived, and it is now possible for an initial log to be |
| 101 // created. This callback typically arrives back less than one second after | 102 // created. This callback typically arrives back less than one second after |
| 102 // the deferred init task is dispatched. | 103 // the deferred init task is dispatched. |
| 103 // | 104 // |
| 104 // INITIAL_LOG_READY, // Initial log generated, and waiting for reply. | 105 // SENDING_INITIAL_STABILITY_LOG, // Initial stability log being sent. |
| 105 // This state is entered only after an initial log has been composed, and | 106 // During initialization, if a crash occurred during the previous session, an |
| 106 // prepared for transmission. It is also the case that any previously unsent | 107 // initial stability log will be generated and registered with the log manager. |
| 107 // logs have been loaded into instance variables for possible transmission. | 108 // This state will be entered if a stability log was prepared during metrics |
| 109 // service initialization (in InitializeMetricsRecordingState()) and is waiting |
| 110 // to be transmitted when it's time to send up the first log (per the reporting |
| 111 // scheduler). If there is no initial stability log (e.g. there was no previous |
| 112 // crash), then this state will be skipped and the state will advance to |
| 113 // SENDING_INITIAL_METRICS_LOG. |
| 114 // |
| 115 // SENDING_INITIAL_METRICS_LOG, // Initial metrics log being sent. |
| 116 // This state is entered after the initial metrics log has been composed, and |
| 117 // prepared for transmission. This happens after SENDING_INITIAL_STABILITY_LOG |
| 118 // if there was an initial stability log (see above). It is also the case that |
| 119 // any previously unsent logs have been loaded into instance variables for |
| 120 // possible transmission. |
| 108 // | 121 // |
| 109 // SENDING_OLD_LOGS, // Sending unsent logs from previous session. | 122 // SENDING_OLD_LOGS, // Sending unsent logs from previous session. |
| 110 // This state indicates that the initial log for this session has been | 123 // This state indicates that the initial log for this session has been |
| 111 // successfully sent and it is now time to send any logs that were | 124 // successfully sent and it is now time to send any logs that were |
| 112 // saved from previous sessions. All such logs will be transmitted before | 125 // saved from previous sessions. All such logs will be transmitted before |
| 113 // exiting this state, and proceeding with ongoing logs from the current session | 126 // exiting this state, and proceeding with ongoing logs from the current session |
| 114 // (see next state). | 127 // (see next state). |
| 115 // | 128 // |
| 116 // SENDING_CURRENT_LOGS, // Sending standard current logs as they accrue. | 129 // SENDING_CURRENT_LOGS, // Sending standard current logs as they accrue. |
| 117 // Current logs are being accumulated. Typically every 20 minutes a log is | 130 // Current logs are being accumulated. Typically every 20 minutes a log is |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 | 343 |
| 331 void MarkAppCleanShutdownAndCommit() { | 344 void MarkAppCleanShutdownAndCommit() { |
| 332 PrefService* pref = g_browser_process->local_state(); | 345 PrefService* pref = g_browser_process->local_state(); |
| 333 pref->SetBoolean(prefs::kStabilityExitedCleanly, true); | 346 pref->SetBoolean(prefs::kStabilityExitedCleanly, true); |
| 334 pref->SetInteger(prefs::kStabilityExecutionPhase, | 347 pref->SetInteger(prefs::kStabilityExecutionPhase, |
| 335 MetricsService::SHUTDOWN_COMPLETE); | 348 MetricsService::SHUTDOWN_COMPLETE); |
| 336 // Start writing right away (write happens on a different thread). | 349 // Start writing right away (write happens on a different thread). |
| 337 pref->CommitPendingWrite(); | 350 pref->CommitPendingWrite(); |
| 338 } | 351 } |
| 339 | 352 |
| 353 // Returns whether initial stability metrics should be sent in a separate log. |
| 354 bool SendSeparateInitialStabilityLog() { |
| 355 return base::FieldTrialList::FindFullName("UMAStability") == "SeparateLog"; |
| 356 } |
| 357 |
| 340 } // namespace | 358 } // namespace |
| 341 | 359 |
| 342 | 360 |
| 343 SyntheticTrialGroup::SyntheticTrialGroup(uint32 trial, | 361 SyntheticTrialGroup::SyntheticTrialGroup(uint32 trial, |
| 344 uint32 group, | 362 uint32 group, |
| 345 base::TimeTicks start) | 363 base::TimeTicks start) |
| 346 : start_time(start) { | 364 : start_time(start) { |
| 347 id.name = trial; | 365 id.name = trial; |
| 348 id.group = group; | 366 id.group = group; |
| 349 } | 367 } |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 local_state->ClearPref(prefs::kMetricsOngoingLogs); | 514 local_state->ClearPref(prefs::kMetricsOngoingLogs); |
| 497 } | 515 } |
| 498 | 516 |
| 499 MetricsService::MetricsService() | 517 MetricsService::MetricsService() |
| 500 : recording_active_(false), | 518 : recording_active_(false), |
| 501 reporting_active_(false), | 519 reporting_active_(false), |
| 502 test_mode_active_(false), | 520 test_mode_active_(false), |
| 503 state_(INITIALIZED), | 521 state_(INITIALIZED), |
| 504 low_entropy_source_(kLowEntropySourceNotSet), | 522 low_entropy_source_(kLowEntropySourceNotSet), |
| 505 idle_since_last_transmission_(false), | 523 idle_since_last_transmission_(false), |
| 524 session_id_(-1), |
| 506 next_window_id_(0), | 525 next_window_id_(0), |
| 507 self_ptr_factory_(this), | 526 self_ptr_factory_(this), |
| 508 state_saver_factory_(this), | 527 state_saver_factory_(this), |
| 509 waiting_for_asynchronous_reporting_step_(false), | 528 waiting_for_asynchronous_reporting_step_(false), |
| 510 num_async_histogram_fetches_in_progress_(0), | 529 num_async_histogram_fetches_in_progress_(0), |
| 511 entropy_source_returned_(LAST_ENTROPY_NONE) { | 530 entropy_source_returned_(LAST_ENTROPY_NONE) { |
| 512 DCHECK(IsSingleThreaded()); | 531 DCHECK(IsSingleThreaded()); |
| 513 InitializeMetricsState(); | |
| 514 | |
| 515 base::Closure callback = base::Bind(&MetricsService::StartScheduledUpload, | |
| 516 self_ptr_factory_.GetWeakPtr()); | |
| 517 scheduler_.reset(new MetricsReportingScheduler(callback)); | |
| 518 log_manager_.set_log_serializer(new MetricsLogSerializer()); | |
| 519 log_manager_.set_max_ongoing_log_store_size(kUploadLogAvoidRetransmitSize); | |
| 520 | 532 |
| 521 BrowserChildProcessObserver::Add(this); | 533 BrowserChildProcessObserver::Add(this); |
| 522 } | 534 } |
| 523 | 535 |
| 524 MetricsService::~MetricsService() { | 536 MetricsService::~MetricsService() { |
| 525 DisableRecording(); | 537 DisableRecording(); |
| 526 | 538 |
| 527 BrowserChildProcessObserver::Remove(this); | 539 BrowserChildProcessObserver::Remove(this); |
| 528 } | 540 } |
| 529 | 541 |
| 542 void MetricsService::InitializeMetricsRecordingState( |
| 543 ReportingState reporting_state) { |
| 544 InitializeMetricsState(reporting_state); |
| 545 |
| 546 base::Closure callback = base::Bind(&MetricsService::StartScheduledUpload, |
| 547 self_ptr_factory_.GetWeakPtr()); |
| 548 scheduler_.reset(new MetricsReportingScheduler(callback)); |
| 549 log_manager_.set_log_serializer(new MetricsLogSerializer()); |
| 550 log_manager_.set_max_ongoing_log_store_size(kUploadLogAvoidRetransmitSize); |
| 551 } |
| 552 |
| 530 void MetricsService::Start() { | 553 void MetricsService::Start() { |
| 531 HandleIdleSinceLastTransmission(false); | 554 HandleIdleSinceLastTransmission(false); |
| 532 EnableRecording(); | 555 EnableRecording(); |
| 533 EnableReporting(); | 556 EnableReporting(); |
| 534 } | 557 } |
| 535 | 558 |
| 536 void MetricsService::StartRecordingForTests() { | 559 void MetricsService::StartRecordingForTests() { |
| 537 test_mode_active_ = true; | 560 test_mode_active_ = true; |
| 538 EnableRecording(); | 561 EnableRecording(); |
| 539 DisableReporting(); | 562 DisableReporting(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 554 | 577 |
| 555 void MetricsService::DisableReporting() { | 578 void MetricsService::DisableReporting() { |
| 556 reporting_active_ = false; | 579 reporting_active_ = false; |
| 557 } | 580 } |
| 558 | 581 |
| 559 std::string MetricsService::GetClientId() { | 582 std::string MetricsService::GetClientId() { |
| 560 return client_id_; | 583 return client_id_; |
| 561 } | 584 } |
| 562 | 585 |
| 563 scoped_ptr<const base::FieldTrial::EntropyProvider> | 586 scoped_ptr<const base::FieldTrial::EntropyProvider> |
| 564 MetricsService::CreateEntropyProvider(bool reporting_will_be_enabled) { | 587 MetricsService::CreateEntropyProvider(ReportingState reporting_state) { |
| 565 // For metrics reporting-enabled users, we combine the client ID and low | 588 // For metrics reporting-enabled users, we combine the client ID and low |
| 566 // entropy source to get the final entropy source. Otherwise, only use the low | 589 // entropy source to get the final entropy source. Otherwise, only use the low |
| 567 // entropy source. | 590 // entropy source. |
| 568 // This has two useful properties: | 591 // This has two useful properties: |
| 569 // 1) It makes the entropy source less identifiable for parties that do not | 592 // 1) It makes the entropy source less identifiable for parties that do not |
| 570 // know the low entropy source. | 593 // know the low entropy source. |
| 571 // 2) It makes the final entropy source resettable. | 594 // 2) It makes the final entropy source resettable. |
| 572 const int low_entropy_source_value = GetLowEntropySource(); | 595 const int low_entropy_source_value = GetLowEntropySource(); |
| 573 UMA_HISTOGRAM_SPARSE_SLOWLY("UMA.LowEntropySourceValue", | 596 UMA_HISTOGRAM_SPARSE_SLOWLY("UMA.LowEntropySourceValue", |
| 574 low_entropy_source_value); | 597 low_entropy_source_value); |
| 575 if (reporting_will_be_enabled) { | 598 if (reporting_state == REPORTING_ENABLED) { |
| 576 if (entropy_source_returned_ == LAST_ENTROPY_NONE) | 599 if (entropy_source_returned_ == LAST_ENTROPY_NONE) |
| 577 entropy_source_returned_ = LAST_ENTROPY_HIGH; | 600 entropy_source_returned_ = LAST_ENTROPY_HIGH; |
| 578 DCHECK_EQ(LAST_ENTROPY_HIGH, entropy_source_returned_); | 601 DCHECK_EQ(LAST_ENTROPY_HIGH, entropy_source_returned_); |
| 579 const std::string high_entropy_source = | 602 const std::string high_entropy_source = |
| 580 client_id_ + base::IntToString(low_entropy_source_value); | 603 client_id_ + base::IntToString(low_entropy_source_value); |
| 581 return scoped_ptr<const base::FieldTrial::EntropyProvider>( | 604 return scoped_ptr<const base::FieldTrial::EntropyProvider>( |
| 582 new metrics::SHA1EntropyProvider(high_entropy_source)); | 605 new metrics::SHA1EntropyProvider(high_entropy_source)); |
| 583 } | 606 } |
| 584 | 607 |
| 585 if (entropy_source_returned_ == LAST_ENTROPY_NONE) | 608 if (entropy_source_returned_ == LAST_ENTROPY_NONE) |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 #if defined(OS_ANDROID) || defined(OS_IOS) | 804 #if defined(OS_ANDROID) || defined(OS_IOS) |
| 782 void MetricsService::OnAppEnterBackground() { | 805 void MetricsService::OnAppEnterBackground() { |
| 783 scheduler_->Stop(); | 806 scheduler_->Stop(); |
| 784 | 807 |
| 785 MarkAppCleanShutdownAndCommit(); | 808 MarkAppCleanShutdownAndCommit(); |
| 786 | 809 |
| 787 // At this point, there's no way of knowing when the process will be | 810 // At this point, there's no way of knowing when the process will be |
| 788 // killed, so this has to be treated similar to a shutdown, closing and | 811 // killed, so this has to be treated similar to a shutdown, closing and |
| 789 // persisting all logs. Unlinke a shutdown, the state is primed to be ready | 812 // persisting all logs. Unlinke a shutdown, the state is primed to be ready |
| 790 // to continue logging and uploading if the process does return. | 813 // to continue logging and uploading if the process does return. |
| 791 if (recording_active() && state_ >= INITIAL_LOG_READY) { | 814 if (recording_active() && state_ >= SENDING_INITIAL_STABILITY_LOG) { |
| 792 PushPendingLogsToPersistentStorage(); | 815 PushPendingLogsToPersistentStorage(); |
| 793 // Persisting logs closes the current log, so start recording a new log | 816 // Persisting logs closes the current log, so start recording a new log |
| 794 // immediately to capture any background work that might be done before the | 817 // immediately to capture any background work that might be done before the |
| 795 // process is killed. | 818 // process is killed. |
| 796 OpenNewLog(); | 819 OpenNewLog(); |
| 797 } | 820 } |
| 798 } | 821 } |
| 799 | 822 |
| 800 void MetricsService::OnAppEnterForeground() { | 823 void MetricsService::OnAppEnterForeground() { |
| 801 PrefService* pref = g_browser_process->local_state(); | 824 PrefService* pref = g_browser_process->local_state(); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 886 #endif // defined(OS_WIN) | 909 #endif // defined(OS_WIN) |
| 887 | 910 |
| 888 //------------------------------------------------------------------------------ | 911 //------------------------------------------------------------------------------ |
| 889 // private methods | 912 // private methods |
| 890 //------------------------------------------------------------------------------ | 913 //------------------------------------------------------------------------------ |
| 891 | 914 |
| 892 | 915 |
| 893 //------------------------------------------------------------------------------ | 916 //------------------------------------------------------------------------------ |
| 894 // Initialization methods | 917 // Initialization methods |
| 895 | 918 |
| 896 void MetricsService::InitializeMetricsState() { | 919 void MetricsService::InitializeMetricsState(ReportingState reporting_state) { |
| 897 #if defined(OS_POSIX) | 920 #if defined(OS_POSIX) |
| 898 network_stats_server_ = chrome_common_net::kEchoTestServerLocation; | 921 network_stats_server_ = chrome_common_net::kEchoTestServerLocation; |
| 899 http_pipelining_test_server_ = chrome_common_net::kPipelineTestServerBaseUrl; | 922 http_pipelining_test_server_ = chrome_common_net::kPipelineTestServerBaseUrl; |
| 900 #else | 923 #else |
| 901 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); | 924 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| 902 network_stats_server_ = dist->GetNetworkStatsServer(); | 925 network_stats_server_ = dist->GetNetworkStatsServer(); |
| 903 http_pipelining_test_server_ = dist->GetHttpPipeliningTestServer(); | 926 http_pipelining_test_server_ = dist->GetHttpPipeliningTestServer(); |
| 904 #endif | 927 #endif |
| 905 | 928 |
| 906 PrefService* pref = g_browser_process->local_state(); | 929 PrefService* pref = g_browser_process->local_state(); |
| 907 DCHECK(pref); | 930 DCHECK(pref); |
| 908 | 931 |
| 932 // TODO(asvitkine): Kill this logic when SendSeparateInitialStabilityLog() is |
| 933 // is made the default behavior. |
| 909 if ((pref->GetInt64(prefs::kStabilityStatsBuildTime) | 934 if ((pref->GetInt64(prefs::kStabilityStatsBuildTime) |
| 910 != MetricsLog::GetBuildTime()) || | 935 != MetricsLog::GetBuildTime()) || |
| 911 (pref->GetString(prefs::kStabilityStatsVersion) | 936 (pref->GetString(prefs::kStabilityStatsVersion) |
| 912 != MetricsLog::GetVersionString())) { | 937 != MetricsLog::GetVersionString())) { |
| 913 // This is a new version, so we don't want to confuse the stats about the | 938 // This is a new version, so we don't want to confuse the stats about the |
| 914 // old version with info that we upload. | 939 // old version with info that we upload. |
| 915 DiscardOldStabilityStats(pref); | 940 DiscardOldStabilityStats(pref); |
| 916 pref->SetString(prefs::kStabilityStatsVersion, | 941 pref->SetString(prefs::kStabilityStatsVersion, |
| 917 MetricsLog::GetVersionString()); | 942 MetricsLog::GetVersionString()); |
| 918 pref->SetInt64(prefs::kStabilityStatsBuildTime, | 943 pref->SetInt64(prefs::kStabilityStatsBuildTime, |
| 919 MetricsLog::GetBuildTime()); | 944 MetricsLog::GetBuildTime()); |
| 920 } | 945 } |
| 921 | 946 |
| 922 // Update session ID | |
| 923 session_id_ = pref->GetInteger(prefs::kMetricsSessionID); | 947 session_id_ = pref->GetInteger(prefs::kMetricsSessionID); |
| 924 ++session_id_; | |
| 925 pref->SetInteger(prefs::kMetricsSessionID, session_id_); | |
| 926 | |
| 927 // Stability bookkeeping | |
| 928 IncrementPrefValue(prefs::kStabilityLaunchCount); | |
| 929 | 948 |
| 930 if (!pref->GetBoolean(prefs::kStabilityExitedCleanly)) { | 949 if (!pref->GetBoolean(prefs::kStabilityExitedCleanly)) { |
| 931 IncrementPrefValue(prefs::kStabilityCrashCount); | 950 IncrementPrefValue(prefs::kStabilityCrashCount); |
| 932 // Reset flag, and wait until we call LogNeedForCleanShutdown() before | 951 // Reset flag, and wait until we call LogNeedForCleanShutdown() before |
| 933 // monitoring. | 952 // monitoring. |
| 934 pref->SetBoolean(prefs::kStabilityExitedCleanly, true); | 953 pref->SetBoolean(prefs::kStabilityExitedCleanly, true); |
| 935 | 954 |
| 936 // TODO(rtenneti): On windows, consider saving/getting execution_phase from | 955 // TODO(rtenneti): On windows, consider saving/getting execution_phase from |
| 937 // the registry. | 956 // the registry. |
| 938 int execution_phase = pref->GetInteger(prefs::kStabilityExecutionPhase); | 957 int execution_phase = pref->GetInteger(prefs::kStabilityExecutionPhase); |
| 939 UMA_HISTOGRAM_SPARSE_SLOWLY("Chrome.Browser.CrashedExecutionPhase", | 958 UMA_HISTOGRAM_SPARSE_SLOWLY("Chrome.Browser.CrashedExecutionPhase", |
| 940 execution_phase); | 959 execution_phase); |
| 960 |
| 961 // If the previous session didn't exit cleanly, then prepare an initial |
| 962 // stability log if UMA is enabled. |
| 963 bool reporting_will_be_enabled = (reporting_state == REPORTING_ENABLED); |
| 964 if (reporting_will_be_enabled && SendSeparateInitialStabilityLog()) |
| 965 PrepareInitialStabilityLog(); |
| 941 } | 966 } |
| 967 |
| 968 // Update session ID. |
| 969 ++session_id_; |
| 970 pref->SetInteger(prefs::kMetricsSessionID, session_id_); |
| 971 |
| 972 // Stability bookkeeping |
| 973 IncrementPrefValue(prefs::kStabilityLaunchCount); |
| 974 |
| 942 DCHECK_EQ(UNINITIALIZED_PHASE, execution_phase_); | 975 DCHECK_EQ(UNINITIALIZED_PHASE, execution_phase_); |
| 943 SetExecutionPhase(START_METRICS_RECORDING); | 976 SetExecutionPhase(START_METRICS_RECORDING); |
| 944 | 977 |
| 945 #if defined(OS_WIN) | 978 #if defined(OS_WIN) |
| 946 CountBrowserCrashDumpAttempts(); | 979 CountBrowserCrashDumpAttempts(); |
| 947 #endif // defined(OS_WIN) | 980 #endif // defined(OS_WIN) |
| 948 | 981 |
| 949 if (!pref->GetBoolean(prefs::kStabilitySessionEndCompleted)) { | 982 if (!pref->GetBoolean(prefs::kStabilitySessionEndCompleted)) { |
| 950 IncrementPrefValue(prefs::kStabilityIncompleteSessionEndCount); | 983 IncrementPrefValue(prefs::kStabilityIncompleteSessionEndCount); |
| 951 // This is marked false when we get a WM_ENDSESSION. | 984 // This is marked false when we get a WM_ENDSESSION. |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1080 HandleIdleSinceLastTransmission(false); | 1113 HandleIdleSinceLastTransmission(false); |
| 1081 } | 1114 } |
| 1082 | 1115 |
| 1083 void MetricsService::ReceivedProfilerData( | 1116 void MetricsService::ReceivedProfilerData( |
| 1084 const tracked_objects::ProcessDataSnapshot& process_data, | 1117 const tracked_objects::ProcessDataSnapshot& process_data, |
| 1085 int process_type) { | 1118 int process_type) { |
| 1086 DCHECK_EQ(INIT_TASK_SCHEDULED, state_); | 1119 DCHECK_EQ(INIT_TASK_SCHEDULED, state_); |
| 1087 | 1120 |
| 1088 // Upon the first callback, create the initial log so that we can immediately | 1121 // Upon the first callback, create the initial log so that we can immediately |
| 1089 // save the profiler data. | 1122 // save the profiler data. |
| 1090 if (!initial_log_.get()) | 1123 if (!initial_metrics_log_.get()) |
| 1091 initial_log_.reset(new MetricsLog(client_id_, session_id_)); | 1124 initial_metrics_log_.reset(new MetricsLog(client_id_, session_id_)); |
| 1092 | 1125 |
| 1093 initial_log_->RecordProfilerData(process_data, process_type); | 1126 initial_metrics_log_->RecordProfilerData(process_data, process_type); |
| 1094 } | 1127 } |
| 1095 | 1128 |
| 1096 void MetricsService::FinishedReceivingProfilerData() { | 1129 void MetricsService::FinishedReceivingProfilerData() { |
| 1097 DCHECK_EQ(INIT_TASK_SCHEDULED, state_); | 1130 DCHECK_EQ(INIT_TASK_SCHEDULED, state_); |
| 1098 state_ = INIT_TASK_DONE; | 1131 state_ = INIT_TASK_DONE; |
| 1099 scheduler_->InitTaskComplete(); | 1132 scheduler_->InitTaskComplete(); |
| 1100 } | 1133 } |
| 1101 | 1134 |
| 1102 base::TimeDelta MetricsService::GetIncrementalUptime(PrefService* pref) { | 1135 base::TimeDelta MetricsService::GetIncrementalUptime(PrefService* pref) { |
| 1103 base::TimeTicks now = base::TimeTicks::Now(); | 1136 base::TimeTicks now = base::TimeTicks::Now(); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1240 PrefService* pref = g_browser_process->local_state(); | 1273 PrefService* pref = g_browser_process->local_state(); |
| 1241 current_log->RecordStabilityMetrics(GetIncrementalUptime(pref), | 1274 current_log->RecordStabilityMetrics(GetIncrementalUptime(pref), |
| 1242 MetricsLog::ONGOING_LOG); | 1275 MetricsLog::ONGOING_LOG); |
| 1243 | 1276 |
| 1244 RecordCurrentHistograms(); | 1277 RecordCurrentHistograms(); |
| 1245 | 1278 |
| 1246 log_manager_.FinishCurrentLog(); | 1279 log_manager_.FinishCurrentLog(); |
| 1247 } | 1280 } |
| 1248 | 1281 |
| 1249 void MetricsService::PushPendingLogsToPersistentStorage() { | 1282 void MetricsService::PushPendingLogsToPersistentStorage() { |
| 1250 if (state_ < INITIAL_LOG_READY) | 1283 if (state_ < SENDING_INITIAL_STABILITY_LOG) |
| 1251 return; // We didn't and still don't have time to get plugin list etc. | 1284 return; // We didn't and still don't have time to get plugin list etc. |
| 1252 | 1285 |
| 1253 if (log_manager_.has_staged_log()) { | 1286 if (log_manager_.has_staged_log()) { |
| 1254 // We may race here, and send second copy of the log later. | 1287 // We may race here, and send second copy of the log later. |
| 1255 MetricsLogManager::StoreType store_type; | 1288 MetricsLogManager::StoreType store_type; |
| 1256 if (current_fetch_.get()) | 1289 if (current_fetch_.get()) |
| 1257 store_type = MetricsLogManager::PROVISIONAL_STORE; | 1290 store_type = MetricsLogManager::PROVISIONAL_STORE; |
| 1258 else | 1291 else |
| 1259 store_type = MetricsLogManager::NORMAL_STORE; | 1292 store_type = MetricsLogManager::NORMAL_STORE; |
| 1260 log_manager_.StoreStagedLogAsUnsent(store_type); | 1293 log_manager_.StoreStagedLogAsUnsent(store_type); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1273 // Transmission of logs methods | 1306 // Transmission of logs methods |
| 1274 | 1307 |
| 1275 void MetricsService::StartSchedulerIfNecessary() { | 1308 void MetricsService::StartSchedulerIfNecessary() { |
| 1276 // Never schedule cutting or uploading of logs in test mode. | 1309 // Never schedule cutting or uploading of logs in test mode. |
| 1277 if (test_mode_active_) | 1310 if (test_mode_active_) |
| 1278 return; | 1311 return; |
| 1279 | 1312 |
| 1280 // Even if reporting is disabled, the scheduler is needed to trigger the | 1313 // Even if reporting is disabled, the scheduler is needed to trigger the |
| 1281 // creation of the initial log, which must be done in order for any logs to be | 1314 // creation of the initial log, which must be done in order for any logs to be |
| 1282 // persisted on shutdown or backgrounding. | 1315 // persisted on shutdown or backgrounding. |
| 1283 if (recording_active() && (reporting_active() || state_ < INITIAL_LOG_READY)) | 1316 if (recording_active() && |
| 1317 (reporting_active() || state_ < SENDING_INITIAL_STABILITY_LOG)) { |
| 1284 scheduler_->Start(); | 1318 scheduler_->Start(); |
| 1319 } |
| 1285 } | 1320 } |
| 1286 | 1321 |
| 1287 void MetricsService::StartScheduledUpload() { | 1322 void MetricsService::StartScheduledUpload() { |
| 1288 // If we're getting no notifications, then the log won't have much in it, and | 1323 // If we're getting no notifications, then the log won't have much in it, and |
| 1289 // it's possible the computer is about to go to sleep, so don't upload and | 1324 // it's possible the computer is about to go to sleep, so don't upload and |
| 1290 // stop the scheduler. | 1325 // stop the scheduler. |
| 1291 // If recording has been turned off, the scheduler doesn't need to run. | 1326 // If recording has been turned off, the scheduler doesn't need to run. |
| 1292 // If reporting is off, proceed if the initial log hasn't been created, since | 1327 // If reporting is off, proceed if the initial log hasn't been created, since |
| 1293 // that has to happen in order for logs to be cut and stored when persisting. | 1328 // that has to happen in order for logs to be cut and stored when persisting. |
| 1294 // TODO(stuartmorgan): Call Stop() on the schedule when reporting and/or | 1329 // TODO(stuartmorgan): Call Stop() on the schedule when reporting and/or |
| 1295 // recording are turned off instead of letting it fire and then aborting. | 1330 // recording are turned off instead of letting it fire and then aborting. |
| 1296 if (idle_since_last_transmission_ || | 1331 if (idle_since_last_transmission_ || |
| 1297 !recording_active() || | 1332 !recording_active() || |
| 1298 (!reporting_active() && state_ >= INITIAL_LOG_READY)) { | 1333 (!reporting_active() && state_ >= SENDING_INITIAL_STABILITY_LOG)) { |
| 1299 scheduler_->Stop(); | 1334 scheduler_->Stop(); |
| 1300 scheduler_->UploadCancelled(); | 1335 scheduler_->UploadCancelled(); |
| 1301 return; | 1336 return; |
| 1302 } | 1337 } |
| 1303 | 1338 |
| 1304 // If the callback was to upload an old log, but there no longer is one, | 1339 // If the callback was to upload an old log, but there no longer is one, |
| 1305 // just report success back to the scheduler to begin the ongoing log | 1340 // just report success back to the scheduler to begin the ongoing log |
| 1306 // callbacks. | 1341 // callbacks. |
| 1307 // TODO(stuartmorgan): Consider removing the distinction between | 1342 // TODO(stuartmorgan): Consider removing the distinction between |
| 1308 // SENDING_OLD_LOGS and SENDING_CURRENT_LOGS to simplify the state machine | 1343 // SENDING_OLD_LOGS and SENDING_CURRENT_LOGS to simplify the state machine |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1427 if (!reporting_active()) { | 1462 if (!reporting_active()) { |
| 1428 scheduler_->Stop(); | 1463 scheduler_->Stop(); |
| 1429 scheduler_->UploadCancelled(); | 1464 scheduler_->UploadCancelled(); |
| 1430 return; | 1465 return; |
| 1431 } | 1466 } |
| 1432 | 1467 |
| 1433 SendStagedLog(); | 1468 SendStagedLog(); |
| 1434 } | 1469 } |
| 1435 | 1470 |
| 1436 void MetricsService::StageNewLog() { | 1471 void MetricsService::StageNewLog() { |
| 1437 if (log_manager_.has_staged_log()) | 1472 if (state_ != INIT_TASK_DONE && log_manager_.has_staged_log()) |
| 1438 return; | 1473 return; |
| 1439 | 1474 |
| 1440 switch (state_) { | 1475 switch (state_) { |
| 1441 case INITIALIZED: | 1476 case INITIALIZED: |
| 1442 case INIT_TASK_SCHEDULED: // We should be further along by now. | 1477 case INIT_TASK_SCHEDULED: // We should be further along by now. |
| 1443 NOTREACHED(); | 1478 NOTREACHED(); |
| 1444 return; | 1479 return; |
| 1445 | 1480 |
| 1446 case INIT_TASK_DONE: | 1481 case INIT_TASK_DONE: |
| 1447 PrepareInitialLog(); | 1482 if (log_manager_.has_staged_log()) { |
| 1448 DCHECK_EQ(INIT_TASK_DONE, state_); | 1483 // There's an initial stability log, ready to send. |
| 1449 log_manager_.LoadPersistedUnsentLogs(); | 1484 state_ = SENDING_INITIAL_STABILITY_LOG; |
| 1450 state_ = INITIAL_LOG_READY; | 1485 } else { |
| 1486 // TODO(asvitkine): When the field trial is removed, the |log_type| |
| 1487 // arg should be removed and PrepareInitialMetricsLog() should always |
| 1488 // use ONGOING_LOG. Use INITIAL_LOG only to match to the old behavior |
| 1489 // when the field trial is off. |
| 1490 MetricsLog::LogType log_type = SendSeparateInitialStabilityLog() ? |
| 1491 MetricsLog::ONGOING_LOG : MetricsLog::INITIAL_LOG; |
| 1492 PrepareInitialMetricsLog(log_type); |
| 1493 state_ = SENDING_INITIAL_METRICS_LOG; |
| 1494 } |
| 1451 break; | 1495 break; |
| 1452 | 1496 |
| 1453 case SENDING_OLD_LOGS: | 1497 case SENDING_OLD_LOGS: |
| 1454 NOTREACHED(); // Shouldn't be staging a new log during old log sending. | 1498 NOTREACHED(); // Shouldn't be staging a new log during old log sending. |
| 1455 return; | 1499 return; |
| 1456 | 1500 |
| 1457 case SENDING_CURRENT_LOGS: | 1501 case SENDING_CURRENT_LOGS: |
| 1458 CloseCurrentLog(); | 1502 CloseCurrentLog(); |
| 1459 OpenNewLog(); | 1503 OpenNewLog(); |
| 1460 log_manager_.StageNextLogForUpload(); | 1504 log_manager_.StageNextLogForUpload(); |
| 1461 break; | 1505 break; |
| 1462 | 1506 |
| 1463 default: | 1507 default: |
| 1464 NOTREACHED(); | 1508 NOTREACHED(); |
| 1465 return; | 1509 return; |
| 1466 } | 1510 } |
| 1467 | 1511 |
| 1468 DCHECK(log_manager_.has_staged_log()); | 1512 DCHECK(log_manager_.has_staged_log()); |
| 1469 } | 1513 } |
| 1470 | 1514 |
| 1471 void MetricsService::PrepareInitialLog() { | 1515 void MetricsService::PrepareInitialStabilityLog() { |
| 1472 DCHECK_EQ(INIT_TASK_DONE, state_); | 1516 DCHECK_EQ(INITIALIZED, state_); |
| 1473 | 1517 |
| 1474 DCHECK(initial_log_.get()); | 1518 scoped_ptr<MetricsLog> initial_stability_log( |
| 1475 initial_log_->set_hardware_class(hardware_class_); | 1519 new MetricsLog(client_id_, session_id_)); |
| 1520 if (!initial_stability_log->LoadSavedEnvironmentFromPrefs()) |
| 1521 return; |
| 1522 initial_stability_log->RecordStabilityMetrics(base::TimeDelta(), |
| 1523 MetricsLog::INITIAL_LOG); |
| 1524 |
| 1525 log_manager_.PauseCurrentLog(); |
| 1526 log_manager_.BeginLoggingWithLog(initial_stability_log.release(), |
| 1527 MetricsLog::INITIAL_LOG); |
| 1528 log_manager_.FinishCurrentLog(); |
| 1529 log_manager_.ResumePausedLog(); |
| 1530 // TODO(asvitkine): It would be nice to defer StageNextLogForUpload() until |
| 1531 // the log is ready to be actually sent. This way, the initial stability log |
| 1532 // can be kept around in unsent logs (and saved to prefs) in case there's a |
| 1533 // crash. However, this would require loading existing unsent logs earlier - |
| 1534 // which is currently done in PrepareInitialMetricsLog(). |
| 1535 log_manager_.StageNextLogForUpload(); |
| 1536 } |
| 1537 |
| 1538 void MetricsService::PrepareInitialMetricsLog(MetricsLog::LogType log_type) { |
| 1539 DCHECK(state_ == INIT_TASK_DONE || state_ == SENDING_INITIAL_STABILITY_LOG); |
| 1540 initial_metrics_log_->set_hardware_class(hardware_class_); |
| 1476 | 1541 |
| 1477 std::vector<chrome_variations::ActiveGroupId> synthetic_trials; | 1542 std::vector<chrome_variations::ActiveGroupId> synthetic_trials; |
| 1478 GetCurrentSyntheticFieldTrials(&synthetic_trials); | 1543 GetCurrentSyntheticFieldTrials(&synthetic_trials); |
| 1479 initial_log_->RecordEnvironment(plugins_, google_update_metrics_, | 1544 initial_metrics_log_->RecordEnvironment(plugins_, google_update_metrics_, |
| 1480 synthetic_trials); | 1545 synthetic_trials); |
| 1481 PrefService* pref = g_browser_process->local_state(); | 1546 PrefService* pref = g_browser_process->local_state(); |
| 1482 initial_log_->RecordStabilityMetrics(GetIncrementalUptime(pref), | 1547 initial_metrics_log_->RecordStabilityMetrics(GetIncrementalUptime(pref), |
| 1483 MetricsLog::INITIAL_LOG); | 1548 log_type); |
| 1484 | 1549 |
| 1485 // Histograms only get written to the current log, so make the new log current | 1550 // Histograms only get written to the current log, so make the new log current |
| 1486 // before writing them. | 1551 // before writing them. |
| 1487 log_manager_.PauseCurrentLog(); | 1552 log_manager_.PauseCurrentLog(); |
| 1488 log_manager_.BeginLoggingWithLog(initial_log_.release(), | 1553 log_manager_.BeginLoggingWithLog(initial_metrics_log_.release(), log_type); |
| 1489 MetricsLog::INITIAL_LOG); | |
| 1490 RecordCurrentHistograms(); | 1554 RecordCurrentHistograms(); |
| 1491 log_manager_.FinishCurrentLog(); | 1555 log_manager_.FinishCurrentLog(); |
| 1492 log_manager_.ResumePausedLog(); | 1556 log_manager_.ResumePausedLog(); |
| 1493 | 1557 |
| 1494 DCHECK(!log_manager_.has_staged_log()); | 1558 DCHECK(!log_manager_.has_staged_log()); |
| 1495 log_manager_.StageNextLogForUpload(); | 1559 log_manager_.StageNextLogForUpload(); |
| 1560 log_manager_.LoadPersistedUnsentLogs(); |
| 1496 } | 1561 } |
| 1497 | 1562 |
| 1498 void MetricsService::StoreUnsentLogs() { | 1563 void MetricsService::StoreUnsentLogs() { |
| 1499 if (state_ < INITIAL_LOG_READY) | 1564 if (state_ < SENDING_INITIAL_STABILITY_LOG) |
| 1500 return; // We never Recalled the prior unsent logs. | 1565 return; // We never Recalled the prior unsent logs. |
| 1501 | 1566 |
| 1502 log_manager_.PersistUnsentLogs(); | 1567 log_manager_.PersistUnsentLogs(); |
| 1503 } | 1568 } |
| 1504 | 1569 |
| 1505 void MetricsService::SendStagedLog() { | 1570 void MetricsService::SendStagedLog() { |
| 1506 DCHECK(log_manager_.has_staged_log()); | 1571 DCHECK(log_manager_.has_staged_log()); |
| 1507 | 1572 |
| 1508 PrepareFetchWithStagedLog(); | 1573 PrepareFetchWithStagedLog(); |
| 1509 | 1574 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1600 discard_log = true; | 1665 discard_log = true; |
| 1601 } | 1666 } |
| 1602 | 1667 |
| 1603 if (upload_succeeded || discard_log) | 1668 if (upload_succeeded || discard_log) |
| 1604 log_manager_.DiscardStagedLog(); | 1669 log_manager_.DiscardStagedLog(); |
| 1605 | 1670 |
| 1606 waiting_for_asynchronous_reporting_step_ = false; | 1671 waiting_for_asynchronous_reporting_step_ = false; |
| 1607 | 1672 |
| 1608 if (!log_manager_.has_staged_log()) { | 1673 if (!log_manager_.has_staged_log()) { |
| 1609 switch (state_) { | 1674 switch (state_) { |
| 1610 case INITIAL_LOG_READY: | 1675 case SENDING_INITIAL_STABILITY_LOG: |
| 1676 PrepareInitialMetricsLog(MetricsLog::ONGOING_LOG); |
| 1677 SendStagedLog(); |
| 1678 state_ = SENDING_INITIAL_METRICS_LOG; |
| 1679 break; |
| 1680 |
| 1681 case SENDING_INITIAL_METRICS_LOG: |
| 1611 state_ = log_manager_.has_unsent_logs() ? SENDING_OLD_LOGS | 1682 state_ = log_manager_.has_unsent_logs() ? SENDING_OLD_LOGS |
| 1612 : SENDING_CURRENT_LOGS; | 1683 : SENDING_CURRENT_LOGS; |
| 1613 break; | 1684 break; |
| 1614 | 1685 |
| 1615 case SENDING_OLD_LOGS: | 1686 case SENDING_OLD_LOGS: |
| 1616 // Store the updated list to disk now that the removed log is uploaded. | 1687 // Store the updated list to disk now that the removed log is uploaded. |
| 1617 StoreUnsentLogs(); | 1688 StoreUnsentLogs(); |
| 1618 if (!log_manager_.has_unsent_logs()) | 1689 if (!log_manager_.has_unsent_logs()) |
| 1619 state_ = SENDING_CURRENT_LOGS; | 1690 state_ = SENDING_CURRENT_LOGS; |
| 1620 break; | 1691 break; |
| 1621 | 1692 |
| 1622 case SENDING_CURRENT_LOGS: | 1693 case SENDING_CURRENT_LOGS: |
| 1623 break; | 1694 break; |
| 1624 | 1695 |
| 1625 default: | 1696 default: |
| 1626 NOTREACHED(); | 1697 NOTREACHED(); |
| 1627 break; | 1698 break; |
| 1628 } | 1699 } |
| 1629 | 1700 |
| 1630 if (log_manager_.has_unsent_logs()) | 1701 if (log_manager_.has_unsent_logs()) |
| 1631 DCHECK_LT(state_, SENDING_CURRENT_LOGS); | 1702 DCHECK_LT(state_, SENDING_CURRENT_LOGS); |
| 1632 } | 1703 } |
| 1633 | 1704 |
| 1634 // Error 400 indicates a problem with the log, not with the server, so | 1705 // Error 400 indicates a problem with the log, not with the server, so |
| 1635 // don't consider that a sign that the server is in trouble. | 1706 // don't consider that a sign that the server is in trouble. |
| 1636 bool server_is_healthy = upload_succeeded || response_code == 400; | 1707 bool server_is_healthy = upload_succeeded || response_code == 400; |
| 1637 scheduler_->UploadFinished(server_is_healthy, log_manager_.has_unsent_logs()); | 1708 // Don't notify the scheduler that the upload is finished if we've only sent |
| 1709 // the initial stability log, but not yet the initial metrics log (treat the |
| 1710 // two as a single unit of work as far as the scheduler is concerned). |
| 1711 if (state_ != SENDING_INITIAL_METRICS_LOG) { |
| 1712 scheduler_->UploadFinished(server_is_healthy, |
| 1713 log_manager_.has_unsent_logs()); |
| 1714 } |
| 1638 | 1715 |
| 1639 // Collect network stats if UMA upload succeeded. | 1716 // Collect network stats if UMA upload succeeded. |
| 1640 IOThread* io_thread = g_browser_process->io_thread(); | 1717 IOThread* io_thread = g_browser_process->io_thread(); |
| 1641 if (server_is_healthy && io_thread) { | 1718 if (server_is_healthy && io_thread) { |
| 1642 chrome_browser_net::CollectNetworkStats(network_stats_server_, io_thread); | 1719 chrome_browser_net::CollectNetworkStats(network_stats_server_, io_thread); |
| 1643 chrome_browser_net::CollectPipeliningCapabilityStatsOnUIThread( | 1720 chrome_browser_net::CollectPipeliningCapabilityStatsOnUIThread( |
| 1644 http_pipelining_test_server_, io_thread); | 1721 http_pipelining_test_server_, io_thread); |
| 1645 #if defined(OS_WIN) | 1722 #if defined(OS_WIN) |
| 1646 chrome::CollectTimeTicksStats(); | 1723 chrome::CollectTimeTicksStats(); |
| 1647 #endif | 1724 #endif |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1693 } | 1770 } |
| 1694 | 1771 |
| 1695 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildCrashes", | 1772 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildCrashes", |
| 1696 was_extension_process ? 2 : 1); | 1773 was_extension_process ? 2 : 1); |
| 1697 } else if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED) { | 1774 } else if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED) { |
| 1698 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildKills", | 1775 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildKills", |
| 1699 was_extension_process ? 2 : 1); | 1776 was_extension_process ? 2 : 1); |
| 1700 } else if (status == base::TERMINATION_STATUS_STILL_RUNNING) { | 1777 } else if (status == base::TERMINATION_STATUS_STILL_RUNNING) { |
| 1701 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.DisconnectedAlive", | 1778 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.DisconnectedAlive", |
| 1702 was_extension_process ? 2 : 1); | 1779 was_extension_process ? 2 : 1); |
| 1703 } | |
| 1704 } | 1780 } |
| 1781 } |
| 1705 | 1782 |
| 1706 void MetricsService::LogRendererHang() { | 1783 void MetricsService::LogRendererHang() { |
| 1707 IncrementPrefValue(prefs::kStabilityRendererHangCount); | 1784 IncrementPrefValue(prefs::kStabilityRendererHangCount); |
| 1708 } | 1785 } |
| 1709 | 1786 |
| 1710 bool MetricsService::UmaMetricsProperlyShutdown() { | 1787 bool MetricsService::UmaMetricsProperlyShutdown() { |
| 1711 CHECK(clean_shutdown_status_ == CLEANLY_SHUTDOWN || | 1788 CHECK(clean_shutdown_status_ == CLEANLY_SHUTDOWN || |
| 1712 clean_shutdown_status_ == NEED_TO_SHUTDOWN); | 1789 clean_shutdown_status_ == NEED_TO_SHUTDOWN); |
| 1713 return clean_shutdown_status_ == CLEANLY_SHUTDOWN; | 1790 return clean_shutdown_status_ == CLEANLY_SHUTDOWN; |
| 1714 } | 1791 } |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1932 if (local_state) { | 2009 if (local_state) { |
| 1933 const PrefService::Preference* uma_pref = | 2010 const PrefService::Preference* uma_pref = |
| 1934 local_state->FindPreference(prefs::kMetricsReportingEnabled); | 2011 local_state->FindPreference(prefs::kMetricsReportingEnabled); |
| 1935 if (uma_pref) { | 2012 if (uma_pref) { |
| 1936 bool success = uma_pref->GetValue()->GetAsBoolean(&result); | 2013 bool success = uma_pref->GetValue()->GetAsBoolean(&result); |
| 1937 DCHECK(success); | 2014 DCHECK(success); |
| 1938 } | 2015 } |
| 1939 } | 2016 } |
| 1940 return result; | 2017 return result; |
| 1941 } | 2018 } |
| OLD | NEW |