Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / base / net_log.cc
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 "net/base/net_log.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/time/time.h"
12 #include "base/values.h"
13 #include "net/base/net_errors.h"
14
15 namespace net {
16
17 namespace {
18
19 // Returns parameters for logging data transferred events. Includes number of
20 // bytes transferred and, if the log level indicates bytes should be logged and
21 // |byte_count| > 0, the bytes themselves.  The bytes are hex-encoded, since
22 // base::StringValue only supports UTF-8.
23 base::Value* BytesTransferredCallback(int byte_count,
24                                       const char* bytes,
25                                       NetLog::LogLevel log_level) {
26   base::DictionaryValue* dict = new base::DictionaryValue();
27   dict->SetInteger("byte_count", byte_count);
28   if (NetLog::IsLoggingBytes(log_level) && byte_count > 0)
29     dict->SetString("hex_encoded_bytes", base::HexEncode(bytes, byte_count));
30   return dict;
31 }
32
33 base::Value* SourceEventParametersCallback(const NetLog::Source source,
34                                            NetLog::LogLevel /* log_level */) {
35   if (!source.IsValid())
36     return NULL;
37   base::DictionaryValue* event_params = new base::DictionaryValue();
38   source.AddToEventParameters(event_params);
39   return event_params;
40 }
41
42 base::Value* NetLogIntegerCallback(const char* name,
43                                    int value,
44                                    NetLog::LogLevel /* log_level */) {
45   base::DictionaryValue* event_params = new base::DictionaryValue();
46   event_params->SetInteger(name, value);
47   return event_params;
48 }
49
50 base::Value* NetLogInt64Callback(const char* name,
51                                  int64 value,
52                                  NetLog::LogLevel /* log_level */) {
53   base::DictionaryValue* event_params = new base::DictionaryValue();
54   event_params->SetString(name, base::Int64ToString(value));
55   return event_params;
56 }
57
58 base::Value* NetLogStringCallback(const char* name,
59                                   const std::string* value,
60                                   NetLog::LogLevel /* log_level */) {
61   base::DictionaryValue* event_params = new base::DictionaryValue();
62   event_params->SetString(name, *value);
63   return event_params;
64 }
65
66 base::Value* NetLogString16Callback(const char* name,
67                                     const base::string16* value,
68                                     NetLog::LogLevel /* log_level */) {
69   base::DictionaryValue* event_params = new base::DictionaryValue();
70   event_params->SetString(name, *value);
71   return event_params;
72 }
73
74 }  // namespace
75
76 // LoadTimingInfo requires this be 0.
77 const uint32 NetLog::Source::kInvalidId = 0;
78
79 NetLog::Source::Source() : type(SOURCE_NONE), id(kInvalidId) {
80 }
81
82 NetLog::Source::Source(SourceType type, uint32 id) : type(type), id(id) {
83 }
84
85 bool NetLog::Source::IsValid() const {
86   return id != kInvalidId;
87 }
88
89 void NetLog::Source::AddToEventParameters(
90     base::DictionaryValue* event_params) const {
91   base::DictionaryValue* dict = new base::DictionaryValue();
92   dict->SetInteger("type", static_cast<int>(type));
93   dict->SetInteger("id", static_cast<int>(id));
94   event_params->Set("source_dependency", dict);
95 }
96
97 NetLog::ParametersCallback NetLog::Source::ToEventParametersCallback() const {
98   return base::Bind(&SourceEventParametersCallback, *this);
99 }
100
101 // static
102 bool NetLog::Source::FromEventParameters(base::Value* event_params,
103                                          Source* source) {
104   base::DictionaryValue* dict = NULL;
105   base::DictionaryValue* source_dict = NULL;
106   int source_id = -1;
107   int source_type = NetLog::SOURCE_COUNT;
108   if (!event_params ||
109       !event_params->GetAsDictionary(&dict) ||
110       !dict->GetDictionary("source_dependency", &source_dict) ||
111       !source_dict->GetInteger("id", &source_id) ||
112       !source_dict->GetInteger("type", &source_type)) {
113     *source = Source();
114     return false;
115   }
116
117   DCHECK_GE(source_id, 0);
118   DCHECK_LT(source_type, NetLog::SOURCE_COUNT);
119   *source = Source(static_cast<SourceType>(source_type), source_id);
120   return true;
121 }
122
123 base::Value* NetLog::Entry::ToValue() const {
124   base::DictionaryValue* entry_dict(new base::DictionaryValue());
125
126   entry_dict->SetString("time", TickCountToString(data_->time));
127
128   // Set the entry source.
129   base::DictionaryValue* source_dict = new base::DictionaryValue();
130   source_dict->SetInteger("id", data_->source.id);
131   source_dict->SetInteger("type", static_cast<int>(data_->source.type));
132   entry_dict->Set("source", source_dict);
133
134   // Set the event info.
135   entry_dict->SetInteger("type", static_cast<int>(data_->type));
136   entry_dict->SetInteger("phase", static_cast<int>(data_->phase));
137
138   // Set the event-specific parameters.
139   if (data_->parameters_callback) {
140     base::Value* value = data_->parameters_callback->Run(log_level_);
141     if (value)
142       entry_dict->Set("params", value);
143   }
144
145   return entry_dict;
146 }
147
148 base::Value* NetLog::Entry::ParametersToValue() const {
149   if (data_->parameters_callback)
150     return data_->parameters_callback->Run(log_level_);
151   return NULL;
152 }
153
154 NetLog::EntryData::EntryData(
155     EventType type,
156     Source source,
157     EventPhase phase,
158     base::TimeTicks time,
159     const ParametersCallback* parameters_callback)
160     : type(type),
161       source(source),
162       phase(phase),
163       time(time),
164       parameters_callback(parameters_callback) {
165 }
166
167 NetLog::EntryData::~EntryData() {
168 }
169
170 NetLog::Entry::Entry(const EntryData* data, LogLevel log_level)
171     : data_(data), log_level_(log_level) {
172 }
173
174 NetLog::Entry::~Entry() {
175 }
176
177 NetLog::ThreadSafeObserver::ThreadSafeObserver() : log_level_(LOG_NONE),
178                                                    net_log_(NULL) {
179 }
180
181 NetLog::ThreadSafeObserver::~ThreadSafeObserver() {
182   // Make sure we aren't watching a NetLog on destruction.  Because the NetLog
183   // may pass events to each observer on multiple threads, we cannot safely
184   // stop watching a NetLog automatically from a parent class.
185   DCHECK(!net_log_);
186 }
187
188 NetLog::LogLevel NetLog::ThreadSafeObserver::log_level() const {
189   DCHECK(net_log_);
190   return log_level_;
191 }
192
193 NetLog* NetLog::ThreadSafeObserver::net_log() const {
194   return net_log_;
195 }
196
197 void NetLog::ThreadSafeObserver::OnAddEntryData(const EntryData& entry_data) {
198   OnAddEntry(Entry(&entry_data, log_level()));
199 }
200
201 NetLog::NetLog() : last_id_(0), effective_log_level_(LOG_NONE) {
202 }
203
204 NetLog::~NetLog() {
205 }
206
207 void NetLog::AddGlobalEntry(EventType type) {
208   AddEntry(type,
209            Source(net::NetLog::SOURCE_NONE, NextID()),
210            net::NetLog::PHASE_NONE,
211            NULL);
212 }
213
214 void NetLog::AddGlobalEntry(
215     EventType type,
216     const NetLog::ParametersCallback& parameters_callback) {
217   AddEntry(type,
218            Source(net::NetLog::SOURCE_NONE, NextID()),
219            net::NetLog::PHASE_NONE,
220            &parameters_callback);
221 }
222
223 uint32 NetLog::NextID() {
224   return base::subtle::NoBarrier_AtomicIncrement(&last_id_, 1);
225 }
226
227 NetLog::LogLevel NetLog::GetLogLevel() const {
228   base::subtle::Atomic32 log_level =
229       base::subtle::NoBarrier_Load(&effective_log_level_);
230   return static_cast<net::NetLog::LogLevel>(log_level);
231 }
232
233 void NetLog::AddThreadSafeObserver(
234     net::NetLog::ThreadSafeObserver* observer,
235     LogLevel log_level) {
236   DCHECK_NE(LOG_NONE, log_level);
237   base::AutoLock lock(lock_);
238
239   DCHECK(!observer->net_log_);
240   DCHECK_EQ(LOG_NONE, observer->log_level_);
241   observers_.AddObserver(observer);
242   observer->net_log_ = this;
243   observer->log_level_ = log_level;
244   UpdateLogLevel();
245 }
246
247 void NetLog::SetObserverLogLevel(
248     net::NetLog::ThreadSafeObserver* observer,
249     LogLevel log_level) {
250   DCHECK_NE(LOG_NONE, log_level);
251   base::AutoLock lock(lock_);
252
253   DCHECK(observers_.HasObserver(observer));
254   DCHECK_EQ(this, observer->net_log_);
255   DCHECK_NE(LOG_NONE, observer->log_level_);
256   observer->log_level_ = log_level;
257   UpdateLogLevel();
258 }
259
260 void NetLog::RemoveThreadSafeObserver(
261     net::NetLog::ThreadSafeObserver* observer) {
262   base::AutoLock lock(lock_);
263
264   DCHECK(observers_.HasObserver(observer));
265   DCHECK_EQ(this, observer->net_log_);
266   DCHECK_NE(LOG_NONE, observer->log_level_);
267   observers_.RemoveObserver(observer);
268   observer->net_log_ = NULL;
269   observer->log_level_ = LOG_NONE;
270   UpdateLogLevel();
271 }
272
273 void NetLog::UpdateLogLevel() {
274   lock_.AssertAcquired();
275
276   // Look through all the observers and find the finest granularity
277   // log level (higher values of the enum imply *lower* log levels).
278   LogLevel new_effective_log_level = LOG_NONE;
279   ObserverListBase<ThreadSafeObserver>::Iterator it(observers_);
280   ThreadSafeObserver* observer;
281   while ((observer = it.GetNext()) != NULL) {
282     new_effective_log_level =
283         std::min(new_effective_log_level, observer->log_level());
284   }
285   base::subtle::NoBarrier_Store(&effective_log_level_,
286                                 new_effective_log_level);
287 }
288
289 // static
290 std::string NetLog::TickCountToString(const base::TimeTicks& time) {
291   int64 delta_time = (time - base::TimeTicks()).InMilliseconds();
292   return base::Int64ToString(delta_time);
293 }
294
295 // static
296 const char* NetLog::EventTypeToString(EventType event) {
297   switch (event) {
298 #define EVENT_TYPE(label) case TYPE_ ## label: return #label;
299 #include "net/base/net_log_event_type_list.h"
300 #undef EVENT_TYPE
301     default:
302       NOTREACHED();
303       return NULL;
304   }
305 }
306
307 // static
308 base::Value* NetLog::GetEventTypesAsValue() {
309   base::DictionaryValue* dict = new base::DictionaryValue();
310   for (int i = 0; i < EVENT_COUNT; ++i) {
311     dict->SetInteger(EventTypeToString(static_cast<EventType>(i)), i);
312   }
313   return dict;
314 }
315
316 // static
317 const char* NetLog::SourceTypeToString(SourceType source) {
318   switch (source) {
319 #define SOURCE_TYPE(label) case SOURCE_ ## label: return #label;
320 #include "net/base/net_log_source_type_list.h"
321 #undef SOURCE_TYPE
322     default:
323       NOTREACHED();
324       return NULL;
325   }
326 }
327
328 // static
329 base::Value* NetLog::GetSourceTypesAsValue() {
330   base::DictionaryValue* dict = new base::DictionaryValue();
331   for (int i = 0; i < SOURCE_COUNT; ++i) {
332     dict->SetInteger(SourceTypeToString(static_cast<SourceType>(i)), i);
333   }
334   return dict;
335 }
336
337 // static
338 const char* NetLog::EventPhaseToString(EventPhase phase) {
339   switch (phase) {
340     case PHASE_BEGIN:
341       return "PHASE_BEGIN";
342     case PHASE_END:
343       return "PHASE_END";
344     case PHASE_NONE:
345       return "PHASE_NONE";
346   }
347   NOTREACHED();
348   return NULL;
349 }
350
351 // static
352 bool NetLog::IsLoggingBytes(LogLevel log_level) {
353   return log_level == NetLog::LOG_ALL;
354 }
355
356 // static
357 bool NetLog::IsLogging(LogLevel log_level) {
358   return log_level < NetLog::LOG_NONE;
359 }
360
361 // static
362 NetLog::ParametersCallback NetLog::IntegerCallback(const char* name,
363                                                    int value) {
364   return base::Bind(&NetLogIntegerCallback, name, value);
365 }
366
367 // static
368 NetLog::ParametersCallback NetLog::Int64Callback(const char* name,
369                                                  int64 value) {
370   return base::Bind(&NetLogInt64Callback, name, value);
371 }
372
373 // static
374 NetLog::ParametersCallback NetLog::StringCallback(const char* name,
375                                                   const std::string* value) {
376   DCHECK(value);
377   return base::Bind(&NetLogStringCallback, name, value);
378 }
379
380 // static
381 NetLog::ParametersCallback NetLog::StringCallback(const char* name,
382                                                   const base::string16* value) {
383   DCHECK(value);
384   return base::Bind(&NetLogString16Callback, name, value);
385 }
386
387 void NetLog::AddEntry(EventType type,
388                       const Source& source,
389                       EventPhase phase,
390                       const NetLog::ParametersCallback* parameters_callback) {
391   if (GetLogLevel() == LOG_NONE)
392     return;
393   EntryData entry_data(type, source, phase, base::TimeTicks::Now(),
394                        parameters_callback);
395
396   // Notify all of the log observers.
397   base::AutoLock lock(lock_);
398   FOR_EACH_OBSERVER(ThreadSafeObserver, observers_, OnAddEntryData(entry_data));
399 }
400
401 void BoundNetLog::AddEntry(NetLog::EventType type,
402                            NetLog::EventPhase phase) const {
403   if (!net_log_)
404     return;
405   net_log_->AddEntry(type, source_, phase, NULL);
406 }
407
408 void BoundNetLog::AddEntry(
409     NetLog::EventType type,
410     NetLog::EventPhase phase,
411     const NetLog::ParametersCallback& get_parameters) const {
412   if (!net_log_)
413     return;
414   net_log_->AddEntry(type, source_, phase, &get_parameters);
415 }
416
417 void BoundNetLog::AddEvent(NetLog::EventType type) const {
418   AddEntry(type, NetLog::PHASE_NONE);
419 }
420
421 void BoundNetLog::AddEvent(
422     NetLog::EventType type,
423     const NetLog::ParametersCallback& get_parameters) const {
424   AddEntry(type, NetLog::PHASE_NONE, get_parameters);
425 }
426
427 void BoundNetLog::BeginEvent(NetLog::EventType type) const {
428   AddEntry(type, NetLog::PHASE_BEGIN);
429 }
430
431 void BoundNetLog::BeginEvent(
432     NetLog::EventType type,
433     const NetLog::ParametersCallback& get_parameters) const {
434   AddEntry(type, NetLog::PHASE_BEGIN, get_parameters);
435 }
436
437 void BoundNetLog::EndEvent(NetLog::EventType type) const {
438   AddEntry(type, NetLog::PHASE_END);
439 }
440
441 void BoundNetLog::EndEvent(
442     NetLog::EventType type,
443     const NetLog::ParametersCallback& get_parameters) const {
444   AddEntry(type, NetLog::PHASE_END, get_parameters);
445 }
446
447 void BoundNetLog::AddEventWithNetErrorCode(NetLog::EventType event_type,
448                                            int net_error) const {
449   DCHECK_NE(ERR_IO_PENDING, net_error);
450   if (net_error >= 0) {
451     AddEvent(event_type);
452   } else {
453     AddEvent(event_type, NetLog::IntegerCallback("net_error", net_error));
454   }
455 }
456
457 void BoundNetLog::EndEventWithNetErrorCode(NetLog::EventType event_type,
458                                            int net_error) const {
459   DCHECK_NE(ERR_IO_PENDING, net_error);
460   if (net_error >= 0) {
461     EndEvent(event_type);
462   } else {
463     EndEvent(event_type, NetLog::IntegerCallback("net_error", net_error));
464   }
465 }
466
467 void BoundNetLog::AddByteTransferEvent(NetLog::EventType event_type,
468                                        int byte_count,
469                                        const char* bytes) const {
470   AddEvent(event_type, base::Bind(BytesTransferredCallback, byte_count, bytes));
471 }
472
473 NetLog::LogLevel BoundNetLog::GetLogLevel() const {
474   if (net_log_)
475     return net_log_->GetLogLevel();
476   return NetLog::LOG_NONE;
477 }
478
479 bool BoundNetLog::IsLoggingBytes() const {
480   return NetLog::IsLoggingBytes(GetLogLevel());
481 }
482
483 bool BoundNetLog::IsLogging() const {
484   return NetLog::IsLogging(GetLogLevel());
485 }
486
487 // static
488 BoundNetLog BoundNetLog::Make(NetLog* net_log,
489                               NetLog::SourceType source_type) {
490   if (!net_log)
491     return BoundNetLog();
492
493   NetLog::Source source(source_type, net_log->NextID());
494   return BoundNetLog(source, net_log);
495 }
496
497 }  // namespace net