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 18 ChromeNetLog::ThreadSafeObserver::ThreadSafeObserver(LogLevel log_level) 19 : net_log_(NULL), 20 log_level_(log_level) { 21 } 22 23 ChromeNetLog::ThreadSafeObserver::~ThreadSafeObserver() { 24 DCHECK(!net_log_); 25 } 26 27 net::NetLog::LogLevel ChromeNetLog::ThreadSafeObserver::log_level() const { 28 return log_level_; 29 } 30 31 void ChromeNetLog::ThreadSafeObserver::AssertNetLogLockAcquired() const { 32 if (net_log_) 33 net_log_->lock_.AssertAcquired(); 34 } 35 36 void 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 44 ChromeNetLog::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 58 ChromeNetLog::Entry::~Entry() {} 59 60 ChromeNetLog::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 76 ChromeNetLog::~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 84 void 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 96 uint32 ChromeNetLog::NextID() { 97 return base::subtle::NoBarrier_AtomicIncrement(&last_id_, 1); 98 } 99 100 net::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 105 void ChromeNetLog::AddObserver(ThreadSafeObserver* observer) { 106 base::AutoLock lock(lock_); 107 AddObserverWhileLockHeld(observer); 108 } 109 110 void 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 118 void ChromeNetLog::AddObserverAndGetAllPassivelyCapturedEvents( 119 ThreadSafeObserver* observer, EntryList* passive_entries) { 120 base::AutoLock lock(lock_); 121 AddObserverWhileLockHeld(observer); 122 passive_collector_->GetAllCapturedEvents(passive_entries); 123 } 124 125 void ChromeNetLog::GetAllPassivelyCapturedEvents(EntryList* passive_entries) { 126 base::AutoLock lock(lock_); 127 passive_collector_->GetAllCapturedEvents(passive_entries); 128 } 129 130 void ChromeNetLog::ClearAllPassivelyCapturedEvents() { 131 base::AutoLock lock(lock_); 132 passive_collector_->Clear(); 133 } 134 135 void 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 149 void ChromeNetLog::AddObserverWhileLockHeld(ThreadSafeObserver* observer) { 150 DCHECK(!observer->net_log_); 151 observer->net_log_ = this; 152 observers_.AddObserver(observer); 153 UpdateLogLevel_(); 154 } 155