1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_PERFORMANCE_MONITOR_PERFORMANCE_MONITOR_H_
#define CHROME_BROWSER_PERFORMANCE_MONITOR_PERFORMANCE_MONITOR_H_
#include <map>
#include <set>
#include <string>
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/process/process_handle.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/performance_monitor/event_type.h"
#include "chrome/browser/performance_monitor/process_metrics_history.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/render_process_host.h"
template <typename Type>
struct DefaultSingletonTraits;
namespace extensions {
class Extension;
}
namespace net {
class URLRequest;
}
namespace performance_monitor {
class Database;
class Event;
struct Metric;
// PerformanceMonitor is a tool which will allow the user to view information
// about Chrome's performance over a period of time. It will gather statistics
// pertaining to performance-oriented areas (e.g. CPU usage, memory usage, and
// network usage) and will also store information about significant events which
// are related to performance, either being indicative (e.g. crashes) or
// potentially causal (e.g. extension installation/uninstallation).
//
// Thread Safety: PerformanceMonitor lives on multiple threads. When interacting
// with the Database, PerformanceMonitor acts on a background thread (which has
// the sequence guaranteed by a token, Database::kDatabaseSequenceToken). At
// other times, the PerformanceMonitor will act on the appropriate thread for
// the task (for instance, gathering statistics about CPU and memory usage
// is done on the background thread, but most notifications occur on the UI
// thread).
class PerformanceMonitor : public content::NotificationObserver {
public:
struct PerformanceDataForIOThread {
PerformanceDataForIOThread();
uint64 network_bytes_read;
};
typedef std::map<base::ProcessHandle, ProcessMetricsHistory> MetricsMap;
// Set the path which the PerformanceMonitor should use for the database files
// constructed. This must be done prior to the initialization of the
// PerformanceMonitor. Returns true on success, false on failure (failure
// likely indicates that PerformanceMonitor has already been started at the
// time of the call).
bool SetDatabasePath(const base::FilePath& path);
bool database_logging_enabled() const { return database_logging_enabled_; }
// Returns the current PerformanceMonitor instance if one exists; otherwise
// constructs a new PerformanceMonitor.
static PerformanceMonitor* GetInstance();
// Begins the initialization process for the PerformanceMonitor in order to
// start collecting data.
void Initialize();
// Start the cycle of metrics gathering.
void StartGatherCycle();
// Inform PerformanceMonitor that bytes have been read; if these came across
// the network (and PerformanceMonitor is initialized), then increment the
// count accordingly.
void BytesReadOnIOThread(const net::URLRequest& request, const int bytes);
// content::NotificationObserver
// Wait for various notifications; insert events into the database upon
// occurance.
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
Database* database() { return database_.get(); }
base::FilePath database_path() { return database_path_; }
static bool initialized() { return initialized_; }
private:
friend struct DefaultSingletonTraits<PerformanceMonitor>;
friend class PerformanceMonitorBrowserTest;
FRIEND_TEST_ALL_PREFIXES(PerformanceMonitorUncleanExitBrowserTest,
OneProfileUncleanExit);
FRIEND_TEST_ALL_PREFIXES(PerformanceMonitorUncleanExitBrowserTest,
TwoProfileUncleanExit);
FRIEND_TEST_ALL_PREFIXES(PerformanceMonitorBrowserTest, NetworkBytesRead);
PerformanceMonitor();
virtual ~PerformanceMonitor();
// Perform any additional initialization which must be performed on a
// background thread (e.g. constructing the database).
void InitOnBackgroundThread();
void FinishInit();
// Create the persistent database if we haven't already done so.
void InitializeDatabaseIfNeeded();
// Register for the appropriate notifications as a NotificationObserver.
void RegisterForNotifications();
// Checks for whether the previous profiles closed uncleanly; this method
// should only be called once per run in order to avoid duplication of events
// (exceptions made for testing purposes where we construct the environment).
void CheckForUncleanExits();
// Find the last active time for the profile and insert the event into the
// database.
void AddUncleanExitEventOnBackgroundThread(const std::string& profile_name);
// Check the previous Chrome version from the Database and determine if
// it has been updated. If it has, insert an event in the database.
void CheckForVersionUpdateOnBackgroundThread();
// Wrapper function for inserting events into the database.
void AddEvent(scoped_ptr<Event> event);
void AddEventOnBackgroundThread(scoped_ptr<Event> event);
// Since Database::AddMetric() is overloaded, base::Bind() does not work and
// we need a helper function.
void AddMetricOnBackgroundThread(const Metric& metric);
// Notify any listeners that PerformanceMonitor has finished the initializing.
void NotifyInitialized();
// Perform any collections that are done on a timed basis.
void DoTimedCollections();
// Update the database record of the last time the active profiles were
// running; this is used in determining when an unclean exit occurred.
#if !defined(OS_ANDROID)
void UpdateLiveProfiles();
void UpdateLiveProfilesHelper(
scoped_ptr<std::set<std::string> > active_profiles, std::string time);
#endif
// Stores CPU/memory usage metrics to the database.
void StoreMetricsOnBackgroundThread(
int current_update_sequence,
const PerformanceDataForIOThread& performance_data_for_io_thread);
// Mark the given process as alive in the current update iteration.
// This means adding an entry to the map of watched processes if it's not
// already present.
void MarkProcessAsAlive(const base::ProcessHandle& handle,
int process_type,
int current_update_sequence);
// Updates the ProcessMetrics map with the current list of processes and
// gathers metrics from each entry.
void GatherMetricsMapOnUIThread();
void GatherMetricsMapOnIOThread(int current_update_sequence);
// Generate an appropriate ExtensionEvent for an extension-related occurrance
// and insert it in the database.
void AddExtensionEvent(EventType type,
const extensions::Extension* extension);
// Generate an appropriate RendererFailure for a renderer crash and insert it
// in the database.
void AddRendererClosedEvent(
content::RenderProcessHost* host,
const content::RenderProcessHost::RendererClosedDetails& details);
// The store for all performance data that must be gathered from the IO
// thread.
PerformanceDataForIOThread performance_data_for_io_thread_;
// The location at which the database files are stored; if empty, the database
// will default to '<user_data_dir>/performance_monitor_dbs'.
base::FilePath database_path_;
scoped_ptr<Database> database_;
// A map of currently running ProcessHandles to ProcessMetrics.
MetricsMap metrics_map_;
// The next time we should collect averages from the performance metrics
// and act on them.
base::Time next_collection_time_;
// How long to wait between collections.
int gather_interval_in_seconds_;
// Enable persistent logging of performance metrics to a database.
bool database_logging_enabled_;
// The timer to signal PerformanceMonitor to perform its timed collections.
base::DelayTimer<PerformanceMonitor> timer_;
content::NotificationRegistrar registrar_;
// A flag indicating whether or not PerformanceMonitor is initialized. Any
// external sources accessing PerformanceMonitor should either wait for
// the PERFORMANCE_MONITOR_INITIALIZED notification or should check this
// flag.
static bool initialized_;
// Disable auto-starting the collection timer; used for tests.
bool disable_timer_autostart_for_testing_;
DISALLOW_COPY_AND_ASSIGN(PerformanceMonitor);
};
} // namespace performance_monitor
#endif // CHROME_BROWSER_PERFORMANCE_MONITOR_PERFORMANCE_MONITOR_H_
|