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