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(https://crbug.com/1418110): 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 FileNetLogObserver(const FileNetLogObserver&) = delete; 90 FileNetLogObserver& operator=(const FileNetLogObserver&) = delete; 91 92 ~FileNetLogObserver() override; 93 94 // Attaches this observer to |net_log| and begins observing events. 95 void StartObserving(NetLog* net_log); 96 97 // Stops observing net_log() and closes the output file(s). Must be called 98 // after StartObserving. Should be called before destruction of the 99 // FileNetLogObserver and the NetLog, or the NetLog files (except for an 100 // externally provided output_file) will be deleted when the observer is 101 // destroyed. Note that it is OK to destroy |this| immediately after calling 102 // StopObserving() - the callback will still be called once the file writing 103 // has completed. 104 // 105 // |polled_data| is an optional argument used to add additional network stack 106 // state to the log. 107 // 108 // If non-null, |optional_callback| will be run on whichever thread 109 // StopObserving() was called on once all file writing is complete and the 110 // netlog files can be accessed safely. 111 void StopObserving(std::unique_ptr<base::Value> polled_data, 112 base::OnceClosure optional_callback); 113 114 // NetLog::ThreadSafeObserver 115 void OnAddEntry(const NetLogEntry& entry) override; 116 117 // Same as CreateBounded() but you can additionally specify 118 // |total_num_event_files|. 119 static std::unique_ptr<FileNetLogObserver> CreateBoundedForTests( 120 const base::FilePath& log_path, 121 uint64_t max_total_size, 122 size_t total_num_event_files, 123 NetLogCaptureMode capture_mode, 124 std::unique_ptr<base::Value::Dict> constants); 125 126 private: 127 class WriteQueue; 128 class FileWriter; 129 130 static std::unique_ptr<FileNetLogObserver> CreateInternal( 131 const base::FilePath& log_path, 132 const base::FilePath& inprogress_dir_path, 133 std::optional<base::File> pre_existing_out_file, 134 uint64_t max_total_size, 135 size_t total_num_event_files, 136 NetLogCaptureMode capture_mode, 137 std::unique_ptr<base::Value::Dict> constants); 138 139 FileNetLogObserver(scoped_refptr<base::SequencedTaskRunner> file_task_runner, 140 std::unique_ptr<FileWriter> file_writer, 141 scoped_refptr<WriteQueue> write_queue, 142 NetLogCaptureMode capture_mode, 143 std::unique_ptr<base::Value::Dict> constants); 144 145 static std::string CaptureModeToString(NetLogCaptureMode mode); 146 147 scoped_refptr<base::SequencedTaskRunner> file_task_runner_; 148 149 // The |write_queue_| object is shared between the file task runner and the 150 // main thread, and should be alive for the entirety of the observer's 151 // lifetime. It should be destroyed once both the observer has been destroyed 152 // and all tasks posted to the file task runner have completed. 153 scoped_refptr<WriteQueue> write_queue_; 154 155 // The FileNetLogObserver is shared between the main thread and 156 // |file_task_runner_|. 157 // 158 // Conceptually FileNetLogObserver owns it, however on destruction its 159 // deletion is deferred until outstanding tasks on |file_task_runner_| have 160 // finished (since it is posted using base::Unretained()). 161 std::unique_ptr<FileWriter> file_writer_; 162 163 const NetLogCaptureMode capture_mode_; 164 }; 165 166 // Serializes |value| to a JSON string used when writing to a file. 167 NET_EXPORT_PRIVATE std::string SerializeNetLogValueToJson( 168 const base::ValueView& value); 169 170 } // namespace net 171 172 #endif // NET_LOG_FILE_NET_LOG_OBSERVER_H_ 173