xref: /aosp_15_r20/external/cronet/net/log/file_net_log_observer.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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