Add logging.store and logging.uploadStored to thunk.js for Hangouts.
[chromium-blink-merge.git] / net / log / net_log.cc
blobdef248d39ff5f261bf17973f31952b6b11483b2a
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.
5 #include "net/log/net_log.h"
7 #include "base/bind.h"
8 #include "base/debug/alias.h"
9 #include "base/logging.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/time/time.h"
13 #include "base/values.h"
14 #include "net/base/net_errors.h"
16 namespace net {
18 namespace {
20 // Returns parameters for logging data transferred events. At a minimum includes
21 // the number of bytes transferred. If the capture mode allows logging byte
22 // contents and |byte_count| > 0, then will include the actual bytes. The
23 // bytes are hex-encoded, since base::StringValue only supports UTF-8.
24 scoped_ptr<base::Value> BytesTransferredCallback(
25 int byte_count,
26 const char* bytes,
27 NetLogCaptureMode capture_mode) {
28 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
29 dict->SetInteger("byte_count", byte_count);
30 if (capture_mode.include_socket_bytes() && byte_count > 0)
31 dict->SetString("hex_encoded_bytes", base::HexEncode(bytes, byte_count));
32 return dict.Pass();
35 scoped_ptr<base::Value> SourceEventParametersCallback(
36 const NetLog::Source source,
37 NetLogCaptureMode /* capture_mode */) {
38 if (!source.IsValid())
39 return scoped_ptr<base::Value>();
40 scoped_ptr<base::DictionaryValue> event_params(new base::DictionaryValue());
41 source.AddToEventParameters(event_params.get());
42 return event_params.Pass();
45 scoped_ptr<base::Value> NetLogBoolCallback(
46 const char* name,
47 bool value,
48 NetLogCaptureMode /* capture_mode */) {
49 scoped_ptr<base::DictionaryValue> event_params(new base::DictionaryValue());
50 event_params->SetBoolean(name, value);
51 return event_params.Pass();
54 scoped_ptr<base::Value> NetLogIntegerCallback(
55 const char* name,
56 int value,
57 NetLogCaptureMode /* capture_mode */) {
58 scoped_ptr<base::DictionaryValue> event_params(new base::DictionaryValue());
59 event_params->SetInteger(name, value);
60 return event_params.Pass();
63 scoped_ptr<base::Value> NetLogInt64Callback(
64 const char* name,
65 int64 value,
66 NetLogCaptureMode /* capture_mode */) {
67 scoped_ptr<base::DictionaryValue> event_params(new base::DictionaryValue());
68 event_params->SetString(name, base::Int64ToString(value));
69 return event_params.Pass();
72 scoped_ptr<base::Value> NetLogStringCallback(
73 const char* name,
74 const std::string* value,
75 NetLogCaptureMode /* capture_mode */) {
76 scoped_ptr<base::DictionaryValue> event_params(new base::DictionaryValue());
77 event_params->SetString(name, *value);
78 return event_params.Pass();
81 scoped_ptr<base::Value> NetLogString16Callback(
82 const char* name,
83 const base::string16* value,
84 NetLogCaptureMode /* capture_mode */) {
85 scoped_ptr<base::DictionaryValue> event_params(new base::DictionaryValue());
86 event_params->SetString(name, *value);
87 return event_params.Pass();
90 } // namespace
92 // LoadTimingInfo requires this be 0.
93 const uint32 NetLog::Source::kInvalidId = 0;
95 NetLog::Source::Source() : type(SOURCE_NONE), id(kInvalidId) {
98 NetLog::Source::Source(SourceType type, uint32 id) : type(type), id(id) {
101 bool NetLog::Source::IsValid() const {
102 return id != kInvalidId;
105 void NetLog::Source::AddToEventParameters(
106 base::DictionaryValue* event_params) const {
107 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
108 dict->SetInteger("type", static_cast<int>(type));
109 dict->SetInteger("id", static_cast<int>(id));
110 event_params->Set("source_dependency", dict.Pass());
113 NetLog::ParametersCallback NetLog::Source::ToEventParametersCallback() const {
114 return base::Bind(&SourceEventParametersCallback, *this);
117 // static
118 bool NetLog::Source::FromEventParameters(base::Value* event_params,
119 Source* source) {
120 base::DictionaryValue* dict = NULL;
121 base::DictionaryValue* source_dict = NULL;
122 int source_id = -1;
123 int source_type = NetLog::SOURCE_COUNT;
124 if (!event_params || !event_params->GetAsDictionary(&dict) ||
125 !dict->GetDictionary("source_dependency", &source_dict) ||
126 !source_dict->GetInteger("id", &source_id) ||
127 !source_dict->GetInteger("type", &source_type)) {
128 *source = Source();
129 return false;
132 DCHECK_GE(source_id, 0);
133 DCHECK_LT(source_type, NetLog::SOURCE_COUNT);
134 *source = Source(static_cast<SourceType>(source_type), source_id);
135 return true;
138 base::Value* NetLog::Entry::ToValue() const {
139 scoped_ptr<base::DictionaryValue> entry_dict(new base::DictionaryValue());
141 entry_dict->SetString("time", TickCountToString(data_->time));
143 // Set the entry source.
144 scoped_ptr<base::DictionaryValue> source_dict(new base::DictionaryValue());
145 source_dict->SetInteger("id", data_->source.id);
146 source_dict->SetInteger("type", static_cast<int>(data_->source.type));
147 entry_dict->Set("source", source_dict.Pass());
149 // Set the event info.
150 entry_dict->SetInteger("type", static_cast<int>(data_->type));
151 entry_dict->SetInteger("phase", static_cast<int>(data_->phase));
153 // Set the event-specific parameters.
154 if (data_->parameters_callback) {
155 scoped_ptr<base::Value> value(
156 data_->parameters_callback->Run(capture_mode_));
157 if (value)
158 entry_dict->Set("params", value.Pass());
161 return entry_dict.release();
164 base::Value* NetLog::Entry::ParametersToValue() const {
165 if (data_->parameters_callback)
166 return data_->parameters_callback->Run(capture_mode_).release();
167 return NULL;
170 NetLog::EntryData::EntryData(EventType type,
171 Source source,
172 EventPhase phase,
173 base::TimeTicks time,
174 const ParametersCallback* parameters_callback)
175 : type(type),
176 source(source),
177 phase(phase),
178 time(time),
179 parameters_callback(parameters_callback) {
182 NetLog::EntryData::~EntryData() {
185 NetLog::Entry::Entry(const EntryData* data, NetLogCaptureMode capture_mode)
186 : data_(data), capture_mode_(capture_mode) {
189 NetLog::Entry::~Entry() {
192 NetLog::ThreadSafeObserver::ThreadSafeObserver() : net_log_(NULL) {
195 NetLog::ThreadSafeObserver::~ThreadSafeObserver() {
196 // Make sure we aren't watching a NetLog on destruction. Because the NetLog
197 // may pass events to each observer on multiple threads, we cannot safely
198 // stop watching a NetLog automatically from a parent class.
199 DCHECK(!net_log_);
202 NetLogCaptureMode NetLog::ThreadSafeObserver::capture_mode() const {
203 DCHECK(net_log_);
204 return capture_mode_;
207 NetLog* NetLog::ThreadSafeObserver::net_log() const {
208 return net_log_;
211 void NetLog::ThreadSafeObserver::OnAddEntryData(const EntryData& entry_data) {
212 OnAddEntry(Entry(&entry_data, capture_mode()));
215 NetLog::NetLog() : last_id_(0), is_capturing_(0) {
218 NetLog::~NetLog() {
221 void NetLog::AddGlobalEntry(EventType type) {
222 AddEntry(type, Source(NetLog::SOURCE_NONE, NextID()), NetLog::PHASE_NONE,
223 NULL);
226 void NetLog::AddGlobalEntry(
227 EventType type,
228 const NetLog::ParametersCallback& parameters_callback) {
229 AddEntry(type, Source(NetLog::SOURCE_NONE, NextID()), NetLog::PHASE_NONE,
230 &parameters_callback);
233 uint32 NetLog::NextID() {
234 return base::subtle::NoBarrier_AtomicIncrement(&last_id_, 1);
237 bool NetLog::IsCapturing() const {
238 return base::subtle::NoBarrier_Load(&is_capturing_) != 0;
241 void NetLog::DeprecatedAddObserver(NetLog::ThreadSafeObserver* observer,
242 NetLogCaptureMode capture_mode) {
243 base::AutoLock lock(lock_);
245 DCHECK(!observer->net_log_);
246 observers_.AddObserver(observer);
247 observer->net_log_ = this;
248 observer->capture_mode_ = capture_mode;
249 UpdateIsCapturing();
252 void NetLog::SetObserverCaptureMode(NetLog::ThreadSafeObserver* observer,
253 NetLogCaptureMode capture_mode) {
254 base::AutoLock lock(lock_);
256 DCHECK(observers_.HasObserver(observer));
257 DCHECK_EQ(this, observer->net_log_);
258 observer->capture_mode_ = capture_mode;
261 void NetLog::DeprecatedRemoveObserver(NetLog::ThreadSafeObserver* observer) {
262 base::AutoLock lock(lock_);
264 DCHECK(observers_.HasObserver(observer));
265 DCHECK_EQ(this, observer->net_log_);
266 observers_.RemoveObserver(observer);
267 observer->net_log_ = NULL;
268 observer->capture_mode_ = NetLogCaptureMode();
269 UpdateIsCapturing();
272 void NetLog::UpdateIsCapturing() {
273 lock_.AssertAcquired();
274 base::subtle::NoBarrier_Store(&is_capturing_,
275 observers_.might_have_observers() ? 1 : 0);
278 // static
279 std::string NetLog::TickCountToString(const base::TimeTicks& time) {
280 int64 delta_time = (time - base::TimeTicks()).InMilliseconds();
281 return base::Int64ToString(delta_time);
284 // static
285 const char* NetLog::EventTypeToString(EventType event) {
286 switch (event) {
287 #define EVENT_TYPE(label) \
288 case TYPE_##label: \
289 return #label;
290 #include "net/log/net_log_event_type_list.h"
291 #undef EVENT_TYPE
292 default:
293 NOTREACHED();
294 return NULL;
298 // static
299 base::Value* NetLog::GetEventTypesAsValue() {
300 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
301 for (int i = 0; i < EVENT_COUNT; ++i) {
302 dict->SetInteger(EventTypeToString(static_cast<EventType>(i)), i);
304 return dict.release();
307 // static
308 const char* NetLog::SourceTypeToString(SourceType source) {
309 switch (source) {
310 #define SOURCE_TYPE(label) \
311 case SOURCE_##label: \
312 return #label;
313 #include "net/log/net_log_source_type_list.h"
314 #undef SOURCE_TYPE
315 default:
316 NOTREACHED();
317 return NULL;
321 // static
322 base::Value* NetLog::GetSourceTypesAsValue() {
323 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
324 for (int i = 0; i < SOURCE_COUNT; ++i) {
325 dict->SetInteger(SourceTypeToString(static_cast<SourceType>(i)), i);
327 return dict.release();
330 // static
331 const char* NetLog::EventPhaseToString(EventPhase phase) {
332 switch (phase) {
333 case PHASE_BEGIN:
334 return "PHASE_BEGIN";
335 case PHASE_END:
336 return "PHASE_END";
337 case PHASE_NONE:
338 return "PHASE_NONE";
340 NOTREACHED();
341 return NULL;
344 // static
345 NetLog::ParametersCallback NetLog::BoolCallback(const char* name, bool value) {
346 return base::Bind(&NetLogBoolCallback, name, value);
349 // static
350 NetLog::ParametersCallback NetLog::IntegerCallback(const char* name,
351 int value) {
352 return base::Bind(&NetLogIntegerCallback, name, value);
355 // static
356 NetLog::ParametersCallback NetLog::Int64Callback(const char* name,
357 int64 value) {
358 return base::Bind(&NetLogInt64Callback, name, value);
361 // static
362 NetLog::ParametersCallback NetLog::StringCallback(const char* name,
363 const std::string* value) {
364 DCHECK(value);
365 return base::Bind(&NetLogStringCallback, name, value);
368 // static
369 NetLog::ParametersCallback NetLog::StringCallback(const char* name,
370 const base::string16* value) {
371 DCHECK(value);
372 return base::Bind(&NetLogString16Callback, name, value);
375 void NetLog::AddEntry(EventType type,
376 const Source& source,
377 EventPhase phase,
378 const NetLog::ParametersCallback* parameters_callback) {
379 if (!IsCapturing())
380 return;
381 EntryData entry_data(type, source, phase, base::TimeTicks::Now(),
382 parameters_callback);
384 // Notify all of the log observers.
385 base::AutoLock lock(lock_);
386 FOR_EACH_OBSERVER(ThreadSafeObserver, observers_, OnAddEntryData(entry_data));
389 BoundNetLog::~BoundNetLog() {
390 liveness_ = DEAD;
393 void BoundNetLog::AddEntry(NetLog::EventType type,
394 NetLog::EventPhase phase) const {
395 CrashIfInvalid();
397 if (!net_log_)
398 return;
399 net_log_->AddEntry(type, source_, phase, NULL);
402 void BoundNetLog::AddEntry(
403 NetLog::EventType type,
404 NetLog::EventPhase phase,
405 const NetLog::ParametersCallback& get_parameters) const {
406 CrashIfInvalid();
408 if (!net_log_)
409 return;
410 net_log_->AddEntry(type, source_, phase, &get_parameters);
413 void BoundNetLog::AddEvent(NetLog::EventType type) const {
414 AddEntry(type, NetLog::PHASE_NONE);
417 void BoundNetLog::AddEvent(
418 NetLog::EventType type,
419 const NetLog::ParametersCallback& get_parameters) const {
420 AddEntry(type, NetLog::PHASE_NONE, get_parameters);
423 void BoundNetLog::BeginEvent(NetLog::EventType type) const {
424 AddEntry(type, NetLog::PHASE_BEGIN);
427 void BoundNetLog::BeginEvent(
428 NetLog::EventType type,
429 const NetLog::ParametersCallback& get_parameters) const {
430 AddEntry(type, NetLog::PHASE_BEGIN, get_parameters);
433 void BoundNetLog::EndEvent(NetLog::EventType type) const {
434 AddEntry(type, NetLog::PHASE_END);
437 void BoundNetLog::EndEvent(
438 NetLog::EventType type,
439 const NetLog::ParametersCallback& get_parameters) const {
440 AddEntry(type, NetLog::PHASE_END, get_parameters);
443 void BoundNetLog::AddEventWithNetErrorCode(NetLog::EventType event_type,
444 int net_error) const {
445 DCHECK_NE(ERR_IO_PENDING, net_error);
446 if (net_error >= 0) {
447 AddEvent(event_type);
448 } else {
449 AddEvent(event_type, NetLog::IntegerCallback("net_error", net_error));
453 void BoundNetLog::EndEventWithNetErrorCode(NetLog::EventType event_type,
454 int net_error) const {
455 DCHECK_NE(ERR_IO_PENDING, net_error);
456 if (net_error >= 0) {
457 EndEvent(event_type);
458 } else {
459 EndEvent(event_type, NetLog::IntegerCallback("net_error", net_error));
463 void BoundNetLog::AddByteTransferEvent(NetLog::EventType event_type,
464 int byte_count,
465 const char* bytes) const {
466 AddEvent(event_type, base::Bind(BytesTransferredCallback, byte_count, bytes));
469 bool BoundNetLog::IsCapturing() const {
470 CrashIfInvalid();
471 return net_log_ && net_log_->IsCapturing();
474 // static
475 BoundNetLog BoundNetLog::Make(NetLog* net_log, NetLog::SourceType source_type) {
476 if (!net_log)
477 return BoundNetLog();
479 NetLog::Source source(source_type, net_log->NextID());
480 return BoundNetLog(source, net_log);
483 void BoundNetLog::CrashIfInvalid() const {
484 Liveness liveness = liveness_;
486 if (liveness == ALIVE)
487 return;
489 base::debug::Alias(&liveness);
490 CHECK_EQ(ALIVE, liveness);
493 } // namespace net