1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/net/chrome_net_log.h" 6 7#include <algorithm> 8 9#include "base/command_line.h" 10#include "base/logging.h" 11#include "base/string_util.h" 12#include "base/values.h" 13#include "chrome/browser/net/load_timing_observer.h" 14#include "chrome/browser/net/net_log_logger.h" 15#include "chrome/browser/net/passive_log_collector.h" 16#include "chrome/common/chrome_switches.h" 17 18ChromeNetLog::ThreadSafeObserver::ThreadSafeObserver(LogLevel log_level) 19 : net_log_(NULL), 20 log_level_(log_level) { 21} 22 23ChromeNetLog::ThreadSafeObserver::~ThreadSafeObserver() { 24 DCHECK(!net_log_); 25} 26 27net::NetLog::LogLevel ChromeNetLog::ThreadSafeObserver::log_level() const { 28 return log_level_; 29} 30 31void ChromeNetLog::ThreadSafeObserver::AssertNetLogLockAcquired() const { 32 if (net_log_) 33 net_log_->lock_.AssertAcquired(); 34} 35 36void ChromeNetLog::ThreadSafeObserver::SetLogLevel( 37 net::NetLog::LogLevel log_level) { 38 DCHECK(net_log_); 39 base::AutoLock lock(net_log_->lock_); 40 log_level_ = log_level; 41 net_log_->UpdateLogLevel_(); 42} 43 44ChromeNetLog::Entry::Entry(uint32 order, 45 net::NetLog::EventType type, 46 const base::TimeTicks& time, 47 net::NetLog::Source source, 48 net::NetLog::EventPhase phase, 49 net::NetLog::EventParameters* params) 50 : order(order), 51 type(type), 52 time(time), 53 source(source), 54 phase(phase), 55 params(params) { 56} 57 58ChromeNetLog::Entry::~Entry() {} 59 60ChromeNetLog::ChromeNetLog() 61 : last_id_(0), 62 log_level_(LOG_BASIC), 63 passive_collector_(new PassiveLogCollector), 64 load_timing_observer_(new LoadTimingObserver) { 65 AddObserver(passive_collector_.get()); 66 AddObserver(load_timing_observer_.get()); 67 68 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 69 if (command_line.HasSwitch(switches::kLogNetLog)) { 70 net_log_logger_.reset(new NetLogLogger( 71 command_line.GetSwitchValuePath(switches::kLogNetLog))); 72 AddObserver(net_log_logger_.get()); 73 } 74} 75 76ChromeNetLog::~ChromeNetLog() { 77 RemoveObserver(passive_collector_.get()); 78 RemoveObserver(load_timing_observer_.get()); 79 if (net_log_logger_.get()) { 80 RemoveObserver(net_log_logger_.get()); 81 } 82} 83 84void ChromeNetLog::AddEntry(EventType type, 85 const base::TimeTicks& time, 86 const Source& source, 87 EventPhase phase, 88 EventParameters* params) { 89 base::AutoLock lock(lock_); 90 91 // Notify all of the log observers. 92 FOR_EACH_OBSERVER(ThreadSafeObserver, observers_, 93 OnAddEntry(type, time, source, phase, params)); 94} 95 96uint32 ChromeNetLog::NextID() { 97 return base::subtle::NoBarrier_AtomicIncrement(&last_id_, 1); 98} 99 100net::NetLog::LogLevel ChromeNetLog::GetLogLevel() const { 101 base::subtle::Atomic32 log_level = base::subtle::NoBarrier_Load(&log_level_); 102 return static_cast<net::NetLog::LogLevel>(log_level); 103} 104 105void ChromeNetLog::AddObserver(ThreadSafeObserver* observer) { 106 base::AutoLock lock(lock_); 107 AddObserverWhileLockHeld(observer); 108} 109 110void ChromeNetLog::RemoveObserver(ThreadSafeObserver* observer) { 111 base::AutoLock lock(lock_); 112 DCHECK_EQ(observer->net_log_, this); 113 observer->net_log_ = NULL; 114 observers_.RemoveObserver(observer); 115 UpdateLogLevel_(); 116} 117 118void ChromeNetLog::AddObserverAndGetAllPassivelyCapturedEvents( 119 ThreadSafeObserver* observer, EntryList* passive_entries) { 120 base::AutoLock lock(lock_); 121 AddObserverWhileLockHeld(observer); 122 passive_collector_->GetAllCapturedEvents(passive_entries); 123} 124 125void ChromeNetLog::GetAllPassivelyCapturedEvents(EntryList* passive_entries) { 126 base::AutoLock lock(lock_); 127 passive_collector_->GetAllCapturedEvents(passive_entries); 128} 129 130void ChromeNetLog::ClearAllPassivelyCapturedEvents() { 131 base::AutoLock lock(lock_); 132 passive_collector_->Clear(); 133} 134 135void ChromeNetLog::UpdateLogLevel_() { 136 lock_.AssertAcquired(); 137 138 // Look through all the observers and find the finest granularity 139 // log level (higher values of the enum imply *lower* log levels). 140 LogLevel new_log_level = LOG_BASIC; 141 ObserverListBase<ThreadSafeObserver>::Iterator it(observers_); 142 ThreadSafeObserver* observer; 143 while ((observer = it.GetNext()) != NULL) { 144 new_log_level = std::min(new_log_level, observer->log_level()); 145 } 146 base::subtle::NoBarrier_Store(&log_level_, new_log_level); 147} 148 149void ChromeNetLog::AddObserverWhileLockHeld(ThreadSafeObserver* observer) { 150 DCHECK(!observer->net_log_); 151 observer->net_log_ = this; 152 observers_.AddObserver(observer); 153 UpdateLogLevel_(); 154} 155