Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef COMPONENTS_NET_LOG_NET_LOG_FILE_WRITER_H_ | 5 #ifndef COMPONENTS_NET_LOG_NET_LOG_FILE_WRITER_H_ |
| 6 #define COMPONENTS_NET_LOG_NET_LOG_FILE_WRITER_H_ | 6 #define COMPONENTS_NET_LOG_NET_LOG_FILE_WRITER_H_ |
| 7 | 7 |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| 11 #include "base/callback.h" | |
| 11 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 12 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
| 13 #include "base/gtest_prod_util.h" | 14 #include "base/gtest_prod_util.h" |
| 14 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "base/memory/ref_counted.h" | |
| 17 #include "base/memory/weak_ptr.h" | |
| 15 #include "base/threading/thread_checker.h" | 18 #include "base/threading/thread_checker.h" |
| 19 #include "net/log/net_log_capture_mode.h" | |
| 16 | 20 |
| 17 namespace base { | 21 namespace base { |
| 18 class DictionaryValue; | 22 class DictionaryValue; |
| 23 class SingleThreadTaskRunner; | |
| 24 class Value; | |
| 19 } | 25 } |
| 20 | 26 |
| 21 namespace net { | 27 namespace net { |
| 22 class NetLogCaptureMode; | 28 class FileNetLogObserver; |
| 23 class WriteToFileNetLogObserver; | 29 class URLRequestContextGetter; |
| 24 } | 30 } |
| 25 | 31 |
| 26 namespace net_log { | 32 namespace net_log { |
| 27 | 33 |
| 28 class ChromeNetLog; | 34 class ChromeNetLog; |
| 29 | 35 |
| 30 // NetLogFileWriter logs all the NetLog entries into a specified file. | 36 // NetLogFileWriter is used exclusively as a support class for net-export. |
| 37 // It's a singleton that acts as the interface to all NetExportMessageHandlers | |
| 38 // which can tell it to start or stop logging in response to the net-export UIs' | |
|
eroman
2017/01/18 21:32:43
UIs' --> UI's
wangyix1
2017/01/19 23:09:46
Done.
| |
| 39 // user actions. Because it's a singleton, the logging state can be shared | |
| 40 // between multiple instances of the net-export UI. Internally, it manages an | |
|
eroman
2017/01/18 21:32:43
Good comment
wangyix1
2017/01/19 23:09:46
Acknowledged.
| |
| 41 // instance of net::FileNetLogObserver and handles the attaching/detaching of it | |
| 42 // to the ChromeNetLog. This class is used by the iOS and non-iOS | |
| 43 // implementations of net-export. | |
| 31 // | 44 // |
| 32 // NetLogFileWriter maintains the current logging state (state_) and log file | 45 // NetLogFileWriter maintains the current logging state (using the members |
| 33 // type (log_type_) of the logging into a chrome-net-export-log.json file. | 46 // (|state_|, |log_exists_|, |log_capture_mode_known_|, |log_capture_mode_|). |
| 47 // Its three main commands are StartNetLog(), StopNetLog() and GetState(). These | |
| 48 // are the only functions that may cause NetLogFileWriter to change state. | |
| 49 // Also, NetLogFileWriter is lazily initialized. A portion of the initialization | |
| 50 // needs to run on the |file_task_runner_|. | |
| 34 // | 51 // |
| 35 // The following are the possible states | 52 // This class is created and destroyed on the UI thread, and all public entry |
| 36 // a) Only Start is allowed (STATE_NOT_LOGGING, LOG_TYPE_NONE). | 53 // points are to be called on the UI thread. Internally, the class may run some |
| 37 // b) Only Stop is allowed (STATE_LOGGING). | 54 // code on the |file_task_runner_| and |net_task_runner_|. |
| 38 // c) Either Send or Start is allowed (STATE_NOT_LOGGING, anything but | |
| 39 // LOG_TYPE_NONE). | |
| 40 // | |
| 41 // This is created/destroyed on the main thread, but all other function calls | |
| 42 // occur on a background thread. | |
| 43 // | |
| 44 // This relies on the UI thread outlasting all other threads for thread safety. | |
| 45 class NetLogFileWriter { | 55 class NetLogFileWriter { |
| 46 public: | 56 public: |
| 47 // This enum lists the UI button commands it could receive. | 57 // The three main commands StartNetLog(), StopNetLog(), and GetState() and the |
| 48 enum Command { | 58 // getter GetFilePathToCompletedLog() all accept a callback param which is |
| 49 DO_START_LOG_BYTES, // Call StartNetLog logging all bytes received. | 59 // used to notify the caller of the results of that function. For all these |
| 50 DO_START, // Call StartNetLog. | 60 // commands, the callback will always be executed even if the command ends up |
| 51 DO_START_STRIP_PRIVATE_DATA, // Call StartNetLog stripping private data. | 61 // being a no-op or if some failure occurs. |
| 52 DO_STOP, // Call StopNetLog. | |
| 53 }; | |
| 54 | 62 |
| 55 virtual ~NetLogFileWriter(); | 63 using StateCallback = |
| 64 base::Callback<void(std::unique_ptr<base::DictionaryValue>)>; | |
| 56 | 65 |
| 57 // Accepts the button command and executes it. | 66 using FilePathCallback = base::Callback<void(const base::FilePath&)>; |
| 58 void ProcessCommand(Command command); | |
| 59 | 67 |
| 60 // Returns true and the path to the file. If there is no file to | 68 using DirectoryGetter = base::Callback<bool(base::FilePath*)>; |
| 61 // send, then it returns false. It also returns false when actively logging to | |
| 62 // the file. | |
| 63 bool GetFilePath(base::FilePath* path); | |
| 64 | 69 |
| 65 // Creates a Value summary of the state of the NetLogFileWriter. The caller is | 70 ~NetLogFileWriter(); |
| 66 // responsible for deleting the returned value. | |
| 67 base::DictionaryValue* GetState(); | |
| 68 | 71 |
| 69 // Updates |log_path_| to the |custom_path|. | 72 // Starts collecting NetLog data into the file at |log_path|. If |log_path| is |
| 70 void SetUpNetExportLogPath(const base::FilePath& custom_path); | 73 // empty, the default log path is used. It is a no-op if NetLogFileWriter is |
| 74 // already collecting data into a file, and |capture_mode| is ignored. | |
| 75 // ignored. | |
| 76 // TODO(mmenke): That's rather weird behavior, think about improving it. | |
| 77 // | |
| 78 // If NetLogFileWriter is not initialized, StartNetLog() will trigger | |
| 79 // initialization. | |
| 80 // | |
| 81 // |state_callback| will be executed at the end of StartNetLog() | |
| 82 // asynchronously. | |
| 83 void StartNetLog(const base::FilePath& log_path, | |
| 84 net::NetLogCaptureMode capture_mode, | |
| 85 const StateCallback& state_callback); | |
| 86 | |
| 87 // Stops collecting NetLog data into the file. It is a no-op if | |
| 88 // NetLogFileWriter is currently not logging. | |
| 89 // | |
| 90 // |polled_data| is a JSON dictionary that will be appended to the end of the | |
| 91 // log; it's for adding additional info to the log that aren't events. | |
| 92 // If |context_getter| is not null, then StopNetLog() will automatically | |
| 93 // append net info (from net::GetNetInfo() retrieved using |context_getter|) | |
| 94 // to |polled_data|. | |
| 95 // | |
| 96 // |state_callback| will be executed at the end of StopNetLog() | |
| 97 // asynchronously. | |
| 98 void StopNetLog(std::unique_ptr<base::DictionaryValue> polled_data, | |
| 99 scoped_refptr<net::URLRequestContextGetter> context_getter, | |
| 100 const StateCallback& state_callback); | |
| 101 | |
| 102 // Creates a Value summary of the state of the NetLogFileWriter and calls | |
| 103 // |state_callback| with that Value as the param. | |
| 104 // | |
| 105 // If NetLogFileWriter is not initialized, GetState() will trigger | |
| 106 // initialization. | |
| 107 // | |
| 108 // |state_callback| will be executed at the end of GetState() asynchronously. | |
| 109 void GetState(const StateCallback& state_callback); | |
| 110 | |
| 111 // Gets the log filepath. |path_callback| will be used to notify the caller | |
| 112 // when the filepath is retrieved. |path_callback| will be executed with an | |
| 113 // empty filepath if any of the following occurs: | |
| 114 // (1) The NetLogFileWriter is not initialized. | |
| 115 // (2) The log file does not exist. | |
| 116 // (3) The NetLogFileWriter is currently logging. | |
| 117 // (4) The log file's permissions could not be set to all. | |
| 118 // | |
| 119 // |path_callback| will be executed at the end of GetFilePathToCompletedLog() | |
| 120 // asynchronously. | |
| 121 void GetFilePathToCompletedLog(const FilePathCallback& path_callback) const; | |
| 122 | |
| 123 // Sets the task runners used by NetLogFileWriter for doing file I/O and | |
| 124 // network I/O respectively. This must be called prior to using the | |
| 125 // NetLogFileWriter. The task runners must not be changed once set. However, | |
| 126 // calling this function again with the same parameters is OK. | |
| 127 void SetTaskRunners( | |
| 128 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, | |
| 129 scoped_refptr<base::SingleThreadTaskRunner> net_task_runner); | |
| 130 | |
| 131 // Converts to/from the string representation of a capture mode used by | |
| 132 // net_export.js. | |
| 133 static std::string CaptureModeToString(net::NetLogCaptureMode capture_mode); | |
| 134 static net::NetLogCaptureMode CaptureModeFromString( | |
| 135 const std::string& capture_mode_string); | |
| 136 | |
| 137 // Overrides the getter used to retrieve the default log base directory during | |
| 138 // initialization. Should only be used by unit tests. | |
| 139 void SetDefaultLogBaseDirectoryGetter(const DirectoryGetter& getter); | |
|
eroman
2017/01/18 21:32:43
For functions that are exclusively exposed for uni
wangyix1
2017/01/19 23:09:46
Done.
| |
| 71 | 140 |
| 72 protected: | 141 protected: |
| 73 // Constructs a NetLogFileWriter. Only one instance is created in browser | 142 // Constructs a NetLogFileWriter. Only one instance is created in browser |
| 74 // process. | 143 // process. |
| 75 NetLogFileWriter(ChromeNetLog* chrome_net_log, | 144 NetLogFileWriter(ChromeNetLog* chrome_net_log, |
| 76 const base::CommandLine::StringType& command_line_string, | 145 const base::CommandLine::StringType& command_line_string, |
| 77 const std::string& channel_string); | 146 const std::string& channel_string); |
| 78 | 147 |
| 79 // Returns path name to base::GetTempDir() directory. Returns false if | |
| 80 // base::GetTempDir() fails. | |
| 81 virtual bool GetNetExportLogBaseDirectory(base::FilePath* path) const; | |
| 82 | |
| 83 private: | 148 private: |
| 84 friend class ChromeNetLog; | 149 friend class ChromeNetLog; |
| 85 friend class NetLogFileWriterTest; | 150 friend class NetLogFileWriterTest; |
| 86 | 151 |
| 87 // Allow tests to access our innards for testing purposes. | 152 // The possible logging states of NetLogFileWriter. |
| 88 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, EnsureInitFailure); | |
| 89 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, EnsureInitAllowStart); | |
| 90 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, EnsureInitAllowStartOrSend); | |
| 91 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, ProcessCommandDoStartAndStop); | |
| 92 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, DoStartClearsFile); | |
| 93 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, CheckAddEvent); | |
| 94 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, CheckAddEventWithCustomPath); | |
| 95 | |
| 96 // This enum lists the possible state NetLogFileWriter could be in. It is used | |
| 97 // to enable/disable "Start", "Stop" and "Send" (email) UI actions. | |
| 98 enum State { | 153 enum State { |
| 99 STATE_UNINITIALIZED, | 154 STATE_UNINITIALIZED, |
| 155 // Currently in the process of initializing. | |
| 156 STATE_INITIALIZING, | |
| 100 // Not currently logging to file. | 157 // Not currently logging to file. |
| 101 STATE_NOT_LOGGING, | 158 STATE_NOT_LOGGING, |
| 102 // Currently logging to file. | 159 // Currently logging to file. |
| 103 STATE_LOGGING, | 160 STATE_LOGGING, |
| 161 // Currently in the process of stopping the log. | |
| 162 STATE_STOPPING_LOG, | |
| 104 }; | 163 }; |
| 105 | 164 |
| 106 // The type of the current log file on disk. | 165 // Struct used to store the results of SetUpDefaultLogPath() which will be |
| 107 enum LogType { | 166 // passed to InitStateThenCallback(). |
| 108 // There is no current log file. | 167 struct DefaultLogPathResults { |
| 109 LOG_TYPE_NONE, | 168 bool default_log_path_success; |
| 110 // The file predates this session. May or may not have private data. | 169 base::FilePath default_log_path; |
| 111 // TODO(davidben): This state is kind of silly. | 170 bool log_exists; |
| 112 LOG_TYPE_UNKNOWN, | |
| 113 // The log includes raw bytes. | |
| 114 LOG_TYPE_LOG_BYTES, | |
| 115 // The file includes all data. | |
| 116 LOG_TYPE_NORMAL, | |
| 117 // The file has credentials and cookies stripped. | |
| 118 LOG_TYPE_STRIP_PRIVATE_DATA, | |
| 119 }; | 171 }; |
| 120 | 172 |
| 121 // Returns the NetLog::CaptureMode corresponding to a LogType. | 173 // Helper function used by commands that may trigger initialization |
| 122 static net::NetLogCaptureMode GetCaptureModeForLogType(LogType log_type); | 174 // (StartNetLog(), GetState()). This function attempts to initialize |
| 175 // NetLogFileWriter asynchronously, then executes |callback|. | |
| 176 void InitThenCallback(const base::Closure& callback); | |
| 123 | 177 |
| 124 // Initializes the |state_| to STATE_NOT_LOGGING and |log_type_| to | 178 // Contains file-related initialization tasks. Will run on the file task |
| 125 // LOG_TYPE_NONE (if there is no file from earlier run) or | 179 // runner. |
| 126 // LOG_TYPE_UNKNOWN (if there is a file from earlier run). Returns | 180 static DefaultLogPathResults SetUpDefaultLogPath( |
|
eroman
2017/01/18 21:32:43
Can this be part of the .cc file instead of a stat
wangyix1
2017/01/19 23:09:46
This would require exposing the struct NetLogFileW
| |
| 127 // false if initialization of |log_path_| fails. | 181 const DirectoryGetter& default_log_base_directory_getter); |
| 128 bool EnsureInit(); | |
| 129 | 182 |
| 130 // Start collecting NetLog data into chrome-net-export-log.json file in | 183 // Initializes |state_| and |log_path_| using results from |
| 131 // a directory, using the specified capture mode. It is a no-op if we are | 184 // SetUpDefaultLogPath(), then executes |callback| synchronously. |
| 132 // already collecting data into a file, and |capture_mode| is ignored. | 185 void InitStateThenCallback( |
| 133 // ignored. | 186 const base::Closure& callback, |
| 134 // TODO(mmenke): That's rather weird behavior, think about improving it. | 187 const DefaultLogPathResults& set_up_default_log_path_results); |
| 135 void StartNetLog(LogType log_type); | |
| 136 | 188 |
| 137 // Stop collecting NetLog data into the file. It is a no-op if we | 189 // Executes |state_callback| synchronously. StartLogging() is expected to be |
| 138 // are not collecting data into a file. | 190 // called asynchronously. |
| 139 void StopNetLog(); | 191 void StartLogging(const base::FilePath& log_path, |
| 192 net::NetLogCaptureMode capture_mode, | |
| 193 const StateCallback& state_callback); | |
| 140 | 194 |
| 141 // Updates |log_path_| to be the base::FilePath to use for log files, which | 195 // Executes |state_callback| asynchronously. |
| 142 // will be inside the base::GetTempDir() directory. Returns false if | 196 void StopLogging(const StateCallback& state_callback, |
| 143 // base::GetTempDir() fails, or unable to create a subdirectory for logging | 197 std::unique_ptr<base::DictionaryValue> polled_data); |
| 144 // within that directory. | |
| 145 bool SetUpDefaultNetExportLogPath(); | |
| 146 | 198 |
| 147 // Returns true if a file exists at |log_path_|. | 199 // Executes |state_callback| synchronously. |
| 148 bool NetExportLogExists() const; | 200 // ResetObserverThenSetStateNotLogging() is expected to be called |
| 201 // asynchronously. | |
| 202 void ResetObserverThenSetStateNotLogging(const StateCallback& state_callback); | |
| 203 | |
| 204 std::unique_ptr<base::DictionaryValue> GetState() const; | |
| 205 | |
| 206 // Gets the state and runs |state_callback| synchronously. | |
| 207 void RunStateCallback(const StateCallback& state_callback) const; | |
| 208 | |
| 209 // Gets the state and runs |state_callback| asynchronously. | |
| 210 void RunStateCallbackAsync(const StateCallback& state_callback) const; | |
| 211 | |
| 212 // If |set_file_permissions_success| is true, |path_callback| is executed with | |
| 213 // |path|. Otherwise, |path_callback| is executed with empty path. | |
| 214 static void RunFilePathCallback(const FilePathCallback& path_callback, | |
| 215 const base::FilePath& path, | |
| 216 bool set_file_permissions_success); | |
| 217 | |
| 218 // All members are accessed solely from the main thread (the thread that | |
| 219 // |thread_checker_| is bound to). | |
| 149 | 220 |
| 150 base::ThreadChecker thread_checker_; | 221 base::ThreadChecker thread_checker_; |
| 151 | 222 |
| 152 // Helper function for unit tests. | 223 // Task runners for file-specific and net-specific tasks that must run on a |
| 153 State state() const { return state_; } | 224 // file or net thread. |
| 154 LogType log_type() const { return log_type_; } | 225 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_; |
| 226 scoped_refptr<base::SingleThreadTaskRunner> net_task_runner_; | |
| 155 | 227 |
| 156 State state_; // Current state of NetLogFileWriter. | 228 State state_; // Current logging state of NetLogFileWriter. |
| 157 LogType log_type_; // Type of current log file on disk. | 229 |
| 230 bool log_exists_; // Whether or not the log exists on disk. | |
| 231 bool log_capture_mode_known_; | |
| 232 net::NetLogCaptureMode log_capture_mode_; | |
| 158 | 233 |
| 159 base::FilePath log_path_; // base::FilePath to the NetLog file. | 234 base::FilePath log_path_; // base::FilePath to the NetLog file. |
| 160 | 235 |
| 161 // |write_to_file_observer_| watches the NetLog event stream, and | 236 // |write_to_file_observer_| watches the NetLog event stream, and |
| 162 // sends all entries to the file created in StartNetLog(). | 237 // sends all entries to the file created in StartNetLog(). |
| 163 std::unique_ptr<net::WriteToFileNetLogObserver> write_to_file_observer_; | 238 std::unique_ptr<net::FileNetLogObserver> write_to_file_observer_; |
| 164 | 239 |
| 165 // The |chrome_net_log_| is owned by the browser process, cached here to avoid | 240 // The |chrome_net_log_| is owned by the browser process, cached here to avoid |
| 166 // using global (g_browser_process). | 241 // using global (g_browser_process). |
| 167 ChromeNetLog* chrome_net_log_; | 242 ChromeNetLog* chrome_net_log_; |
| 168 | 243 |
| 169 const base::CommandLine::StringType command_line_string_; | 244 const base::CommandLine::StringType command_line_string_; |
| 170 const std::string channel_string_; | 245 const std::string channel_string_; |
| 171 | 246 |
| 247 // Used by unit tests to override the default log base directory retrieved | |
| 248 // during initialization. This getter is initialized to base::GetTempDir(). | |
| 249 DirectoryGetter default_log_base_directory_getter_; | |
| 250 | |
| 251 base::WeakPtrFactory<NetLogFileWriter> weak_ptr_factory_; | |
| 252 | |
| 172 DISALLOW_COPY_AND_ASSIGN(NetLogFileWriter); | 253 DISALLOW_COPY_AND_ASSIGN(NetLogFileWriter); |
| 173 }; | 254 }; |
| 174 | 255 |
| 175 } // namespace net_log | 256 } // namespace net_log |
| 176 | 257 |
| 177 #endif // COMPONENTS_NET_LOG_NET_LOG_FILE_WRITER_H_ | 258 #endif // COMPONENTS_NET_LOG_NET_LOG_FILE_WRITER_H_ |
| OLD | NEW |