Home | History | Annotate | Download | only in net
      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