| 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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 | 512 |
| 495 local_state->ClearPref(prefs::kMetricsInitialLogs); | 513 local_state->ClearPref(prefs::kMetricsInitialLogs); |
| 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), |
| 522 has_initial_stability_log_(false), |
| 504 low_entropy_source_(kLowEntropySourceNotSet), | 523 low_entropy_source_(kLowEntropySourceNotSet), |
| 505 idle_since_last_transmission_(false), | 524 idle_since_last_transmission_(false), |
| 525 session_id_(-1), |
| 506 next_window_id_(0), | 526 next_window_id_(0), |
| 507 self_ptr_factory_(this), | 527 self_ptr_factory_(this), |
| 508 state_saver_factory_(this), | 528 state_saver_factory_(this), |
| 509 waiting_for_asynchronous_reporting_step_(false), | 529 waiting_for_asynchronous_reporting_step_(false), |
| 510 num_async_histogram_fetches_in_progress_(0), | 530 num_async_histogram_fetches_in_progress_(0), |
| 511 entropy_source_returned_(LAST_ENTROPY_NONE) { | 531 entropy_source_returned_(LAST_ENTROPY_NONE) { |
| 512 DCHECK(IsSingleThreaded()); | 532 DCHECK(IsSingleThreaded()); |
| 513 InitializeMetricsState(); | |
| 514 | 533 |
| 515 base::Closure callback = base::Bind(&MetricsService::StartScheduledUpload, | 534 log_manager_.set_log_serializer(new MetricsLogSerializer); |
| 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); | 535 log_manager_.set_max_ongoing_log_store_size(kUploadLogAvoidRetransmitSize); |
| 520 | 536 |
| 521 BrowserChildProcessObserver::Add(this); | 537 BrowserChildProcessObserver::Add(this); |
| 522 } | 538 } |
| 523 | 539 |
| 524 MetricsService::~MetricsService() { | 540 MetricsService::~MetricsService() { |
| 525 DisableRecording(); | 541 DisableRecording(); |
| 526 | 542 |
| 527 BrowserChildProcessObserver::Remove(this); | 543 BrowserChildProcessObserver::Remove(this); |
| 528 } | 544 } |
| 529 | 545 |
| 546 void MetricsService::InitializeMetricsRecordingState( |
| 547 ReportingState reporting_state) { |
| 548 InitializeMetricsState(reporting_state); |
| 549 |
| 550 base::Closure callback = base::Bind(&MetricsService::StartScheduledUpload, |
| 551 self_ptr_factory_.GetWeakPtr()); |
| 552 scheduler_.reset(new MetricsReportingScheduler(callback)); |
| 553 } |
| 554 |
| 530 void MetricsService::Start() { | 555 void MetricsService::Start() { |
| 531 HandleIdleSinceLastTransmission(false); | 556 HandleIdleSinceLastTransmission(false); |
| 532 EnableRecording(); | 557 EnableRecording(); |
| 533 EnableReporting(); | 558 EnableReporting(); |
| 534 } | 559 } |
| 535 | 560 |
| 536 void MetricsService::StartRecordingForTests() { | 561 void MetricsService::StartRecordingForTests() { |
| 537 test_mode_active_ = true; | 562 test_mode_active_ = true; |
| 538 EnableRecording(); | 563 EnableRecording(); |
| 539 DisableReporting(); | 564 DisableReporting(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 554 | 579 |
| 555 void MetricsService::DisableReporting() { | 580 void MetricsService::DisableReporting() { |
| 556 reporting_active_ = false; | 581 reporting_active_ = false; |
| 557 } | 582 } |
| 558 | 583 |
| 559 std::string MetricsService::GetClientId() { | 584 std::string MetricsService::GetClientId() { |
| 560 return client_id_; | 585 return client_id_; |
| 561 } | 586 } |
| 562 | 587 |
| 563 scoped_ptr<const base::FieldTrial::EntropyProvider> | 588 scoped_ptr<const base::FieldTrial::EntropyProvider> |
| 564 MetricsService::CreateEntropyProvider(bool reporting_will_be_enabled) { | 589 MetricsService::CreateEntropyProvider(ReportingState reporting_state) { |
| 565 // For metrics reporting-enabled users, we combine the client ID and low | 590 // 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 | 591 // entropy source to get the final entropy source. Otherwise, only use the low |
| 567 // entropy source. | 592 // entropy source. |
| 568 // This has two useful properties: | 593 // This has two useful properties: |
| 569 // 1) It makes the entropy source less identifiable for parties that do not | 594 // 1) It makes the entropy source less identifiable for parties that do not |
| 570 // know the low entropy source. | 595 // know the low entropy source. |
| 571 // 2) It makes the final entropy source resettable. | 596 // 2) It makes the final entropy source resettable. |
| 572 const int low_entropy_source_value = GetLowEntropySource(); | 597 const int low_entropy_source_value = GetLowEntropySource(); |
| 573 UMA_HISTOGRAM_SPARSE_SLOWLY("UMA.LowEntropySourceValue", | 598 UMA_HISTOGRAM_SPARSE_SLOWLY("UMA.LowEntropySourceValue", |
| 574 low_entropy_source_value); | 599 low_entropy_source_value); |
| 575 if (reporting_will_be_enabled) { | 600 if (reporting_state == REPORTING_ENABLED) { |
| 576 if (entropy_source_returned_ == LAST_ENTROPY_NONE) | 601 if (entropy_source_returned_ == LAST_ENTROPY_NONE) |
| 577 entropy_source_returned_ = LAST_ENTROPY_HIGH; | 602 entropy_source_returned_ = LAST_ENTROPY_HIGH; |
| 578 DCHECK_EQ(LAST_ENTROPY_HIGH, entropy_source_returned_); | 603 DCHECK_EQ(LAST_ENTROPY_HIGH, entropy_source_returned_); |
| 579 const std::string high_entropy_source = | 604 const std::string high_entropy_source = |
| 580 client_id_ + base::IntToString(low_entropy_source_value); | 605 client_id_ + base::IntToString(low_entropy_source_value); |
| 581 return scoped_ptr<const base::FieldTrial::EntropyProvider>( | 606 return scoped_ptr<const base::FieldTrial::EntropyProvider>( |
| 582 new metrics::SHA1EntropyProvider(high_entropy_source)); | 607 new metrics::SHA1EntropyProvider(high_entropy_source)); |
| 583 } | 608 } |
| 584 | 609 |
| 585 if (entropy_source_returned_ == LAST_ENTROPY_NONE) | 610 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) | 806 #if defined(OS_ANDROID) || defined(OS_IOS) |
| 782 void MetricsService::OnAppEnterBackground() { | 807 void MetricsService::OnAppEnterBackground() { |
| 783 scheduler_->Stop(); | 808 scheduler_->Stop(); |
| 784 | 809 |
| 785 MarkAppCleanShutdownAndCommit(); | 810 MarkAppCleanShutdownAndCommit(); |
| 786 | 811 |
| 787 // At this point, there's no way of knowing when the process will be | 812 // 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 | 813 // 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 | 814 // persisting all logs. Unlinke a shutdown, the state is primed to be ready |
| 790 // to continue logging and uploading if the process does return. | 815 // to continue logging and uploading if the process does return. |
| 791 if (recording_active() && state_ >= INITIAL_LOG_READY) { | 816 if (recording_active() && state_ >= SENDING_INITIAL_STABILITY_LOG) { |
| 792 PushPendingLogsToPersistentStorage(); | 817 PushPendingLogsToPersistentStorage(); |
| 793 // Persisting logs closes the current log, so start recording a new log | 818 // 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 | 819 // immediately to capture any background work that might be done before the |
| 795 // process is killed. | 820 // process is killed. |
| 796 OpenNewLog(); | 821 OpenNewLog(); |
| 797 } | 822 } |
| 798 } | 823 } |
| 799 | 824 |
| 800 void MetricsService::OnAppEnterForeground() { | 825 void MetricsService::OnAppEnterForeground() { |
| 801 PrefService* pref = g_browser_process->local_state(); | 826 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) | 911 #endif // defined(OS_WIN) |
| 887 | 912 |
| 888 //------------------------------------------------------------------------------ | 913 //------------------------------------------------------------------------------ |
| 889 // private methods | 914 // private methods |
| 890 //------------------------------------------------------------------------------ | 915 //------------------------------------------------------------------------------ |
| 891 | 916 |
| 892 | 917 |
| 893 //------------------------------------------------------------------------------ | 918 //------------------------------------------------------------------------------ |
| 894 // Initialization methods | 919 // Initialization methods |
| 895 | 920 |
| 896 void MetricsService::InitializeMetricsState() { | 921 void MetricsService::InitializeMetricsState(ReportingState reporting_state) { |
| 897 #if defined(OS_POSIX) | 922 #if defined(OS_POSIX) |
| 898 network_stats_server_ = chrome_common_net::kEchoTestServerLocation; | 923 network_stats_server_ = chrome_common_net::kEchoTestServerLocation; |
| 899 http_pipelining_test_server_ = chrome_common_net::kPipelineTestServerBaseUrl; | 924 http_pipelining_test_server_ = chrome_common_net::kPipelineTestServerBaseUrl; |
| 900 #else | 925 #else |
| 901 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); | 926 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| 902 network_stats_server_ = dist->GetNetworkStatsServer(); | 927 network_stats_server_ = dist->GetNetworkStatsServer(); |
| 903 http_pipelining_test_server_ = dist->GetHttpPipeliningTestServer(); | 928 http_pipelining_test_server_ = dist->GetHttpPipeliningTestServer(); |
| 904 #endif | 929 #endif |
| 905 | 930 |
| 906 PrefService* pref = g_browser_process->local_state(); | 931 PrefService* pref = g_browser_process->local_state(); |
| 907 DCHECK(pref); | 932 DCHECK(pref); |
| 908 | 933 |
| 934 // TODO(asvitkine): Kill this logic when SendSeparateInitialStabilityLog() is |
| 935 // is made the default behavior. |
| 909 if ((pref->GetInt64(prefs::kStabilityStatsBuildTime) | 936 if ((pref->GetInt64(prefs::kStabilityStatsBuildTime) |
| 910 != MetricsLog::GetBuildTime()) || | 937 != MetricsLog::GetBuildTime()) || |
| 911 (pref->GetString(prefs::kStabilityStatsVersion) | 938 (pref->GetString(prefs::kStabilityStatsVersion) |
| 912 != MetricsLog::GetVersionString())) { | 939 != MetricsLog::GetVersionString())) { |
| 913 // This is a new version, so we don't want to confuse the stats about the | 940 // This is a new version, so we don't want to confuse the stats about the |
| 914 // old version with info that we upload. | 941 // old version with info that we upload. |
| 915 DiscardOldStabilityStats(pref); | 942 DiscardOldStabilityStats(pref); |
| 916 pref->SetString(prefs::kStabilityStatsVersion, | 943 pref->SetString(prefs::kStabilityStatsVersion, |
| 917 MetricsLog::GetVersionString()); | 944 MetricsLog::GetVersionString()); |
| 918 pref->SetInt64(prefs::kStabilityStatsBuildTime, | 945 pref->SetInt64(prefs::kStabilityStatsBuildTime, |
| 919 MetricsLog::GetBuildTime()); | 946 MetricsLog::GetBuildTime()); |
| 920 } | 947 } |
| 921 | 948 |
| 922 // Update session ID | |
| 923 session_id_ = pref->GetInteger(prefs::kMetricsSessionID); | 949 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 | 950 |
| 930 if (!pref->GetBoolean(prefs::kStabilityExitedCleanly)) { | 951 if (!pref->GetBoolean(prefs::kStabilityExitedCleanly)) { |
| 931 IncrementPrefValue(prefs::kStabilityCrashCount); | 952 IncrementPrefValue(prefs::kStabilityCrashCount); |
| 932 // Reset flag, and wait until we call LogNeedForCleanShutdown() before | 953 // Reset flag, and wait until we call LogNeedForCleanShutdown() before |
| 933 // monitoring. | 954 // monitoring. |
| 934 pref->SetBoolean(prefs::kStabilityExitedCleanly, true); | 955 pref->SetBoolean(prefs::kStabilityExitedCleanly, true); |
| 935 | 956 |
| 936 // TODO(rtenneti): On windows, consider saving/getting execution_phase from | 957 // TODO(rtenneti): On windows, consider saving/getting execution_phase from |
| 937 // the registry. | 958 // the registry. |
| 938 int execution_phase = pref->GetInteger(prefs::kStabilityExecutionPhase); | 959 int execution_phase = pref->GetInteger(prefs::kStabilityExecutionPhase); |
| 939 UMA_HISTOGRAM_SPARSE_SLOWLY("Chrome.Browser.CrashedExecutionPhase", | 960 UMA_HISTOGRAM_SPARSE_SLOWLY("Chrome.Browser.CrashedExecutionPhase", |
| 940 execution_phase); | 961 execution_phase); |
| 962 |
| 963 // If the previous session didn't exit cleanly, then prepare an initial |
| 964 // stability log if UMA is enabled. |
| 965 bool reporting_will_be_enabled = (reporting_state == REPORTING_ENABLED); |
| 966 if (reporting_will_be_enabled && SendSeparateInitialStabilityLog()) |
| 967 PrepareInitialStabilityLog(); |
| 941 } | 968 } |
| 969 |
| 970 // Update session ID. |
| 971 ++session_id_; |
| 972 pref->SetInteger(prefs::kMetricsSessionID, session_id_); |
| 973 |
| 974 // Stability bookkeeping |
| 975 IncrementPrefValue(prefs::kStabilityLaunchCount); |
| 976 |
| 942 DCHECK_EQ(UNINITIALIZED_PHASE, execution_phase_); | 977 DCHECK_EQ(UNINITIALIZED_PHASE, execution_phase_); |
| 943 SetExecutionPhase(START_METRICS_RECORDING); | 978 SetExecutionPhase(START_METRICS_RECORDING); |
| 944 | 979 |
| 945 #if defined(OS_WIN) | 980 #if defined(OS_WIN) |
| 946 CountBrowserCrashDumpAttempts(); | 981 CountBrowserCrashDumpAttempts(); |
| 947 #endif // defined(OS_WIN) | 982 #endif // defined(OS_WIN) |
| 948 | 983 |
| 949 if (!pref->GetBoolean(prefs::kStabilitySessionEndCompleted)) { | 984 if (!pref->GetBoolean(prefs::kStabilitySessionEndCompleted)) { |
| 950 IncrementPrefValue(prefs::kStabilityIncompleteSessionEndCount); | 985 IncrementPrefValue(prefs::kStabilityIncompleteSessionEndCount); |
| 951 // This is marked false when we get a WM_ENDSESSION. | 986 // 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); | 1115 HandleIdleSinceLastTransmission(false); |
| 1081 } | 1116 } |
| 1082 | 1117 |
| 1083 void MetricsService::ReceivedProfilerData( | 1118 void MetricsService::ReceivedProfilerData( |
| 1084 const tracked_objects::ProcessDataSnapshot& process_data, | 1119 const tracked_objects::ProcessDataSnapshot& process_data, |
| 1085 int process_type) { | 1120 int process_type) { |
| 1086 DCHECK_EQ(INIT_TASK_SCHEDULED, state_); | 1121 DCHECK_EQ(INIT_TASK_SCHEDULED, state_); |
| 1087 | 1122 |
| 1088 // Upon the first callback, create the initial log so that we can immediately | 1123 // Upon the first callback, create the initial log so that we can immediately |
| 1089 // save the profiler data. | 1124 // save the profiler data. |
| 1090 if (!initial_log_.get()) | 1125 if (!initial_metrics_log_.get()) |
| 1091 initial_log_.reset(new MetricsLog(client_id_, session_id_)); | 1126 initial_metrics_log_.reset(new MetricsLog(client_id_, session_id_)); |
| 1092 | 1127 |
| 1093 initial_log_->RecordProfilerData(process_data, process_type); | 1128 initial_metrics_log_->RecordProfilerData(process_data, process_type); |
| 1094 } | 1129 } |
| 1095 | 1130 |
| 1096 void MetricsService::FinishedReceivingProfilerData() { | 1131 void MetricsService::FinishedReceivingProfilerData() { |
| 1097 DCHECK_EQ(INIT_TASK_SCHEDULED, state_); | 1132 DCHECK_EQ(INIT_TASK_SCHEDULED, state_); |
| 1098 state_ = INIT_TASK_DONE; | 1133 state_ = INIT_TASK_DONE; |
| 1099 scheduler_->InitTaskComplete(); | 1134 scheduler_->InitTaskComplete(); |
| 1100 } | 1135 } |
| 1101 | 1136 |
| 1102 base::TimeDelta MetricsService::GetIncrementalUptime(PrefService* pref) { | 1137 base::TimeDelta MetricsService::GetIncrementalUptime(PrefService* pref) { |
| 1103 base::TimeTicks now = base::TimeTicks::Now(); | 1138 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(); | 1275 PrefService* pref = g_browser_process->local_state(); |
| 1241 current_log->RecordStabilityMetrics(GetIncrementalUptime(pref), | 1276 current_log->RecordStabilityMetrics(GetIncrementalUptime(pref), |
| 1242 MetricsLog::ONGOING_LOG); | 1277 MetricsLog::ONGOING_LOG); |
| 1243 | 1278 |
| 1244 RecordCurrentHistograms(); | 1279 RecordCurrentHistograms(); |
| 1245 | 1280 |
| 1246 log_manager_.FinishCurrentLog(); | 1281 log_manager_.FinishCurrentLog(); |
| 1247 } | 1282 } |
| 1248 | 1283 |
| 1249 void MetricsService::PushPendingLogsToPersistentStorage() { | 1284 void MetricsService::PushPendingLogsToPersistentStorage() { |
| 1250 if (state_ < INITIAL_LOG_READY) | 1285 if (state_ < SENDING_INITIAL_STABILITY_LOG) |
| 1251 return; // We didn't and still don't have time to get plugin list etc. | 1286 return; // We didn't and still don't have time to get plugin list etc. |
| 1252 | 1287 |
| 1253 if (log_manager_.has_staged_log()) { | 1288 if (log_manager_.has_staged_log()) { |
| 1254 // We may race here, and send second copy of the log later. | 1289 // We may race here, and send second copy of the log later. |
| 1255 MetricsLogManager::StoreType store_type; | 1290 MetricsLogManager::StoreType store_type; |
| 1256 if (current_fetch_.get()) | 1291 if (current_fetch_.get()) |
| 1257 store_type = MetricsLogManager::PROVISIONAL_STORE; | 1292 store_type = MetricsLogManager::PROVISIONAL_STORE; |
| 1258 else | 1293 else |
| 1259 store_type = MetricsLogManager::NORMAL_STORE; | 1294 store_type = MetricsLogManager::NORMAL_STORE; |
| 1260 log_manager_.StoreStagedLogAsUnsent(store_type); | 1295 log_manager_.StoreStagedLogAsUnsent(store_type); |
| 1261 } | 1296 } |
| 1262 DCHECK(!log_manager_.has_staged_log()); | 1297 DCHECK(!log_manager_.has_staged_log()); |
| 1263 CloseCurrentLog(); | 1298 CloseCurrentLog(); |
| 1264 StoreUnsentLogs(); | 1299 log_manager_.PersistUnsentLogs(); |
| 1265 | 1300 |
| 1266 // If there was a staged and/or current log, then there is now at least one | 1301 // If there was a staged and/or current log, then there is now at least one |
| 1267 // log waiting to be uploaded. | 1302 // log waiting to be uploaded. |
| 1268 if (log_manager_.has_unsent_logs()) | 1303 if (log_manager_.has_unsent_logs()) |
| 1269 state_ = SENDING_OLD_LOGS; | 1304 state_ = SENDING_OLD_LOGS; |
| 1270 } | 1305 } |
| 1271 | 1306 |
| 1272 //------------------------------------------------------------------------------ | 1307 //------------------------------------------------------------------------------ |
| 1273 // Transmission of logs methods | 1308 // Transmission of logs methods |
| 1274 | 1309 |
| 1275 void MetricsService::StartSchedulerIfNecessary() { | 1310 void MetricsService::StartSchedulerIfNecessary() { |
| 1276 // Never schedule cutting or uploading of logs in test mode. | 1311 // Never schedule cutting or uploading of logs in test mode. |
| 1277 if (test_mode_active_) | 1312 if (test_mode_active_) |
| 1278 return; | 1313 return; |
| 1279 | 1314 |
| 1280 // Even if reporting is disabled, the scheduler is needed to trigger the | 1315 // 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 | 1316 // creation of the initial log, which must be done in order for any logs to be |
| 1282 // persisted on shutdown or backgrounding. | 1317 // persisted on shutdown or backgrounding. |
| 1283 if (recording_active() && (reporting_active() || state_ < INITIAL_LOG_READY)) | 1318 if (recording_active() && |
| 1319 (reporting_active() || state_ < SENDING_INITIAL_STABILITY_LOG)) { |
| 1284 scheduler_->Start(); | 1320 scheduler_->Start(); |
| 1321 } |
| 1285 } | 1322 } |
| 1286 | 1323 |
| 1287 void MetricsService::StartScheduledUpload() { | 1324 void MetricsService::StartScheduledUpload() { |
| 1288 // If we're getting no notifications, then the log won't have much in it, and | 1325 // 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 | 1326 // it's possible the computer is about to go to sleep, so don't upload and |
| 1290 // stop the scheduler. | 1327 // stop the scheduler. |
| 1291 // If recording has been turned off, the scheduler doesn't need to run. | 1328 // 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 | 1329 // 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. | 1330 // 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 | 1331 // TODO(stuartmorgan): Call Stop() on the schedule when reporting and/or |
| 1295 // recording are turned off instead of letting it fire and then aborting. | 1332 // recording are turned off instead of letting it fire and then aborting. |
| 1296 if (idle_since_last_transmission_ || | 1333 if (idle_since_last_transmission_ || |
| 1297 !recording_active() || | 1334 !recording_active() || |
| 1298 (!reporting_active() && state_ >= INITIAL_LOG_READY)) { | 1335 (!reporting_active() && state_ >= SENDING_INITIAL_STABILITY_LOG)) { |
| 1299 scheduler_->Stop(); | 1336 scheduler_->Stop(); |
| 1300 scheduler_->UploadCancelled(); | 1337 scheduler_->UploadCancelled(); |
| 1301 return; | 1338 return; |
| 1302 } | 1339 } |
| 1303 | 1340 |
| 1304 // If the callback was to upload an old log, but there no longer is one, | 1341 // 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 | 1342 // just report success back to the scheduler to begin the ongoing log |
| 1306 // callbacks. | 1343 // callbacks. |
| 1307 // TODO(stuartmorgan): Consider removing the distinction between | 1344 // TODO(stuartmorgan): Consider removing the distinction between |
| 1308 // SENDING_OLD_LOGS and SENDING_CURRENT_LOGS to simplify the state machine | 1345 // SENDING_OLD_LOGS and SENDING_CURRENT_LOGS to simplify the state machine |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1437 if (log_manager_.has_staged_log()) | 1474 if (log_manager_.has_staged_log()) |
| 1438 return; | 1475 return; |
| 1439 | 1476 |
| 1440 switch (state_) { | 1477 switch (state_) { |
| 1441 case INITIALIZED: | 1478 case INITIALIZED: |
| 1442 case INIT_TASK_SCHEDULED: // We should be further along by now. | 1479 case INIT_TASK_SCHEDULED: // We should be further along by now. |
| 1443 NOTREACHED(); | 1480 NOTREACHED(); |
| 1444 return; | 1481 return; |
| 1445 | 1482 |
| 1446 case INIT_TASK_DONE: | 1483 case INIT_TASK_DONE: |
| 1447 PrepareInitialLog(); | 1484 if (has_initial_stability_log_) { |
| 1448 DCHECK_EQ(INIT_TASK_DONE, state_); | 1485 // There's an initial stability log, ready to send. |
| 1449 log_manager_.LoadPersistedUnsentLogs(); | 1486 log_manager_.StageNextLogForUpload(); |
| 1450 state_ = INITIAL_LOG_READY; | 1487 has_initial_stability_log_ = false; |
| 1488 state_ = SENDING_INITIAL_STABILITY_LOG; |
| 1489 } else { |
| 1490 // TODO(asvitkine): When the field trial is removed, the |log_type| |
| 1491 // arg should be removed and PrepareInitialMetricsLog() should always |
| 1492 // use ONGOING_LOG. Use INITIAL_LOG only to match to the old behavior |
| 1493 // when the field trial is off. |
| 1494 MetricsLog::LogType log_type = SendSeparateInitialStabilityLog() ? |
| 1495 MetricsLog::ONGOING_LOG : MetricsLog::INITIAL_LOG; |
| 1496 PrepareInitialMetricsLog(log_type); |
| 1497 // If the stability log field trial is off, load unsent logs from local |
| 1498 // state here. Otherwise, they have already been loaded earlier. |
| 1499 if (log_type == MetricsLog::INITIAL_LOG) |
| 1500 log_manager_.LoadPersistedUnsentLogs(); |
| 1501 state_ = SENDING_INITIAL_METRICS_LOG; |
| 1502 } |
| 1451 break; | 1503 break; |
| 1452 | 1504 |
| 1453 case SENDING_OLD_LOGS: | 1505 case SENDING_OLD_LOGS: |
| 1454 NOTREACHED(); // Shouldn't be staging a new log during old log sending. | 1506 NOTREACHED(); // Shouldn't be staging a new log during old log sending. |
| 1455 return; | 1507 return; |
| 1456 | 1508 |
| 1457 case SENDING_CURRENT_LOGS: | 1509 case SENDING_CURRENT_LOGS: |
| 1458 CloseCurrentLog(); | 1510 CloseCurrentLog(); |
| 1459 OpenNewLog(); | 1511 OpenNewLog(); |
| 1460 log_manager_.StageNextLogForUpload(); | 1512 log_manager_.StageNextLogForUpload(); |
| 1461 break; | 1513 break; |
| 1462 | 1514 |
| 1463 default: | 1515 default: |
| 1464 NOTREACHED(); | 1516 NOTREACHED(); |
| 1465 return; | 1517 return; |
| 1466 } | 1518 } |
| 1467 | 1519 |
| 1468 DCHECK(log_manager_.has_staged_log()); | 1520 DCHECK(log_manager_.has_staged_log()); |
| 1469 } | 1521 } |
| 1470 | 1522 |
| 1471 void MetricsService::PrepareInitialLog() { | 1523 void MetricsService::PrepareInitialStabilityLog() { |
| 1472 DCHECK_EQ(INIT_TASK_DONE, state_); | 1524 DCHECK_EQ(INITIALIZED, state_); |
| 1525 PrefService* pref = g_browser_process->local_state(); |
| 1526 DCHECK_NE(0, pref->GetInteger(prefs::kStabilityCrashCount)); |
| 1473 | 1527 |
| 1474 DCHECK(initial_log_.get()); | 1528 scoped_ptr<MetricsLog> initial_stability_log( |
| 1475 initial_log_->set_hardware_class(hardware_class_); | 1529 new MetricsLog(client_id_, session_id_)); |
| 1530 if (!initial_stability_log->LoadSavedEnvironmentFromPrefs()) |
| 1531 return; |
| 1532 initial_stability_log->RecordStabilityMetrics(base::TimeDelta(), |
| 1533 MetricsLog::INITIAL_LOG); |
| 1534 log_manager_.LoadPersistedUnsentLogs(); |
| 1535 |
| 1536 log_manager_.PauseCurrentLog(); |
| 1537 log_manager_.BeginLoggingWithLog(initial_stability_log.release(), |
| 1538 MetricsLog::INITIAL_LOG); |
| 1539 log_manager_.FinishCurrentLog(); |
| 1540 log_manager_.ResumePausedLog(); |
| 1541 |
| 1542 // Store unsent logs, including the stability log that was just saved, so |
| 1543 // that they're not lost in case of a crash before upload time. |
| 1544 log_manager_.PersistUnsentLogs(); |
| 1545 |
| 1546 has_initial_stability_log_ = true; |
| 1547 } |
| 1548 |
| 1549 void MetricsService::PrepareInitialMetricsLog(MetricsLog::LogType log_type) { |
| 1550 DCHECK(state_ == INIT_TASK_DONE || state_ == SENDING_INITIAL_STABILITY_LOG); |
| 1551 initial_metrics_log_->set_hardware_class(hardware_class_); |
| 1476 | 1552 |
| 1477 std::vector<chrome_variations::ActiveGroupId> synthetic_trials; | 1553 std::vector<chrome_variations::ActiveGroupId> synthetic_trials; |
| 1478 GetCurrentSyntheticFieldTrials(&synthetic_trials); | 1554 GetCurrentSyntheticFieldTrials(&synthetic_trials); |
| 1479 initial_log_->RecordEnvironment(plugins_, google_update_metrics_, | 1555 initial_metrics_log_->RecordEnvironment(plugins_, google_update_metrics_, |
| 1480 synthetic_trials); | 1556 synthetic_trials); |
| 1481 PrefService* pref = g_browser_process->local_state(); | 1557 PrefService* pref = g_browser_process->local_state(); |
| 1482 initial_log_->RecordStabilityMetrics(GetIncrementalUptime(pref), | 1558 initial_metrics_log_->RecordStabilityMetrics(GetIncrementalUptime(pref), |
| 1483 MetricsLog::INITIAL_LOG); | 1559 log_type); |
| 1484 | 1560 |
| 1485 // Histograms only get written to the current log, so make the new log current | 1561 // Histograms only get written to the current log, so make the new log current |
| 1486 // before writing them. | 1562 // before writing them. |
| 1487 log_manager_.PauseCurrentLog(); | 1563 log_manager_.PauseCurrentLog(); |
| 1488 log_manager_.BeginLoggingWithLog(initial_log_.release(), | 1564 log_manager_.BeginLoggingWithLog(initial_metrics_log_.release(), log_type); |
| 1489 MetricsLog::INITIAL_LOG); | |
| 1490 RecordCurrentHistograms(); | 1565 RecordCurrentHistograms(); |
| 1491 log_manager_.FinishCurrentLog(); | 1566 log_manager_.FinishCurrentLog(); |
| 1492 log_manager_.ResumePausedLog(); | 1567 log_manager_.ResumePausedLog(); |
| 1493 | 1568 |
| 1494 DCHECK(!log_manager_.has_staged_log()); | 1569 DCHECK(!log_manager_.has_staged_log()); |
| 1495 log_manager_.StageNextLogForUpload(); | 1570 log_manager_.StageNextLogForUpload(); |
| 1496 } | 1571 } |
| 1497 | 1572 |
| 1498 void MetricsService::StoreUnsentLogs() { | |
| 1499 if (state_ < INITIAL_LOG_READY) | |
| 1500 return; // We never Recalled the prior unsent logs. | |
| 1501 | |
| 1502 log_manager_.PersistUnsentLogs(); | |
| 1503 } | |
| 1504 | |
| 1505 void MetricsService::SendStagedLog() { | 1573 void MetricsService::SendStagedLog() { |
| 1506 DCHECK(log_manager_.has_staged_log()); | 1574 DCHECK(log_manager_.has_staged_log()); |
| 1507 | 1575 |
| 1508 PrepareFetchWithStagedLog(); | 1576 PrepareFetchWithStagedLog(); |
| 1509 | 1577 |
| 1510 bool upload_created = (current_fetch_.get() != NULL); | 1578 bool upload_created = (current_fetch_.get() != NULL); |
| 1511 UMA_HISTOGRAM_BOOLEAN("UMA.UploadCreation", upload_created); | 1579 UMA_HISTOGRAM_BOOLEAN("UMA.UploadCreation", upload_created); |
| 1512 if (!upload_created) { | 1580 if (!upload_created) { |
| 1513 // Compression failed, and log discarded :-/. | 1581 // Compression failed, and log discarded :-/. |
| 1514 // Skip this upload and hope things work out next time. | 1582 // Skip this upload and hope things work out next time. |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1600 discard_log = true; | 1668 discard_log = true; |
| 1601 } | 1669 } |
| 1602 | 1670 |
| 1603 if (upload_succeeded || discard_log) | 1671 if (upload_succeeded || discard_log) |
| 1604 log_manager_.DiscardStagedLog(); | 1672 log_manager_.DiscardStagedLog(); |
| 1605 | 1673 |
| 1606 waiting_for_asynchronous_reporting_step_ = false; | 1674 waiting_for_asynchronous_reporting_step_ = false; |
| 1607 | 1675 |
| 1608 if (!log_manager_.has_staged_log()) { | 1676 if (!log_manager_.has_staged_log()) { |
| 1609 switch (state_) { | 1677 switch (state_) { |
| 1610 case INITIAL_LOG_READY: | 1678 case SENDING_INITIAL_STABILITY_LOG: |
| 1679 // Store the updated list to disk now that the removed log is uploaded. |
| 1680 log_manager_.PersistUnsentLogs(); |
| 1681 PrepareInitialMetricsLog(MetricsLog::ONGOING_LOG); |
| 1682 SendStagedLog(); |
| 1683 state_ = SENDING_INITIAL_METRICS_LOG; |
| 1684 break; |
| 1685 |
| 1686 case SENDING_INITIAL_METRICS_LOG: |
| 1687 // The initial metrics log never gets persisted to local state, so it's |
| 1688 // not necessary to call log_manager_.PersistUnsentLogs() here. |
| 1689 // TODO(asvitkine): It should be persisted like the initial stability |
| 1690 // log and old unsent logs. http://crbug.com/328417 |
| 1611 state_ = log_manager_.has_unsent_logs() ? SENDING_OLD_LOGS | 1691 state_ = log_manager_.has_unsent_logs() ? SENDING_OLD_LOGS |
| 1612 : SENDING_CURRENT_LOGS; | 1692 : SENDING_CURRENT_LOGS; |
| 1613 break; | 1693 break; |
| 1614 | 1694 |
| 1615 case SENDING_OLD_LOGS: | 1695 case SENDING_OLD_LOGS: |
| 1616 // Store the updated list to disk now that the removed log is uploaded. | 1696 // Store the updated list to disk now that the removed log is uploaded. |
| 1617 StoreUnsentLogs(); | 1697 log_manager_.PersistUnsentLogs(); |
| 1618 if (!log_manager_.has_unsent_logs()) | 1698 if (!log_manager_.has_unsent_logs()) |
| 1619 state_ = SENDING_CURRENT_LOGS; | 1699 state_ = SENDING_CURRENT_LOGS; |
| 1620 break; | 1700 break; |
| 1621 | 1701 |
| 1622 case SENDING_CURRENT_LOGS: | 1702 case SENDING_CURRENT_LOGS: |
| 1623 break; | 1703 break; |
| 1624 | 1704 |
| 1625 default: | 1705 default: |
| 1626 NOTREACHED(); | 1706 NOTREACHED(); |
| 1627 break; | 1707 break; |
| 1628 } | 1708 } |
| 1629 | 1709 |
| 1630 if (log_manager_.has_unsent_logs()) | 1710 if (log_manager_.has_unsent_logs()) |
| 1631 DCHECK_LT(state_, SENDING_CURRENT_LOGS); | 1711 DCHECK_LT(state_, SENDING_CURRENT_LOGS); |
| 1632 } | 1712 } |
| 1633 | 1713 |
| 1634 // Error 400 indicates a problem with the log, not with the server, so | 1714 // 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. | 1715 // don't consider that a sign that the server is in trouble. |
| 1636 bool server_is_healthy = upload_succeeded || response_code == 400; | 1716 bool server_is_healthy = upload_succeeded || response_code == 400; |
| 1637 scheduler_->UploadFinished(server_is_healthy, log_manager_.has_unsent_logs()); | 1717 // Don't notify the scheduler that the upload is finished if we've only sent |
| 1718 // the initial stability log, but not yet the initial metrics log (treat the |
| 1719 // two as a single unit of work as far as the scheduler is concerned). |
| 1720 if (state_ != SENDING_INITIAL_METRICS_LOG) { |
| 1721 scheduler_->UploadFinished(server_is_healthy, |
| 1722 log_manager_.has_unsent_logs()); |
| 1723 } |
| 1638 | 1724 |
| 1639 // Collect network stats if UMA upload succeeded. | 1725 // Collect network stats if UMA upload succeeded. |
| 1640 IOThread* io_thread = g_browser_process->io_thread(); | 1726 IOThread* io_thread = g_browser_process->io_thread(); |
| 1641 if (server_is_healthy && io_thread) { | 1727 if (server_is_healthy && io_thread) { |
| 1642 chrome_browser_net::CollectNetworkStats(network_stats_server_, io_thread); | 1728 chrome_browser_net::CollectNetworkStats(network_stats_server_, io_thread); |
| 1643 chrome_browser_net::CollectPipeliningCapabilityStatsOnUIThread( | 1729 chrome_browser_net::CollectPipeliningCapabilityStatsOnUIThread( |
| 1644 http_pipelining_test_server_, io_thread); | 1730 http_pipelining_test_server_, io_thread); |
| 1645 #if defined(OS_WIN) | 1731 #if defined(OS_WIN) |
| 1646 chrome::CollectTimeTicksStats(); | 1732 chrome::CollectTimeTicksStats(); |
| 1647 #endif | 1733 #endif |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1693 } | 1779 } |
| 1694 | 1780 |
| 1695 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildCrashes", | 1781 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildCrashes", |
| 1696 was_extension_process ? 2 : 1); | 1782 was_extension_process ? 2 : 1); |
| 1697 } else if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED) { | 1783 } else if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED) { |
| 1698 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildKills", | 1784 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.ChildKills", |
| 1699 was_extension_process ? 2 : 1); | 1785 was_extension_process ? 2 : 1); |
| 1700 } else if (status == base::TERMINATION_STATUS_STILL_RUNNING) { | 1786 } else if (status == base::TERMINATION_STATUS_STILL_RUNNING) { |
| 1701 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.DisconnectedAlive", | 1787 UMA_HISTOGRAM_PERCENTAGE("BrowserRenderProcessHost.DisconnectedAlive", |
| 1702 was_extension_process ? 2 : 1); | 1788 was_extension_process ? 2 : 1); |
| 1703 } | |
| 1704 } | 1789 } |
| 1790 } |
| 1705 | 1791 |
| 1706 void MetricsService::LogRendererHang() { | 1792 void MetricsService::LogRendererHang() { |
| 1707 IncrementPrefValue(prefs::kStabilityRendererHangCount); | 1793 IncrementPrefValue(prefs::kStabilityRendererHangCount); |
| 1708 } | 1794 } |
| 1709 | 1795 |
| 1710 bool MetricsService::UmaMetricsProperlyShutdown() { | 1796 bool MetricsService::UmaMetricsProperlyShutdown() { |
| 1711 CHECK(clean_shutdown_status_ == CLEANLY_SHUTDOWN || | 1797 CHECK(clean_shutdown_status_ == CLEANLY_SHUTDOWN || |
| 1712 clean_shutdown_status_ == NEED_TO_SHUTDOWN); | 1798 clean_shutdown_status_ == NEED_TO_SHUTDOWN); |
| 1713 return clean_shutdown_status_ == CLEANLY_SHUTDOWN; | 1799 return clean_shutdown_status_ == CLEANLY_SHUTDOWN; |
| 1714 } | 1800 } |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1932 if (local_state) { | 2018 if (local_state) { |
| 1933 const PrefService::Preference* uma_pref = | 2019 const PrefService::Preference* uma_pref = |
| 1934 local_state->FindPreference(prefs::kMetricsReportingEnabled); | 2020 local_state->FindPreference(prefs::kMetricsReportingEnabled); |
| 1935 if (uma_pref) { | 2021 if (uma_pref) { |
| 1936 bool success = uma_pref->GetValue()->GetAsBoolean(&result); | 2022 bool success = uma_pref->GetValue()->GetAsBoolean(&result); |
| 1937 DCHECK(success); | 2023 DCHECK(success); |
| 1938 } | 2024 } |
| 1939 } | 2025 } |
| 1940 return result; | 2026 return result; |
| 1941 } | 2027 } |
| OLD | NEW |