summaryrefslogtreecommitdiffstats
path: root/net/log/write_to_file_net_log_observer.cc
blob: 3bc78141b387cfc3498d1d95170436fef8ae8ca2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/log/write_to_file_net_log_observer.h"

#include <stdio.h>
#include <set>
#include <utility>

#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "net/log/net_log_util.h"
#include "net/url_request/url_request_context.h"

namespace net {

WriteToFileNetLogObserver::WriteToFileNetLogObserver()
    : capture_mode_(NetLogCaptureMode::Default()), added_events_(false) {
}

WriteToFileNetLogObserver::~WriteToFileNetLogObserver() {
}

void WriteToFileNetLogObserver::set_capture_mode(
    NetLogCaptureMode capture_mode) {
  DCHECK(!net_log());
  capture_mode_ = capture_mode;
}

void WriteToFileNetLogObserver::StartObserving(
    NetLog* net_log,
    base::ScopedFILE file,
    base::Value* constants,
    URLRequestContext* url_request_context) {
  DCHECK(file.get());
  file_ = std::move(file);
  added_events_ = false;

  // Write constants to the output file.  This allows loading files that have
  // different source and event types, as they may be added and removed
  // between Chrome versions.
  std::string json;
  if (constants)
    base::JSONWriter::Write(*constants, &json);
  else
    base::JSONWriter::Write(*GetNetConstants(), &json);

  fprintf(file_.get(), "{\"constants\": %s,\n", json.c_str());

  // Start events array.  It's closed in StopObserving().
  fprintf(file_.get(), "\"events\": [\n");

  // Add events for in progress requests if a context is given.
  if (url_request_context) {
    DCHECK(url_request_context->CalledOnValidThread());

    std::set<URLRequestContext*> contexts;
    contexts.insert(url_request_context);
    CreateNetLogEntriesForActiveObjects(contexts, this);
  }

  net_log->DeprecatedAddObserver(this, capture_mode_);
}

void WriteToFileNetLogObserver::StopObserving(
    URLRequestContext* url_request_context) {
  net_log()->DeprecatedRemoveObserver(this);

  // End events array.
  fprintf(file_.get(), "]");

  // Write state of the URLRequestContext when logging stopped.
  if (url_request_context) {
    DCHECK(url_request_context->CalledOnValidThread());

    std::string json;
    base::JSONWriter::Write(
        *GetNetInfo(url_request_context, NET_INFO_ALL_SOURCES), &json);
    fprintf(file_.get(), ",\"tabInfo\": %s\n", json.c_str());
  }
  fprintf(file_.get(), "}");

  file_.reset();
}

void WriteToFileNetLogObserver::OnAddEntry(const NetLog::Entry& entry) {
  // Add a comma and newline for every event but the first.  Newlines are needed
  // so can load partial log files by just ignoring the last line.  For this to
  // work, lines cannot be pretty printed.
  scoped_ptr<base::Value> value(entry.ToValue());
  std::string json;
  base::JSONWriter::Write(*value, &json);
  fprintf(file_.get(), "%s%s", (added_events_ ? ",\n" : ""), json.c_str());
  added_events_ = true;
}

}  // namespace net