chrome_net_log.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 2012 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 "base/command_line.h"
8#include "base/logging.h"
9#include "base/string_number_conversions.h"
10#include "base/string_util.h"
11#include "base/values.h"
12#include "chrome/browser/net/load_timing_observer.h"
13#include "chrome/browser/net/net_log_logger.h"
14#include "chrome/common/chrome_switches.h"
15
16ChromeNetLog::ChromeNetLog()
17    : last_id_(0),
18      base_log_level_(LOG_BASIC),
19      effective_log_level_(LOG_BASIC),
20      load_timing_observer_(new LoadTimingObserver()) {
21  const CommandLine* command_line = CommandLine::ForCurrentProcess();
22  // Adjust base log level based on command line switch, if present.
23  // This is done before adding any observers so the call to UpdateLogLevel when
24  // an observers is added will set |effective_log_level_| correctly.
25  if (command_line->HasSwitch(switches::kNetLogLevel)) {
26    std::string log_level_string =
27        command_line->GetSwitchValueASCII(switches::kNetLogLevel);
28    int command_line_log_level;
29    if (base::StringToInt(log_level_string, &command_line_log_level) &&
30        command_line_log_level >= LOG_ALL &&
31        command_line_log_level <= LOG_BASIC) {
32      base_log_level_ = static_cast<LogLevel>(command_line_log_level);
33    }
34  }
35
36  load_timing_observer_->StartObserving(this);
37
38  if (command_line->HasSwitch(switches::kLogNetLog)) {
39    net_log_logger_.reset(new NetLogLogger(
40        command_line->GetSwitchValuePath(switches::kLogNetLog)));
41    net_log_logger_->StartObserving(this);
42  }
43}
44
45ChromeNetLog::~ChromeNetLog() {
46  // Remove the observers we own before we're destroyed.
47  RemoveThreadSafeObserver(load_timing_observer_.get());
48  if (net_log_logger_.get())
49    RemoveThreadSafeObserver(net_log_logger_.get());
50}
51
52void ChromeNetLog::OnAddEntry(const net::NetLog::Entry& entry) {
53  base::AutoLock lock(lock_);
54
55  // Notify all of the log observers.
56  FOR_EACH_OBSERVER(ThreadSafeObserver, observers_, OnAddEntry(entry));
57}
58
59uint32 ChromeNetLog::NextID() {
60  return base::subtle::NoBarrier_AtomicIncrement(&last_id_, 1);
61}
62
63net::NetLog::LogLevel ChromeNetLog::GetLogLevel() const {
64  base::subtle::Atomic32 log_level =
65      base::subtle::NoBarrier_Load(&effective_log_level_);
66  return static_cast<net::NetLog::LogLevel>(log_level);
67}
68
69void ChromeNetLog::AddThreadSafeObserver(
70    net::NetLog::ThreadSafeObserver* observer,
71    LogLevel log_level) {
72  base::AutoLock lock(lock_);
73
74  observers_.AddObserver(observer);
75  OnAddObserver(observer, log_level);
76  UpdateLogLevel();
77}
78
79void ChromeNetLog::SetObserverLogLevel(
80    net::NetLog::ThreadSafeObserver* observer,
81    LogLevel log_level) {
82  base::AutoLock lock(lock_);
83
84  DCHECK(observers_.HasObserver(observer));
85  OnSetObserverLogLevel(observer, log_level);
86  UpdateLogLevel();
87}
88
89void ChromeNetLog::RemoveThreadSafeObserver(
90    net::NetLog::ThreadSafeObserver* observer) {
91  base::AutoLock lock(lock_);
92
93  DCHECK(observers_.HasObserver(observer));
94  observers_.RemoveObserver(observer);
95  OnRemoveObserver(observer);
96  UpdateLogLevel();
97}
98
99void ChromeNetLog::UpdateLogLevel() {
100  lock_.AssertAcquired();
101
102  // Look through all the observers and find the finest granularity
103  // log level (higher values of the enum imply *lower* log levels).
104  LogLevel new_effective_log_level = base_log_level_;
105  ObserverListBase<ThreadSafeObserver>::Iterator it(observers_);
106  ThreadSafeObserver* observer;
107  while ((observer = it.GetNext()) != NULL) {
108    new_effective_log_level =
109        std::min(new_effective_log_level, observer->log_level());
110  }
111  base::subtle::NoBarrier_Store(&effective_log_level_,
112                                new_effective_log_level);
113}
114