xref: /aosp_15_r20/external/cronet/net/docs/net-log.md (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker# NetLog
2*6777b538SAndroid Build Coastguard Worker
3*6777b538SAndroid Build Coastguard WorkerThis document describes the design and use of logging through NetLog.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker[TOC]
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker## Adding new NetLogging code
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard WorkerAdding information to the NetLog helps debugging. However, logging also requires
10*6777b538SAndroid Build Coastguard Workercareful review as it can impact performance, privacy, and security.
11*6777b538SAndroid Build Coastguard Worker
12*6777b538SAndroid Build Coastguard WorkerPlease add a [net/log/OWNERS](../log/OWNERS) reviewer when adding new NetLog
13*6777b538SAndroid Build Coastguard Workerparameters, or adding information to existing ones.
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard WorkerThe high level objectives when adding net logging code are:
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard Worker* No performance cost when capturing is off.
18*6777b538SAndroid Build Coastguard Worker* Logs captured using [`kDefault`](../log/net_log_capture_mode.h) are safe to
19*6777b538SAndroid Build Coastguard Worker  upload and share publicly.
20*6777b538SAndroid Build Coastguard Worker* Capturing using [`kDefault`](../log/net_log_capture_mode.h) has a low
21*6777b538SAndroid Build Coastguard Worker  performance impact.
22*6777b538SAndroid Build Coastguard Worker* Logs captured using [`kDefault`](../log/net_log_capture_mode.h) are small
23*6777b538SAndroid Build Coastguard Worker  enough to upload to bug reports.
24*6777b538SAndroid Build Coastguard Worker* Events that may emit sensitive information have accompanying unit-tests.
25*6777b538SAndroid Build Coastguard Worker* The event and its possible parameters are documented in
26*6777b538SAndroid Build Coastguard Worker  [net_log_event_type_list.h](../log/net_log_event_type_list.h)
27*6777b538SAndroid Build Coastguard Worker
28*6777b538SAndroid Build Coastguard WorkerTo avoid doing work when logging is off, logging code should generally be
29*6777b538SAndroid Build Coastguard Workerconditional on `NetLog::IsCapturing()`. Note that when specifying parameters
30*6777b538SAndroid Build Coastguard Workervia a lambda, the lambda is already conditional on `IsCapturing()`.
31*6777b538SAndroid Build Coastguard Worker
32*6777b538SAndroid Build Coastguard Worker### Binary data and strings
33*6777b538SAndroid Build Coastguard Worker
34*6777b538SAndroid Build Coastguard WorkerNetLog parameters are specified as a JSON serializable `base::Value`. This has
35*6777b538SAndroid Build Coastguard Workersome subtle implications:
36*6777b538SAndroid Build Coastguard Worker
37*6777b538SAndroid Build Coastguard Worker* Do not use `base::Value::Type::STRING` with non-UTF-8 data.
38*6777b538SAndroid Build Coastguard Worker* Do not use `base::Value::Type::BINARY` (the JSON serializer can't handle it)
39*6777b538SAndroid Build Coastguard Worker
40*6777b538SAndroid Build Coastguard WorkerInstead:
41*6777b538SAndroid Build Coastguard Worker
42*6777b538SAndroid Build Coastguard Worker* If the string is likely ASCII or UTF-8, use `NetLogStringValue()`.
43*6777b538SAndroid Build Coastguard Worker* If the string is arbitrary data, use `NetLogBinaryValue()`.
44*6777b538SAndroid Build Coastguard Worker* If the string is guaranteed to be valid UTF-8, you can use
45*6777b538SAndroid Build Coastguard Worker  `base::Value::Type::STRING`
46*6777b538SAndroid Build Coastguard Worker
47*6777b538SAndroid Build Coastguard WorkerAlso consider the maximum size of any string parameters:
48*6777b538SAndroid Build Coastguard Worker
49*6777b538SAndroid Build Coastguard Worker* If the string could be large, truncate or omit it when using the default
50*6777b538SAndroid Build Coastguard Worker  capture mode. Large strings should be relegated to the `kEverything`
51*6777b538SAndroid Build Coastguard Worker  capture mode.
52*6777b538SAndroid Build Coastguard Worker
53*6777b538SAndroid Build Coastguard Worker### 64-bit integers
54*6777b538SAndroid Build Coastguard Worker
55*6777b538SAndroid Build Coastguard WorkerNetLog parameters are specified as a JSON serializable `base::Value` which does
56*6777b538SAndroid Build Coastguard Workernot support 64-bit integers.
57*6777b538SAndroid Build Coastguard Worker
58*6777b538SAndroid Build Coastguard WorkerBe careful when using `base::Value::Dict::Set()` as it will truncate 64-bit
59*6777b538SAndroid Build Coastguard Workervalues to 32-bits.
60*6777b538SAndroid Build Coastguard Worker
61*6777b538SAndroid Build Coastguard WorkerInstead use `NetLogNumberValue()`.
62*6777b538SAndroid Build Coastguard Worker
63*6777b538SAndroid Build Coastguard Worker### Backwards compatibility
64*6777b538SAndroid Build Coastguard Worker
65*6777b538SAndroid Build Coastguard WorkerThere is no backwards compatibility requirement for NetLog events and their
66*6777b538SAndroid Build Coastguard Workerparameters, so you are free to change their structure/value as needed.
67*6777b538SAndroid Build Coastguard Worker
68*6777b538SAndroid Build Coastguard WorkerThat said, changing core events may have consequences for external consumers of
69*6777b538SAndroid Build Coastguard WorkerNetLogs, which rely on the structure and parameters to events for pretty
70*6777b538SAndroid Build Coastguard Workerprinting and log analysis.
71*6777b538SAndroid Build Coastguard Worker
72*6777b538SAndroid Build Coastguard WorkerThe [NetLog viewer](https://netlog-viewer.appspot.com/) for instance pretty
73*6777b538SAndroid Build Coastguard Workerprints certain parameters based on their names, and the event name that added
74*6777b538SAndroid Build Coastguard Workerthem.
75*6777b538SAndroid Build Coastguard Worker
76*6777b538SAndroid Build Coastguard Worker### Example 1
77*6777b538SAndroid Build Coastguard Worker
78*6777b538SAndroid Build Coastguard WorkerAdd an `PROXY_RESOLUTION_SERVICE` event without any parameters, at all capture
79*6777b538SAndroid Build Coastguard Workermodes.
80*6777b538SAndroid Build Coastguard Worker
81*6777b538SAndroid Build Coastguard Worker```
82*6777b538SAndroid Build Coastguard Workernet_log.BeginEvent(NetLogEventType::PROXY_RESOLUTION_SERVICE);
83*6777b538SAndroid Build Coastguard Worker```
84*6777b538SAndroid Build Coastguard Worker
85*6777b538SAndroid Build Coastguard WorkerAnalysis:
86*6777b538SAndroid Build Coastguard Worker
87*6777b538SAndroid Build Coastguard Worker* Privacy: Logging the event at all capture modes only reveals timing
88*6777b538SAndroid Build Coastguard Worker  information.
89*6777b538SAndroid Build Coastguard Worker* Performance: When not logging, has the overhead of an unconditional function
90*6777b538SAndroid Build Coastguard Worker  call (`BeginEvent`), and then a branch (test on `IsCapturing()`).
91*6777b538SAndroid Build Coastguard Worker* Size: Minimal data added to NetLog - just one parameterless event per URL
92*6777b538SAndroid Build Coastguard Worker  request.
93*6777b538SAndroid Build Coastguard Worker
94*6777b538SAndroid Build Coastguard Worker### Example 2
95*6777b538SAndroid Build Coastguard Worker
96*6777b538SAndroid Build Coastguard WorkerAdd a `FTP_COMMAND_SENT` event, at all capture modes, along with parameters
97*6777b538SAndroid Build Coastguard Workerthat describe the FTP command.
98*6777b538SAndroid Build Coastguard Worker
99*6777b538SAndroid Build Coastguard Worker```
100*6777b538SAndroid Build Coastguard Workerif (net_log.IsCapturing()) {
101*6777b538SAndroid Build Coastguard Worker  std::string command = BuildCommandForLog();
102*6777b538SAndroid Build Coastguard Worker  net_log.AddEventWithStringParams(NetLogEventType::FTP_COMMAND_SENT,
103*6777b538SAndroid Build Coastguard Worker                                   "command", command);
104*6777b538SAndroid Build Coastguard Worker}
105*6777b538SAndroid Build Coastguard Worker```
106*6777b538SAndroid Build Coastguard Worker
107*6777b538SAndroid Build Coastguard WorkerAnalysis:
108*6777b538SAndroid Build Coastguard Worker
109*6777b538SAndroid Build Coastguard Worker* Privacy: Low risk given FTP traffic is unencrypted. `BuildCommandForString()`
110*6777b538SAndroid Build Coastguard Worker  should additionally best-effort strip any identity information, as this is
111*6777b538SAndroid Build Coastguard Worker  being logged at all capture modes.
112*6777b538SAndroid Build Coastguard Worker* Performance: Costs one branch when not capturing. The call to
113*6777b538SAndroid Build Coastguard Worker  `BuildCommandForString()` is only executed when capturing.
114*6777b538SAndroid Build Coastguard Worker* Size: Cost is proportional to the average FTP command length and frequency of
115*6777b538SAndroid Build Coastguard Worker  FTP, both of which are low. `BuildCommandForLog()` needn't strictly bound the
116*6777b538SAndroid Build Coastguard Worker  string length. If a huge FTP command makes it to a NetLog, there is a good
117*6777b538SAndroid Build Coastguard Worker  chance that is the problem being debugged.
118*6777b538SAndroid Build Coastguard Worker
119*6777b538SAndroid Build Coastguard Worker### Example 3
120*6777b538SAndroid Build Coastguard Worker
121*6777b538SAndroid Build Coastguard WorkerAdd a `SSL_CERTIFICATES_RECEIVED` event, along with the full certificate chain,
122*6777b538SAndroid Build Coastguard Workerat all capture modes.
123*6777b538SAndroid Build Coastguard Worker
124*6777b538SAndroid Build Coastguard Worker```
125*6777b538SAndroid Build Coastguard Workernet_log.AddEvent(NetLogEventType::SSL_CERTIFICATES_RECEIVED, [&] {
126*6777b538SAndroid Build Coastguard Worker  base::Value::Dict dict;
127*6777b538SAndroid Build Coastguard Worker  base::Value::List certs;
128*6777b538SAndroid Build Coastguard Worker  std::vector<std::string> encoded_chain;
129*6777b538SAndroid Build Coastguard Worker  server_cert_->GetPEMEncodedChain(&encoded_chain);
130*6777b538SAndroid Build Coastguard Worker  for (auto& pem : encoded_chain)
131*6777b538SAndroid Build Coastguard Worker    certs.Append(std::move(pem));
132*6777b538SAndroid Build Coastguard Worker  dict.Set("certificates", std::move(certs));
133*6777b538SAndroid Build Coastguard Worker  return base::Value(std::move(dict));
134*6777b538SAndroid Build Coastguard Worker});
135*6777b538SAndroid Build Coastguard Worker```
136*6777b538SAndroid Build Coastguard Worker
137*6777b538SAndroid Build Coastguard WorkerAnalysis:
138*6777b538SAndroid Build Coastguard Worker
139*6777b538SAndroid Build Coastguard Worker* Privacy: Low risk as server certificates are generally public data.
140*6777b538SAndroid Build Coastguard Worker* Performance: Costs one branch when logging is off (hidden by template
141*6777b538SAndroid Build Coastguard Worker  expansion). The code in the lambda which builds the `base::Value` parameters is only
142*6777b538SAndroid Build Coastguard Worker  executed when capturing.
143*6777b538SAndroid Build Coastguard Worker* Size: On average 8K worth of data per request (average of 2K/certificate,
144*6777b538SAndroid Build Coastguard Worker  chain length of 3, and the overhead of PEM-encoding). This is heavy-weight
145*6777b538SAndroid Build Coastguard Worker  for inclusion at `kDefault` capture mode, however justified based on how
146*6777b538SAndroid Build Coastguard Worker  useful the data is.
147*6777b538SAndroid Build Coastguard Worker
148*6777b538SAndroid Build Coastguard Worker### Example 4
149*6777b538SAndroid Build Coastguard Worker
150*6777b538SAndroid Build Coastguard WorkerAdd a `COOKIE_STORE_COOKIE_ADDED` event at all capture modes. Moreover, if the
151*6777b538SAndroid Build Coastguard Workercapture mode is `kIncludeSensitive` or `kEverything`, also logs the cookie's
152*6777b538SAndroid Build Coastguard Workername and value.
153*6777b538SAndroid Build Coastguard Worker
154*6777b538SAndroid Build Coastguard Worker```
155*6777b538SAndroid Build Coastguard Workernet_log.AddEvent(NetLogEventType::COOKIE_STORE_COOKIE_ADDED,
156*6777b538SAndroid Build Coastguard Worker                 [&](NetLogCaptureMode capture_mode) {
157*6777b538SAndroid Build Coastguard Worker                   if (!NetLogCaptureIncludesSensitive(capture_mode))
158*6777b538SAndroid Build Coastguard Worker                     return base::Value();
159*6777b538SAndroid Build Coastguard Worker                   base::Value::Dict dict;
160*6777b538SAndroid Build Coastguard Worker                   dict.Set("name", cookie->Name());
161*6777b538SAndroid Build Coastguard Worker                   dict.Set("value", cookie->Value());
162*6777b538SAndroid Build Coastguard Worker                   return base::Value(std::move(dict));
163*6777b538SAndroid Build Coastguard Worker                 });
164*6777b538SAndroid Build Coastguard Worker```
165*6777b538SAndroid Build Coastguard Worker
166*6777b538SAndroid Build Coastguard WorkerAnalysis:
167*6777b538SAndroid Build Coastguard Worker
168*6777b538SAndroid Build Coastguard Worker* Privacy: The cookie name and value are not included at the `kDefault` capture
169*6777b538SAndroid Build Coastguard Worker  mode, so only cookie counts and timing information is revealed.
170*6777b538SAndroid Build Coastguard Worker* Performance: Costs one branch when logging is off (hidden by template
171*6777b538SAndroid Build Coastguard Worker  expansion). The code in the lambda which builds the `base::Value` parameters is only
172*6777b538SAndroid Build Coastguard Worker  executed when capturing.
173*6777b538SAndroid Build Coastguard Worker* Size: For default captured logs, has a file size cost proportional to the
174*6777b538SAndroid Build Coastguard Worker  number of cookies added. This is borderline justifiable. It would be better
175*6777b538SAndroid Build Coastguard Worker  in this case to simply omit the event all together at `kDefault` than to log
176*6777b538SAndroid Build Coastguard Worker  a parameterless event, as the parameterless event is not broadly useful.
177