1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/chrome_net_log.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/command_line.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 1221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/values.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/load_timing_observer.h" 143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/net/net_log_logger.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/passive_log_collector.h" 163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/chrome_switches.h" 173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenChromeNetLog::ThreadSafeObserver::ThreadSafeObserver(LogLevel log_level) 1921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen : net_log_(NULL), 2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log_level_(log_level) { 2121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenChromeNetLog::ThreadSafeObserver::~ThreadSafeObserver() { 2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(!net_log_); 2521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennet::NetLog::LogLevel ChromeNetLog::ThreadSafeObserver::log_level() const { 28731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return log_level_; 29731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 30731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 3121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ChromeNetLog::ThreadSafeObserver::AssertNetLogLockAcquired() const { 3221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (net_log_) 3321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net_log_->lock_.AssertAcquired(); 3421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 3521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 3621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ChromeNetLog::ThreadSafeObserver::SetLogLevel( 3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::NetLog::LogLevel log_level) { 3821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(net_log_); 3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(net_log_->lock_); 40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick log_level_ = log_level; 4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net_log_->UpdateLogLevel_(); 4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenChromeNetLog::Entry::Entry(uint32 order, 4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::NetLog::EventType type, 4621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const base::TimeTicks& time, 4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::NetLog::Source source, 4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::NetLog::EventPhase phase, 4921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen net::NetLog::EventParameters* params) 5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen : order(order), 5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen type(type), 5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen time(time), 5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen source(source), 5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen phase(phase), 5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen params(params) { 56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 57731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 5821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenChromeNetLog::Entry::~Entry() {} 5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochChromeNetLog::ChromeNetLog() 6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen : last_id_(0), 6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen log_level_(LOG_BASIC), 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch passive_collector_(new PassiveLogCollector), 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch load_timing_observer_(new LoadTimingObserver) { 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddObserver(passive_collector_.get()); 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddObserver(load_timing_observer_.get()); 673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (command_line.HasSwitch(switches::kLogNetLog)) { 7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net_log_logger_.reset(new NetLogLogger( 7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen command_line.GetSwitchValuePath(switches::kLogNetLog))); 723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AddObserver(net_log_logger_.get()); 733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochChromeNetLog::~ChromeNetLog() { 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RemoveObserver(passive_collector_.get()); 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RemoveObserver(load_timing_observer_.get()); 793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (net_log_logger_.get()) { 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick RemoveObserver(net_log_logger_.get()); 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ChromeNetLog::AddEntry(EventType type, 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const base::TimeTicks& time, 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const Source& source, 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EventPhase phase, 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EventParameters* params) { 8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Notify all of the log observers. 9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen FOR_EACH_OBSERVER(ThreadSafeObserver, observers_, 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnAddEntry(type, time, source, phase, params)); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochuint32 ChromeNetLog::NextID() { 9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return base::subtle::NoBarrier_AtomicIncrement(&last_id_, 1); 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricknet::NetLog::LogLevel ChromeNetLog::GetLogLevel() const { 10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen base::subtle::Atomic32 log_level = base::subtle::NoBarrier_Load(&log_level_); 10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return static_cast<net::NetLog::LogLevel>(log_level); 10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 10521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ChromeNetLog::AddObserver(ThreadSafeObserver* observer) { 10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 10721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen AddObserverWhileLockHeld(observer); 10821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 10921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 11021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ChromeNetLog::RemoveObserver(ThreadSafeObserver* observer) { 11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 11221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK_EQ(observer->net_log_, this); 11321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen observer->net_log_ = NULL; 11421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen observers_.RemoveObserver(observer); 11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen UpdateLogLevel_(); 11621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 11721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 11821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ChromeNetLog::AddObserverAndGetAllPassivelyCapturedEvents( 11921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ThreadSafeObserver* observer, EntryList* passive_entries) { 12072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 12121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen AddObserverWhileLockHeld(observer); 12221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen passive_collector_->GetAllCapturedEvents(passive_entries); 12321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ChromeNetLog::GetAllPassivelyCapturedEvents(EntryList* passive_entries) { 12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 12721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen passive_collector_->GetAllCapturedEvents(passive_entries); 12821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 12921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 13021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ChromeNetLog::ClearAllPassivelyCapturedEvents() { 13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 13221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen passive_collector_->Clear(); 13321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 13421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 13521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ChromeNetLog::UpdateLogLevel_() { 13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen lock_.AssertAcquired(); 1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Look through all the observers and find the finest granularity 1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // log level (higher values of the enum imply *lower* log levels). 14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LogLevel new_log_level = LOG_BASIC; 14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ObserverListBase<ThreadSafeObserver>::Iterator it(observers_); 14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ThreadSafeObserver* observer; 1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick while ((observer = it.GetNext()) != NULL) { 14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen new_log_level = std::min(new_log_level, observer->log_level()); 1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen base::subtle::NoBarrier_Store(&log_level_, new_log_level); 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 14921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ChromeNetLog::AddObserverWhileLockHeld(ThreadSafeObserver* observer) { 15021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen DCHECK(!observer->net_log_); 15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen observer->net_log_ = this; 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observers_.AddObserver(observer); 15321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen UpdateLogLevel_(); 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 155