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 #ifndef NET_LOG_FILE_NET_LOG_OBSERVER_H_ 6 #define NET_LOG_FILE_NET_LOG_OBSERVER_H_ 7 8 #include <limits> 9 #include <memory> 10 #include <optional> 11 12 #include "base/files/file.h" 13 #include "base/functional/callback.h" 14 #include "base/memory/scoped_refptr.h" 15 #include "base/values.h" 16 #include "net/base/net_export.h" 17 #include "net/log/net_log.h" 18 19 namespace base { 20 class FilePath; 21 class SequencedTaskRunner; 22 } // namespace base 23 24 namespace net { 25 26 // FileNetLogObserver watches the NetLog event stream and sends all entries to 27 // a file. 28 // 29 // Consumers must call StartObserving before calling StopObserving, and must 30 // call each method exactly once in the lifetime of the observer. 31 // 32 // The log will not be completely written until StopObserving is called. 33 // 34 // When a file size limit is given, FileNetLogObserver will create temporary 35 // directory containing chunks of events. This is used to drop older events in 36 // favor of newer ones. 37 class NET_EXPORT FileNetLogObserver : public NetLog::ThreadSafeObserver { 38 public: 39 // Special value meaning "can use an unlimited number of bytes". 40 static constexpr uint64_t kNoLimit = std::numeric_limits<uint64_t>::max(); 41 42 // Creates an instance of FileNetLogObserver that writes observed netlog 43 // events to |log_path|. 44 // 45 // |log_path| is where the final log file will be written to. If a file 46 // already exists at this path it will be overwritten. While logging is in 47 // progress, events may be written to a like-named directory. 48 // 49 // |max_total_size| is the limit on how many bytes logging may consume on 50 // disk. This is an approximate limit, and in practice FileNetLogObserver may 51 // (slightly) exceed it. This may be set to kNoLimit to remove any size 52 // restrictions. 53 // 54 // |constants| is an optional legend for decoding constant values used in the 55 // log. It should generally be a modified version of GetNetConstants(). If not 56 // present, the output of GetNetConstants() will be used. 57 // TODO(crbug.com/40257546): This should be updated to pass a 58 // base::Value::Dict instead of a std::unique_ptr. 59 static std::unique_ptr<FileNetLogObserver> CreateBounded( 60 const base::FilePath& log_path, 61 uint64_t max_total_size, 62 NetLogCaptureMode capture_mode, 63 std::unique_ptr<base::Value::Dict> constants); 64 65 // Shortcut for calling CreateBounded() with kNoLimit. 66 static std::unique_ptr<FileNetLogObserver> CreateUnbounded( 67 const base::FilePath& log_path, 68 NetLogCaptureMode capture_mode, 69 std::unique_ptr<base::Value::Dict> constants); 70 71 // Creates a bounded log that writes to a pre-existing file (truncating 72 // it to start with, and closing it upon completion). |inprogress_dir_path| 73 // will be used as a scratch directory, for temporary files (with predictable 74 // names). 75 static std::unique_ptr<FileNetLogObserver> CreateBoundedPreExisting( 76 const base::FilePath& inprogress_dir_path, 77 base::File output_file, 78 uint64_t max_total_size, 79 NetLogCaptureMode capture_mode, 80 std::unique_ptr<base::Value::Dict> constants); 81 82 // Creates an unbounded log that writes to a pre-existing file (truncating 83 // it to start with, and closing it upon completion). 84 static std::unique_ptr<FileNetLogObserver> CreateUnboundedPreExisting( 85 base::File output_file, 86 NetLogCaptureMode capture_mode, 87 std::unique_ptr<base::Value::Dict> constants); 88 89 // Creates a bounded log that writes to a pre-existing. Instead of stitching 90 // multiple log files together, once the maximum capacity has been reached the 91 // logging stops. 92 static std::unique_ptr<FileNetLogObserver> CreateBoundedFile( 93 base::File output_file, 94 uint64_t max_total_size, 95 NetLogCaptureMode capture_mode, 96 std::unique_ptr<base::Value::Dict> constants); 97 98 FileNetLogObserver(const FileNetLogObserver&) = delete; 99 FileNetLogObserver& operator=(const FileNetLogObserver&) = delete; 100 101 ~FileNetLogObserver() override; 102 103 // Attaches this observer to |net_log| and begins observing events. 104 void StartObserving(NetLog* net_log); 105 106 // Stops observing net_log() and closes the output file(s). Must be called 107 // after StartObserving. Should be called before destruction of the 108 // FileNetLogObserver and the NetLog, or the NetLog files (except for an 109 // externally provided output_file) will be deleted when the observer is 110 // destroyed. Note that it is OK to destroy |this| immediately after calling 111 // StopObserving() - the callback will still be called once the file writing 112 // has completed. 113 // 114 // |polled_data| is an optional argument used to add additional network stack 115 // state to the log. 116 // 117 // If non-null, |optional_callback| will be run on whichever thread 118 // StopObserving() was called on once all file writing is complete and the 119 // netlog files can be accessed safely. 120 void StopObserving(std::unique_ptr<base::Value> polled_data, 121 base::OnceClosure optional_callback); 122 123 // NetLog::ThreadSafeObserver 124 void OnAddEntry(const NetLogEntry& entry) override; 125 126 // Same as CreateBounded() but you can additionally specify 127 // |total_num_event_files|. 128 static std::unique_ptr<FileNetLogObserver> CreateBoundedForTests( 129 const base::FilePath& log_path, 130 uint64_t max_total_size, 131 size_t total_num_event_files, 132 NetLogCaptureMode capture_mode, 133 std::unique_ptr<base::Value::Dict> constants); 134 135 private: 136 class WriteQueue; 137 class FileWriter; 138 139 static std::unique_ptr<FileNetLogObserver> CreateInternal( 140 const base::FilePath& log_path, 141 const base::FilePath& inprogress_dir_path, 142 std::optional<base::File> pre_existing_out_file, 143 uint64_t max_total_size, 144 size_t total_num_event_files, 145 NetLogCaptureMode capture_mode, 146 std::unique_ptr<base::Value::Dict> constants); 147 148 FileNetLogObserver(scoped_refptr<base::SequencedTaskRunner> file_task_runner, 149 std::unique_ptr<FileWriter> file_writer, 150 scoped_refptr<WriteQueue> write_queue, 151 NetLogCaptureMode capture_mode, 152 std::unique_ptr<base::Value::Dict> constants); 153 154 static std::string CaptureModeToString(NetLogCaptureMode mode); 155 156 scoped_refptr<base::SequencedTaskRunner> file_task_runner_; 157 158 // The |write_queue_| object is shared between the file task runner and the 159 // main thread, and should be alive for the entirety of the observer's 160 // lifetime. It should be destroyed once both the observer has been destroyed 161 // and all tasks posted to the file task runner have completed. 162 scoped_refptr<WriteQueue> write_queue_; 163 164 // The FileNetLogObserver is shared between the main thread and 165 // |file_task_runner_|. 166 // 167 // Conceptually FileNetLogObserver owns it, however on destruction its 168 // deletion is deferred until outstanding tasks on |file_task_runner_| have 169 // finished (since it is posted using base::Unretained()). 170 std::unique_ptr<FileWriter> file_writer_; 171 172 const NetLogCaptureMode capture_mode_; 173 }; 174 175 // Serializes |value| to a JSON string used when writing to a file. 176 NET_EXPORT_PRIVATE std::string SerializeNetLogValueToJson( 177 const base::ValueView& value); 178 179 } // namespace net 180 181 #endif // NET_LOG_FILE_NET_LOG_OBSERVER_H_ 182