// Copyright (c) 2011 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.
#ifndef NET_BASE_NET_LOG_H_
#define NET_BASE_NET_LOG_H_
#pragma once
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
class Value;
namespace base {
class TimeTicks;
}
namespace net {
// NetLog is the destination for log messages generated by the network stack.
// Each log message has a "source" field which identifies the specific entity
// that generated the message (for example, which URLRequest or which
// SocketStream).
//
// To avoid needing to pass in the "source id" to the logging functions, NetLog
// is usually accessed through a BoundNetLog, which will always pass in a
// specific source ID.
//
// ******** The NetLog (and associated logging) is a work in progress ********
//
// TODO(eroman): Remove the 'const' qualitifer from the BoundNetLog methods.
// TODO(eroman): Start a new Source each time URLRequest redirects
// (simpler to reason about each as a separate entity).
class NetLog {
public:
enum EventType {
#define EVENT_TYPE(label) TYPE_ ## label,
#include "net/base/net_log_event_type_list.h"
#undef EVENT_TYPE
};
// The 'phase' of an event trace (whether it marks the beginning or end
// of an event.).
enum EventPhase {
PHASE_NONE,
PHASE_BEGIN,
PHASE_END,
};
// The "source" identifies the entity that generated the log message.
enum SourceType {
#define SOURCE_TYPE(label, value) SOURCE_ ## label = value,
#include "net/base/net_log_source_type_list.h"
#undef SOURCE_TYPE
};
// Identifies the entity that generated this log. The |id| field should
// uniquely identify the source, and is used by log observers to infer
// message groupings. Can use NetLog::NextID() to create unique IDs.
struct Source {
static const uint32 kInvalidId = 0;
Source() : type(SOURCE_NONE), id(kInvalidId) {}
Source(SourceType type, uint32 id) : type(type), id(id) {}
bool is_valid() const { return id != kInvalidId; }
// The caller takes ownership of the returned Value*.
Value* ToValue() const;
SourceType type;
uint32 id;
};
// Base class for associating additional parameters with an event. Log
// observers need to know what specific derivations of EventParameters a
// particular EventType uses, in order to get at the individual components.
class EventParameters : public base::RefCountedThreadSafe<EventParameters> {
public:
EventParameters() {}
virtual ~EventParameters() {}
// Serializes the parameters to a Value tree. This is intended to be a
// lossless conversion, which is used to serialize the parameters to JSON.
// The caller takes ownership of the returned Value*.
virtual Value* ToValue() const = 0;
private:
DISALLOW_COPY_AND_ASSIGN(EventParameters);
};
// Specifies the granularity of events that should be emitted to the log.
enum LogLevel {
// Log everything possible, even if it is slow and memory expensive.
// Includes logging of transferred bytes.
LOG_ALL,
// Log all events, but do not include the actual transferred bytes as
// parameters for bytes sent/received events.
LOG_ALL_BUT_BYTES,
// Only log events which are cheap, and don't consume much memory.
LOG_BASIC,
};
NetLog() {}
virtual ~NetLog() {}
// Emits an event to the log stream.
// |type| - The type of the event.
// |time| - The time when the event occurred.
// |source| - The source that generated the event.
// |phase| - An optional parameter indicating whether this is the start/end
// of an action.
// |params| - Optional (may be NULL) parameters for this event.
// The specific subclass of EventParameters is defined
// by the contract for events of this |type|.
// TODO(eroman): Take a scoped_refptr<> instead.
virtual void AddEntry(EventType type,
const base::TimeTicks& time,
const Source& source,
EventPhase phase,
EventParameters* params) = 0;
// Returns a unique ID which can be used as a source ID.
virtual uint32 NextID() = 0;
// Returns the logging level for this NetLog. This is used to avoid computing
// and saving expensive log entries.
virtual LogLevel GetLogLevel() const = 0;
// Converts a time to the string format that the NetLog uses to represent
// times. Strings are used since integers may overflow.
static std::string TickCountToString(const base::TimeTicks& time);
// Returns a C-String symbolic name for |event_type|.
static const char* EventTypeToString(EventType event_type);
// Returns a list of all the available EventTypes.
static std::vector<EventType> GetAllEventTypes();
// Returns a C-String symbolic name for |source_type|.
static const char* SourceTypeToString(SourceType source_type);
// Returns a C-String symbolic name for |event_phase|.
static const char* EventPhaseToString(EventPhase event_phase);
// Serializes the specified event to a DictionaryValue.
// If |use_strings| is true, uses strings rather than numeric ids.
static Value* EntryToDictionaryValue(NetLog::EventType type,
const base::TimeTicks& time,
const NetLog::Source& source,
NetLog::EventPhase phase,
NetLog::EventParameters* params,
bool use_strings);
private:
DISALLOW_COPY_AND_ASSIGN(NetLog);
};
// Helper that binds a Source to a NetLog, and exposes convenience methods to
// output log messages without needing to pass in the source.
class BoundNetLog {
public:
BoundNetLog() : net_log_(NULL) {}
BoundNetLog(const NetLog::Source& source, NetLog* net_log)
: source_(source), net_log_(net_log) {
}
// Convenience methods that call through to the NetLog, passing in the
// currently bound source.
void AddEntry(NetLog::EventType type,
NetLog::EventPhase phase,
const scoped_refptr<NetLog::EventParameters>& params) const;
void AddEntryWithTime(
NetLog::EventType type,
const base::TimeTicks& time,
NetLog::EventPhase phase,
const scoped_refptr<NetLog::EventParameters>& params) const;
// Convenience methods that call through to the NetLog, passing in the
// currently bound source, current time, and a fixed "capture phase"
// (begin, end, or none).
void AddEvent(NetLog::EventType event_type,
const scoped_refptr<NetLog::EventParameters>& params) const;
void BeginEvent(NetLog::EventType event_type,
const scoped_refptr<NetLog::EventParameters>& params) const;
void EndEvent(NetLog::EventType event_type,
const scoped_refptr<NetLog::EventParameters>& params) const;
// Just like EndEvent, except |net_error| is a net error code. If it's
// negative, a parameter called "net_error" with a value of |net_error| is
// associated with the event. Otherwise, the end event has no parameters.
// |net_error| must not be ERR_IO_PENDING, as it's not a true error.
void EndEventWithNetErrorCode(NetLog::EventType event_type,
int net_error) const;
NetLog::LogLevel GetLogLevel() const;
// Returns true if the log level is LOG_ALL.
bool IsLoggingBytes() const;
// Returns true if the log level is LOG_ALL or LOG_ALL_BUT_BYTES.
bool IsLoggingAllEvents() const;
// Helper to create a BoundNetLog given a NetLog and a SourceType. Takes care
// of creating a unique source ID, and handles the case of NULL net_log.
static BoundNetLog Make(NetLog* net_log, NetLog::SourceType source_type);
const NetLog::Source& source() const { return source_; }
NetLog* net_log() const { return net_log_; }
private:
NetLog::Source source_;
NetLog* net_log_;
};
// NetLogStringParameter is a subclass of EventParameters that encapsulates a
// single std::string parameter.
class NetLogStringParameter : public NetLog::EventParameters {
public:
// |name| must be a string literal.
NetLogStringParameter(const char* name, const std::string& value);
virtual ~NetLogStringParameter();
const std::string& value() const {
return value_;
}
virtual Value* ToValue() const;
private:
const char* const name_;
const std::string value_;
};
// NetLogIntegerParameter is a subclass of EventParameters that encapsulates a
// single integer parameter.
class NetLogIntegerParameter : public NetLog::EventParameters {
public:
// |name| must be a string literal.
NetLogIntegerParameter(const char* name, int value)
: name_(name), value_(value) {}
int value() const {
return value_;
}
virtual Value* ToValue() const;
private:
const char* name_;
const int value_;
};
// NetLogSourceParameter is a subclass of EventParameters that encapsulates a
// single NetLog::Source parameter.
class NetLogSourceParameter : public NetLog::EventParameters {
public:
// |name| must be a string literal.
NetLogSourceParameter(const char* name, const NetLog::Source& value)
: name_(name), value_(value) {}
const NetLog::Source& value() const {
return value_;
}
virtual Value* ToValue() const;
private:
const char* name_;
const NetLog::Source value_;
};
// ScopedNetLogEvent logs a begin event on creation, and the corresponding end
// event on destruction.
class ScopedNetLogEvent {
public:
ScopedNetLogEvent(const BoundNetLog& net_log,
NetLog::EventType event_type,
const scoped_refptr<NetLog::EventParameters>& params);
~ScopedNetLogEvent();
// Sets the parameters that will logged on object destruction. Can be called
// at most once for a given ScopedNetLogEvent object. If not called, the end
// event will have no parameters.
void SetEndEventParameters(
const scoped_refptr<NetLog::EventParameters>& end_event_params);
const BoundNetLog& net_log() const;
private:
BoundNetLog net_log_;
const NetLog::EventType event_type_;
scoped_refptr<NetLog::EventParameters> end_event_params_;
};
} // namespace net
#endif // NET_BASE_NET_LOG_H_