1 // Copyright 2016 The Chromium Authors
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/log/net_log_with_source.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "base/check_op.h"
11 #include "base/no_destructor.h"
12 #include "base/values.h"
13 #include "net/base/net_errors.h"
14 #include "net/log/net_log.h"
15 #include "net/log/net_log_capture_mode.h"
16 #include "net/log/net_log_values.h"
17
18 namespace net {
19
20 namespace {
21
22 // Returns parameters for logging data transferred events. At a minimum includes
23 // the number of bytes transferred. If the capture mode allows logging byte
24 // contents and |byte_count| > 0, then will include the actual bytes.
BytesTransferredParams(int byte_count,const char * bytes,NetLogCaptureMode capture_mode)25 base::Value::Dict BytesTransferredParams(int byte_count,
26 const char* bytes,
27 NetLogCaptureMode capture_mode) {
28 base::Value::Dict dict;
29 dict.Set("byte_count", byte_count);
30 if (NetLogCaptureIncludesSocketBytes(capture_mode) && byte_count > 0)
31 dict.Set("bytes", NetLogBinaryValue(bytes, byte_count));
32 return dict;
33 }
34
35 } // namespace
36
NetLogWithSource()37 NetLogWithSource::NetLogWithSource() {
38 // Conceptually, default NetLogWithSource have no NetLog*, and will return
39 // nullptr when calling |net_log()|. However for performance reasons, we
40 // always store a non-null member to the NetLog in order to avoid needing
41 // null checks for critical codepaths.
42 //
43 // The "dummy" net log used here will always return false for IsCapturing(),
44 // and have no sideffects should its method be called. In practice the only
45 // method that will get called on it is IsCapturing().
46 static base::NoDestructor<NetLog> dummy{base::PassKey<NetLogWithSource>()};
47 DCHECK(!dummy->IsCapturing());
48 non_null_net_log_ = dummy.get();
49 }
50
51 NetLogWithSource::~NetLogWithSource() = default;
52
AddEntry(NetLogEventType type,NetLogEventPhase phase) const53 void NetLogWithSource::AddEntry(NetLogEventType type,
54 NetLogEventPhase phase) const {
55 non_null_net_log_->AddEntry(type, source_, phase);
56 }
57
AddEvent(NetLogEventType type) const58 void NetLogWithSource::AddEvent(NetLogEventType type) const {
59 AddEntry(type, NetLogEventPhase::NONE);
60 }
61
AddEventWithStringParams(NetLogEventType type,base::StringPiece name,base::StringPiece value) const62 void NetLogWithSource::AddEventWithStringParams(NetLogEventType type,
63 base::StringPiece name,
64 base::StringPiece value) const {
65 AddEvent(type, [&] { return NetLogParamsWithString(name, value); });
66 }
67
AddEventWithIntParams(NetLogEventType type,base::StringPiece name,int value) const68 void NetLogWithSource::AddEventWithIntParams(NetLogEventType type,
69 base::StringPiece name,
70 int value) const {
71 AddEvent(type, [&] { return NetLogParamsWithInt(name, value); });
72 }
73
BeginEventWithIntParams(NetLogEventType type,base::StringPiece name,int value) const74 void NetLogWithSource::BeginEventWithIntParams(NetLogEventType type,
75 base::StringPiece name,
76 int value) const {
77 BeginEvent(type, [&] { return NetLogParamsWithInt(name, value); });
78 }
79
EndEventWithIntParams(NetLogEventType type,base::StringPiece name,int value) const80 void NetLogWithSource::EndEventWithIntParams(NetLogEventType type,
81 base::StringPiece name,
82 int value) const {
83 EndEvent(type, [&] { return NetLogParamsWithInt(name, value); });
84 }
85
AddEventWithInt64Params(NetLogEventType type,base::StringPiece name,int64_t value) const86 void NetLogWithSource::AddEventWithInt64Params(NetLogEventType type,
87 base::StringPiece name,
88 int64_t value) const {
89 AddEvent(type, [&] { return NetLogParamsWithInt64(name, value); });
90 }
91
BeginEventWithStringParams(NetLogEventType type,base::StringPiece name,base::StringPiece value) const92 void NetLogWithSource::BeginEventWithStringParams(
93 NetLogEventType type,
94 base::StringPiece name,
95 base::StringPiece value) const {
96 BeginEvent(type, [&] { return NetLogParamsWithString(name, value); });
97 }
98
AddEventReferencingSource(NetLogEventType type,const NetLogSource & source) const99 void NetLogWithSource::AddEventReferencingSource(
100 NetLogEventType type,
101 const NetLogSource& source) const {
102 AddEvent(type, [&] { return source.ToEventParameters(); });
103 }
104
BeginEventReferencingSource(NetLogEventType type,const NetLogSource & source) const105 void NetLogWithSource::BeginEventReferencingSource(
106 NetLogEventType type,
107 const NetLogSource& source) const {
108 BeginEvent(type, [&] { return source.ToEventParameters(); });
109 }
110
BeginEvent(NetLogEventType type) const111 void NetLogWithSource::BeginEvent(NetLogEventType type) const {
112 AddEntry(type, NetLogEventPhase::BEGIN);
113 }
114
EndEvent(NetLogEventType type) const115 void NetLogWithSource::EndEvent(NetLogEventType type) const {
116 AddEntry(type, NetLogEventPhase::END);
117 }
118
AddEventWithNetErrorCode(NetLogEventType event_type,int net_error) const119 void NetLogWithSource::AddEventWithNetErrorCode(NetLogEventType event_type,
120 int net_error) const {
121 DCHECK_NE(ERR_IO_PENDING, net_error);
122 if (net_error >= 0) {
123 AddEvent(event_type);
124 } else {
125 AddEventWithIntParams(event_type, "net_error", net_error);
126 }
127 }
128
EndEventWithNetErrorCode(NetLogEventType event_type,int net_error) const129 void NetLogWithSource::EndEventWithNetErrorCode(NetLogEventType event_type,
130 int net_error) const {
131 DCHECK_NE(ERR_IO_PENDING, net_error);
132 if (net_error >= 0) {
133 EndEvent(event_type);
134 } else {
135 EndEventWithIntParams(event_type, "net_error", net_error);
136 }
137 }
138
AddEntryWithBoolParams(NetLogEventType type,NetLogEventPhase phase,base::StringPiece name,bool value) const139 void NetLogWithSource::AddEntryWithBoolParams(NetLogEventType type,
140 NetLogEventPhase phase,
141 base::StringPiece name,
142 bool value) const {
143 AddEntry(type, phase, [&] { return NetLogParamsWithBool(name, value); });
144 }
145
AddByteTransferEvent(NetLogEventType event_type,int byte_count,const char * bytes) const146 void NetLogWithSource::AddByteTransferEvent(NetLogEventType event_type,
147 int byte_count,
148 const char* bytes) const {
149 AddEvent(event_type, [&](NetLogCaptureMode capture_mode) {
150 return BytesTransferredParams(byte_count, bytes, capture_mode);
151 });
152 }
153
154 // static
Make(NetLog * net_log,NetLogSourceType source_type)155 NetLogWithSource NetLogWithSource::Make(NetLog* net_log,
156 NetLogSourceType source_type) {
157 if (!net_log)
158 return NetLogWithSource();
159
160 NetLogSource source(source_type, net_log->NextID());
161 return NetLogWithSource(source, net_log);
162 }
163
164 // static
Make(NetLogSourceType source_type)165 NetLogWithSource NetLogWithSource::Make(NetLogSourceType source_type) {
166 return NetLogWithSource::Make(NetLog::Get(), source_type);
167 }
168
169 // static
Make(NetLog * net_log,const NetLogSource & source)170 NetLogWithSource NetLogWithSource::Make(NetLog* net_log,
171 const NetLogSource& source) {
172 if (!net_log || !source.IsValid())
173 return NetLogWithSource();
174 return NetLogWithSource(source, net_log);
175 }
176
177 // static
Make(const NetLogSource & source)178 NetLogWithSource NetLogWithSource::Make(const NetLogSource& source) {
179 return NetLogWithSource::Make(NetLog::Get(), source);
180 }
181
net_log() const182 NetLog* NetLogWithSource::net_log() const {
183 if (source_.IsValid())
184 return non_null_net_log_;
185 return nullptr;
186 }
187
188 } // namespace net
189