| // 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 "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" |
| #include "third_party/abseil-cpp/absl/types/optional.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(https://crbug.com/1418110): 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); |
| |
| FileNetLogObserver(const FileNetLogObserver&) = delete; |
| FileNetLogObserver& operator=(const FileNetLogObserver&) = delete; |
| |
| ~FileNetLogObserver() override; |
| |
| // 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: |
| class WriteQueue; |
| class FileWriter; |
| |
| static std::unique_ptr<FileNetLogObserver> CreateInternal( |
| const base::FilePath& log_path, |
| const base::FilePath& inprogress_dir_path, |
| absl::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_; |
| |
| // 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_ |