1// Copyright (c) 2011 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#ifndef NET_BASE_NET_LOG_H_
6#define NET_BASE_NET_LOG_H_
7#pragma once
8
9#include <string>
10#include <vector>
11
12#include "base/basictypes.h"
13#include "base/memory/ref_counted.h"
14
15class Value;
16
17namespace base {
18class TimeTicks;
19}
20
21namespace net {
22
23// NetLog is the destination for log messages generated by the network stack.
24// Each log message has a "source" field which identifies the specific entity
25// that generated the message (for example, which URLRequest or which
26// SocketStream).
27//
28// To avoid needing to pass in the "source id" to the logging functions, NetLog
29// is usually accessed through a BoundNetLog, which will always pass in a
30// specific source ID.
31//
32// ******** The NetLog (and associated logging) is a work in progress ********
33//
34// TODO(eroman): Remove the 'const' qualitifer from the BoundNetLog methods.
35// TODO(eroman): Start a new Source each time URLRequest redirects
36//               (simpler to reason about each as a separate entity).
37
38class NetLog {
39 public:
40  enum EventType {
41#define EVENT_TYPE(label) TYPE_ ## label,
42#include "net/base/net_log_event_type_list.h"
43#undef EVENT_TYPE
44  };
45
46  // The 'phase' of an event trace (whether it marks the beginning or end
47  // of an event.).
48  enum EventPhase {
49    PHASE_NONE,
50    PHASE_BEGIN,
51    PHASE_END,
52  };
53
54  // The "source" identifies the entity that generated the log message.
55  enum SourceType {
56#define SOURCE_TYPE(label, value) SOURCE_ ## label = value,
57#include "net/base/net_log_source_type_list.h"
58#undef SOURCE_TYPE
59  };
60
61  // Identifies the entity that generated this log. The |id| field should
62  // uniquely identify the source, and is used by log observers to infer
63  // message groupings. Can use NetLog::NextID() to create unique IDs.
64  struct Source {
65    static const uint32 kInvalidId = 0;
66
67    Source() : type(SOURCE_NONE), id(kInvalidId) {}
68    Source(SourceType type, uint32 id) : type(type), id(id) {}
69    bool is_valid() const { return id != kInvalidId; }
70
71    // The caller takes ownership of the returned Value*.
72    Value* ToValue() const;
73
74    SourceType type;
75    uint32 id;
76  };
77
78  // Base class for associating additional parameters with an event. Log
79  // observers need to know what specific derivations of EventParameters a
80  // particular EventType uses, in order to get at the individual components.
81  class EventParameters : public base::RefCountedThreadSafe<EventParameters> {
82   public:
83    EventParameters() {}
84    virtual ~EventParameters() {}
85
86    // Serializes the parameters to a Value tree. This is intended to be a
87    // lossless conversion, which is used to serialize the parameters to JSON.
88    // The caller takes ownership of the returned Value*.
89    virtual Value* ToValue() const = 0;
90
91   private:
92    DISALLOW_COPY_AND_ASSIGN(EventParameters);
93  };
94
95  // Specifies the granularity of events that should be emitted to the log.
96  enum LogLevel {
97    // Log everything possible, even if it is slow and memory expensive.
98    // Includes logging of transferred bytes.
99    LOG_ALL,
100
101    // Log all events, but do not include the actual transferred bytes as
102    // parameters for bytes sent/received events.
103    LOG_ALL_BUT_BYTES,
104
105    // Only log events which are cheap, and don't consume much memory.
106    LOG_BASIC,
107  };
108
109  NetLog() {}
110  virtual ~NetLog() {}
111
112  // Emits an event to the log stream.
113  //  |type| - The type of the event.
114  //  |time| - The time when the event occurred.
115  //  |source| - The source that generated the event.
116  //  |phase| - An optional parameter indicating whether this is the start/end
117  //            of an action.
118  //  |params| - Optional (may be NULL) parameters for this event.
119  //             The specific subclass of EventParameters is defined
120  //             by the contract for events of this |type|.
121  //             TODO(eroman): Take a scoped_refptr<> instead.
122  virtual void AddEntry(EventType type,
123                        const base::TimeTicks& time,
124                        const Source& source,
125                        EventPhase phase,
126                        EventParameters* params) = 0;
127
128  // Returns a unique ID which can be used as a source ID.
129  virtual uint32 NextID() = 0;
130
131  // Returns the logging level for this NetLog. This is used to avoid computing
132  // and saving expensive log entries.
133  virtual LogLevel GetLogLevel() const = 0;
134
135  // Converts a time to the string format that the NetLog uses to represent
136  // times.  Strings are used since integers may overflow.
137  static std::string TickCountToString(const base::TimeTicks& time);
138
139  // Returns a C-String symbolic name for |event_type|.
140  static const char* EventTypeToString(EventType event_type);
141
142  // Returns a list of all the available EventTypes.
143  static std::vector<EventType> GetAllEventTypes();
144
145  // Returns a C-String symbolic name for |source_type|.
146  static const char* SourceTypeToString(SourceType source_type);
147
148  // Returns a C-String symbolic name for |event_phase|.
149  static const char* EventPhaseToString(EventPhase event_phase);
150
151  // Serializes the specified event to a DictionaryValue.
152  // If |use_strings| is true, uses strings rather than numeric ids.
153  static Value* EntryToDictionaryValue(NetLog::EventType type,
154                                       const base::TimeTicks& time,
155                                       const NetLog::Source& source,
156                                       NetLog::EventPhase phase,
157                                       NetLog::EventParameters* params,
158                                       bool use_strings);
159
160 private:
161  DISALLOW_COPY_AND_ASSIGN(NetLog);
162};
163
164// Helper that binds a Source to a NetLog, and exposes convenience methods to
165// output log messages without needing to pass in the source.
166class BoundNetLog {
167 public:
168  BoundNetLog() : net_log_(NULL) {}
169
170  BoundNetLog(const NetLog::Source& source, NetLog* net_log)
171      : source_(source), net_log_(net_log) {
172  }
173
174  // Convenience methods that call through to the NetLog, passing in the
175  // currently bound source.
176  void AddEntry(NetLog::EventType type,
177                NetLog::EventPhase phase,
178                const scoped_refptr<NetLog::EventParameters>& params) const;
179
180  void AddEntryWithTime(
181      NetLog::EventType type,
182      const base::TimeTicks& time,
183      NetLog::EventPhase phase,
184      const scoped_refptr<NetLog::EventParameters>& params) const;
185
186  // Convenience methods that call through to the NetLog, passing in the
187  // currently bound source, current time, and a fixed "capture phase"
188  // (begin, end, or none).
189  void AddEvent(NetLog::EventType event_type,
190                const scoped_refptr<NetLog::EventParameters>& params) const;
191  void BeginEvent(NetLog::EventType event_type,
192                  const scoped_refptr<NetLog::EventParameters>& params) const;
193  void EndEvent(NetLog::EventType event_type,
194                const scoped_refptr<NetLog::EventParameters>& params) const;
195
196  // Just like EndEvent, except |net_error| is a net error code.  If it's
197  // negative, a parameter called "net_error" with a value of |net_error| is
198  // associated with the event.  Otherwise, the end event has no parameters.
199  // |net_error| must not be ERR_IO_PENDING, as it's not a true error.
200  void EndEventWithNetErrorCode(NetLog::EventType event_type,
201                                int net_error) const;
202
203  NetLog::LogLevel GetLogLevel() const;
204
205  // Returns true if the log level is LOG_ALL.
206  bool IsLoggingBytes() const;
207
208  // Returns true if the log level is LOG_ALL or LOG_ALL_BUT_BYTES.
209  bool IsLoggingAllEvents() const;
210
211  // Helper to create a BoundNetLog given a NetLog and a SourceType. Takes care
212  // of creating a unique source ID, and handles the case of NULL net_log.
213  static BoundNetLog Make(NetLog* net_log, NetLog::SourceType source_type);
214
215  const NetLog::Source& source() const { return source_; }
216  NetLog* net_log() const { return net_log_; }
217
218 private:
219  NetLog::Source source_;
220  NetLog* net_log_;
221};
222
223// NetLogStringParameter is a subclass of EventParameters that encapsulates a
224// single std::string parameter.
225class NetLogStringParameter : public NetLog::EventParameters {
226 public:
227  // |name| must be a string literal.
228  NetLogStringParameter(const char* name, const std::string& value);
229  virtual ~NetLogStringParameter();
230
231  const std::string& value() const {
232    return value_;
233  }
234
235  virtual Value* ToValue() const;
236
237 private:
238  const char* const name_;
239  const std::string value_;
240};
241
242// NetLogIntegerParameter is a subclass of EventParameters that encapsulates a
243// single integer parameter.
244class NetLogIntegerParameter : public NetLog::EventParameters {
245 public:
246  // |name| must be a string literal.
247  NetLogIntegerParameter(const char* name, int value)
248      : name_(name), value_(value) {}
249
250  int value() const {
251    return value_;
252  }
253
254  virtual Value* ToValue() const;
255
256 private:
257  const char* name_;
258  const int value_;
259};
260
261// NetLogSourceParameter is a subclass of EventParameters that encapsulates a
262// single NetLog::Source parameter.
263class NetLogSourceParameter : public NetLog::EventParameters {
264 public:
265  // |name| must be a string literal.
266  NetLogSourceParameter(const char* name, const NetLog::Source& value)
267      : name_(name), value_(value) {}
268
269  const NetLog::Source& value() const {
270    return value_;
271  }
272
273  virtual Value* ToValue() const;
274
275 private:
276  const char* name_;
277  const NetLog::Source value_;
278};
279
280// ScopedNetLogEvent logs a begin event on creation, and the corresponding end
281// event on destruction.
282class ScopedNetLogEvent {
283 public:
284  ScopedNetLogEvent(const BoundNetLog& net_log,
285                    NetLog::EventType event_type,
286                    const scoped_refptr<NetLog::EventParameters>& params);
287
288  ~ScopedNetLogEvent();
289
290  // Sets the parameters that will logged on object destruction.  Can be called
291  // at most once for a given ScopedNetLogEvent object.  If not called, the end
292  // event will have no parameters.
293  void SetEndEventParameters(
294      const scoped_refptr<NetLog::EventParameters>& end_event_params);
295
296  const BoundNetLog& net_log() const;
297
298 private:
299  BoundNetLog net_log_;
300  const NetLog::EventType event_type_;
301  scoped_refptr<NetLog::EventParameters> end_event_params_;
302};
303
304}  // namespace net
305
306#endif  // NET_BASE_NET_LOG_H_
307