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