1// Copyright 2014 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 "net/base/trace_net_log_observer.h"
6
7#include <stdio.h>
8
9#include <string>
10
11#include "base/debug/trace_event.h"
12#include "base/json/json_writer.h"
13#include "base/logging.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/values.h"
16#include "net/base/net_log.h"
17
18namespace net {
19
20namespace {
21
22class TracedValue : public base::debug::ConvertableToTraceFormat {
23 public:
24  explicit TracedValue(scoped_ptr<base::Value> value) : value_(value.Pass()) {}
25
26 private:
27  virtual ~TracedValue() {}
28
29  virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE {
30    if (value_) {
31      std::string tmp;
32      base::JSONWriter::Write(value_.get(), &tmp);
33      *out += tmp;
34    } else {
35      *out += "\"\"";
36    }
37  }
38
39 private:
40  scoped_ptr<base::Value> value_;
41};
42
43}  // namespace
44
45TraceNetLogObserver::TraceNetLogObserver() : net_log_to_watch_(NULL) {
46}
47
48TraceNetLogObserver::~TraceNetLogObserver() {
49  DCHECK(!net_log_to_watch_);
50  DCHECK(!net_log());
51}
52
53void TraceNetLogObserver::OnAddEntry(const NetLog::Entry& entry) {
54  scoped_ptr<base::Value> params(entry.ParametersToValue());
55  switch (entry.phase()) {
56    case NetLog::PHASE_BEGIN:
57      TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(
58          "netlog", NetLog::EventTypeToString(entry.type()), entry.source().id,
59          "source_type", NetLog::SourceTypeToString(entry.source().type),
60          "params", scoped_refptr<base::debug::ConvertableToTraceFormat>(
61              new TracedValue(params.Pass())));
62      break;
63    case NetLog::PHASE_END:
64      TRACE_EVENT_NESTABLE_ASYNC_END2(
65          "netlog", NetLog::EventTypeToString(entry.type()), entry.source().id,
66          "source_type", NetLog::SourceTypeToString(entry.source().type),
67          "params", scoped_refptr<base::debug::ConvertableToTraceFormat>(
68              new TracedValue(params.Pass())));
69      break;
70    case NetLog::PHASE_NONE:
71      TRACE_EVENT_NESTABLE_ASYNC_INSTANT2(
72          "netlog", NetLog::EventTypeToString(entry.type()), entry.source().id,
73          "source_type", NetLog::SourceTypeToString(entry.source().type),
74          "params", scoped_refptr<base::debug::ConvertableToTraceFormat>(
75              new TracedValue(params.Pass())));
76      break;
77  }
78}
79
80void TraceNetLogObserver::WatchForTraceStart(NetLog* netlog) {
81  DCHECK(!net_log_to_watch_);
82  DCHECK(!net_log());
83  net_log_to_watch_ = netlog;
84  base::debug::TraceLog::GetInstance()->AddEnabledStateObserver(this);
85}
86
87void TraceNetLogObserver::StopWatchForTraceStart() {
88  // Should only stop if is currently watching.
89  DCHECK(net_log_to_watch_);
90  base::debug::TraceLog::GetInstance()->RemoveEnabledStateObserver(this);
91  if (net_log())
92    net_log()->RemoveThreadSafeObserver(this);
93  net_log_to_watch_ = NULL;
94}
95
96void TraceNetLogObserver::OnTraceLogEnabled() {
97  net_log_to_watch_->AddThreadSafeObserver(this,
98                                           NetLog::LOG_STRIP_PRIVATE_DATA);
99}
100
101void TraceNetLogObserver::OnTraceLogDisabled() {
102  if (net_log())
103    net_log()->RemoveThreadSafeObserver(this);
104}
105
106}  // namespace net
107