• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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