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 logs all the NetLog entries into a specified file. It does |
|
eroman
2017/01/11 19:18:38
I suggest also mentioning that this is used exclus
wangyix1
2017/01/14 02:15:47
Done.
| |
| 37 // so by managing an instance of net::FileNetLogObserver and handles the | |
| 38 // attaching/detaching of it to the ChromeNetLog. | |
| 31 // | 39 // |
| 32 // NetLogFileWriter maintains the current logging state (state_) and log file | 40 // NetLogFileWriter maintains the current logging state (using the members |
| 33 // type (log_type_) of the logging into a chrome-net-export-log.json file. | 41 // (|state_|, |log_exists_|, |log_capture_mode_known_|, |log_capture_mode_|). |
| 42 // Its three main commands are StartNetLog(), StopNetLog() and GetState(). These | |
| 43 // are the only functions that may cause NetLogFileWriter to change state. | |
| 44 // Also, NetLogFileWriter is lazily initialized. A portion of the initialization | |
| 45 // needs to run on the |file_task_runner_|. | |
| 34 // | 46 // |
| 35 // The following are the possible states | 47 // 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). | 48 // points are to be called on the UI thread. Internally, the class may run some |
| 37 // b) Only Stop is allowed (STATE_LOGGING). | 49 // 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 { | 50 class NetLogFileWriter { |
| 46 public: | 51 public: |
| 47 // This enum lists the UI button commands it could receive. | 52 ~NetLogFileWriter(); |
| 48 enum Command { | |
| 49 DO_START_LOG_BYTES, // Call StartNetLog logging all bytes received. | |
| 50 DO_START, // Call StartNetLog. | |
| 51 DO_START_STRIP_PRIVATE_DATA, // Call StartNetLog stripping private data. | |
| 52 DO_STOP, // Call StopNetLog. | |
| 53 }; | |
| 54 | 53 |
| 55 virtual ~NetLogFileWriter(); | 54 // The three main commands StartNetLog(), StopNetLog(), and GetState() all |
| 55 // accept a |state_callback| param which can be used to notify the caller of | |
| 56 // NetLogFileWriter's new state after a command finshes. |state_callback| will | |
| 57 // always be executed by a command even if the command ends up being a no-op | |
| 58 // or if some failure occurs. | |
| 59 using StateCallback = | |
| 60 base::Callback<void(std::unique_ptr<base::DictionaryValue>)>; | |
| 56 | 61 |
| 57 // Accepts the button command and executes it. | 62 // Starts collecting NetLog data into the file at |log_path|. If |log_path| is |
| 58 void ProcessCommand(Command command); | 63 // empty, the default log path is used. It is a no-op if we are |
| 64 // already collecting data into a file, and |capture_mode| is ignored. | |
| 65 // ignored. | |
| 66 // TODO(mmenke): That's rather weird behavior, think about improving it. | |
| 67 // | |
| 68 // If NetLogFileWriter is not initialized, this will trigger initialization | |
| 69 // and |state_callback| will be executed at the end of StartNetLog() | |
| 70 // asynchronously (whether initialization is successful or not). Otherwise, | |
| 71 // |state_callback| will be executed at the end synchronously. | |
|
eroman
2017/01/11 19:18:39
Instead of having a synchronous case, can you make
wangyix1
2017/01/14 02:15:47
Done.
| |
| 72 void StartNetLog(const base::FilePath& log_path, | |
| 73 net::NetLogCaptureMode capture_mode, | |
| 74 const StateCallback& state_callback); | |
| 59 | 75 |
| 60 // Returns true and the path to the file. If there is no file to | 76 // Stops collecting NetLog data into the file. It is a no-op if we |
|
eroman
2017/01/11 19:18:39
nit: can you modify the language to avoid "we" ?
wangyix1
2017/01/14 02:15:47
Done.
| |
| 61 // send, then it returns false. It also returns false when actively logging to | 77 // are not currently logging. |
| 62 // the file. | 78 // |
| 63 bool GetFilePath(base::FilePath* path); | 79 // |polled_data| is a JSON dictionary that will be appended to the end of the |
| 80 // log; it's for adding additional info to the log that aren't events. | |
| 81 // StopNetLog() will automatically append net info (from net::GetNetInfo()) | |
| 82 // to |polled_data|, which it will retrieve using |context_getter|. | |
| 83 // | |
| 84 // |state_callback| will always be executed at the end of StopNetLog() | |
| 85 // (even if this function does a no-op or if some failure occurs). It will | |
| 86 // be executed asynchronously. | |
| 87 void StopNetLog(std::unique_ptr<base::DictionaryValue> polled_data, | |
| 88 scoped_refptr<net::URLRequestContextGetter> context_getter, | |
| 89 const StateCallback& state_callback); | |
| 64 | 90 |
| 65 // Creates a Value summary of the state of the NetLogFileWriter. The caller is | 91 // Creates a Value summary of the state of the NetLogFileWriter and calls |
| 66 // responsible for deleting the returned value. | 92 // |state_callback| with that Value as the param. |
| 67 base::DictionaryValue* GetState(); | 93 // |
| 94 // If NetLogFileWriter is not initialized, this will trigger initialization | |
| 95 // and |state_callback| will be executed at the end of GetState() | |
| 96 // asynchronously (whether initialization is successful or not). Otherwise, | |
|
eroman
2017/01/11 19:18:39
Same comment as earlier -- it is easier for consum
wangyix1
2017/01/14 02:15:47
Done.
| |
| 97 // |state_callback| will be executed at the end synchronously. | |
| 98 void GetState(const StateCallback& state_callback); | |
| 68 | 99 |
| 69 // Updates |log_path_| to the |custom_path|. | 100 using FilePathCallback = base::Callback<void(const base::FilePath&)>; |
|
eroman
2017/01/11 19:18:39
nit: move this to the top of the class declaration
wangyix1
2017/01/14 02:15:47
Done.
| |
| 70 void SetUpNetExportLogPath(const base::FilePath& custom_path); | 101 |
| 102 // Gets the log filepath. |path_callback| will be used to notify the caller | |
|
eroman
2017/01/11 19:18:39
Excellent comments!
wangyix1
2017/01/14 02:15:47
Acknowledged.
| |
| 103 // when the filepath is retrieved. |path_callback| will be executed with an | |
| 104 // empty filepath if any of the following occurs: | |
| 105 // (1) The log file does not exist. | |
| 106 // (2) The NetLogFileWriter is currently logging. | |
| 107 // (3) The log file's permissions could not be set to all. | |
| 108 // | |
| 109 // In cases (1) and (2), |path_callback| will be executed synchronously. In | |
|
eroman
2017/01/11 19:18:39
Same comment -- can we make all the completions as
wangyix1
2017/01/14 02:15:47
Done.
| |
| 110 // case (3) and the success case, it will be executed asynchronously. | |
| 111 void GetFilePath(const FilePathCallback& path_callback) const; | |
|
eroman
2017/01/11 19:18:39
[optional] I suggest changing this function's name
wangyix1
2017/01/14 02:15:47
Done.
| |
| 112 | |
| 113 // Sets the task runners used by NetLogFileWriter for running file-specific | |
|
eroman
2017/01/11 19:18:38
I suggest expanding this comment:
Sets the task r
wangyix1
2017/01/14 02:15:47
Done.
| |
| 114 // and net-specific tasks that must be run on those threads. | |
| 115 void SetTaskRunners( | |
| 116 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner, | |
| 117 scoped_refptr<base::SingleThreadTaskRunner> net_task_runner); | |
| 118 | |
| 119 static std::string CaptureModeToString(net::NetLogCaptureMode capture_mode); | |
|
eroman
2017/01/11 19:18:38
Suggest adding this comment:
// Converts to/from
wangyix1
2017/01/14 02:15:47
Done.
| |
| 120 static net::NetLogCaptureMode CaptureModeFromString( | |
| 121 const std::string& capture_mode_string); | |
| 71 | 122 |
| 72 protected: | 123 protected: |
| 73 // Constructs a NetLogFileWriter. Only one instance is created in browser | 124 // Constructs a NetLogFileWriter. Only one instance is created in browser |
| 74 // process. | 125 // process. |
| 75 NetLogFileWriter(ChromeNetLog* chrome_net_log, | 126 NetLogFileWriter(ChromeNetLog* chrome_net_log, |
| 76 const base::CommandLine::StringType& command_line_string, | 127 const base::CommandLine::StringType& command_line_string, |
| 77 const std::string& channel_string); | 128 const std::string& channel_string); |
| 78 | 129 |
| 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: | 130 private: |
| 84 friend class ChromeNetLog; | 131 friend class ChromeNetLog; |
| 85 friend class NetLogFileWriterTest; | 132 friend class NetLogFileWriterTest; |
| 86 | 133 |
| 87 // Allow tests to access our innards for testing purposes. | 134 // Allow tests to access our innards for testing purposes. |
| 88 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, EnsureInitFailure); | 135 /*FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, EnsureInitFailure); |
|
eroman
2017/01/11 19:18:39
NOTE: I assume this will be updated in a subsequen
wangyix1
2017/01/14 02:15:47
Acknowledged.
| |
| 89 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, EnsureInitAllowStart); | 136 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, EnsureInitAllowStart); |
| 90 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, EnsureInitAllowStartOrSend); | 137 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, EnsureInitAllowStartOrSend); |
| 91 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, ProcessCommandDoStartAndStop); | 138 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, ProcessCommandDoStartAndStop); |
| 92 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, DoStartClearsFile); | 139 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, DoStartClearsFile); |
| 93 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, CheckAddEvent); | 140 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, CheckAddEvent); |
| 94 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, CheckAddEventWithCustomPath); | 141 FRIEND_TEST_ALL_PREFIXES(NetLogFileWriterTest, CheckAddEventWithCustomPath); |
| 142 */ | |
| 95 | 143 |
| 96 // This enum lists the possible state NetLogFileWriter could be in. It is used | 144 // The possible logging states of NetLogFileWriter. |
| 97 // to enable/disable "Start", "Stop" and "Send" (email) UI actions. | |
| 98 enum State { | 145 enum State { |
| 99 STATE_UNINITIALIZED, | 146 STATE_UNINITIALIZED, |
| 147 // Currently in the process of initializing. | |
| 148 STATE_INITIALIZING, | |
| 100 // Not currently logging to file. | 149 // Not currently logging to file. |
| 101 STATE_NOT_LOGGING, | 150 STATE_NOT_LOGGING, |
| 102 // Currently logging to file. | 151 // Currently logging to file. |
| 103 STATE_LOGGING, | 152 STATE_LOGGING, |
| 153 // Currently in the process of stopping the log. | |
| 154 STATE_STOPPING_LOG, | |
| 104 }; | 155 }; |
| 105 | 156 |
| 106 // The type of the current log file on disk. | 157 // Helper function used by commands that may trigger initialization |
| 107 enum LogType { | 158 // (StartNetLog(), GetState()). This function attemps to initialize |
|
eroman
2017/01/11 19:18:39
typo: attempts
wangyix1
2017/01/14 02:15:47
Done.
| |
| 108 // There is no current log file. | 159 // NetLogFileWriter asynchronously, then executes |callback|. |
| 109 LOG_TYPE_NONE, | 160 void InitAndCallback(const base::Closure& callback); |
|
eroman
2017/01/11 19:18:39
[optional] InitThenCallback() ?
wangyix1
2017/01/14 02:15:47
Done.
| |
| 110 // The file predates this session. May or may not have private data. | 161 |
| 111 // TODO(davidben): This state is kind of silly. | 162 // Struct used to store the results of SetUpDefaultLogPath() which will be |
| 112 LOG_TYPE_UNKNOWN, | 163 // passed to InitStateAndCallback(). |
| 113 // The log includes raw bytes. | 164 struct DefaultLogPathResults { |
|
eroman
2017/01/11 19:18:39
Move the struct declaration to be below the enum S
wangyix1
2017/01/14 02:15:47
Done.
| |
| 114 LOG_TYPE_LOG_BYTES, | 165 bool default_log_path_success; |
| 115 // The file includes all data. | 166 base::FilePath default_log_path; |
| 116 LOG_TYPE_NORMAL, | 167 bool log_exists; |
| 117 // The file has credentials and cookies stripped. | |
| 118 LOG_TYPE_STRIP_PRIVATE_DATA, | |
| 119 }; | 168 }; |
| 120 | 169 |
| 121 // Returns the NetLog::CaptureMode corresponding to a LogType. | 170 // Contains file-related initialization tasks. Will run on the file task |
| 122 static net::NetLogCaptureMode GetCaptureModeForLogType(LogType log_type); | 171 // runner. |
| 172 static DefaultLogPathResults SetUpDefaultLogPath(); | |
| 123 | 173 |
| 124 // Initializes the |state_| to STATE_NOT_LOGGING and |log_type_| to | 174 // Initializes |state_| and |log_path_| using results from |
| 125 // LOG_TYPE_NONE (if there is no file from earlier run) or | 175 // SetUpDefaultLogPath(), then executes |callback|. |
|
eroman
2017/01/11 19:18:39
mention if the execution of |callback| is synchro
wangyix1
2017/01/14 02:15:47
Done.
| |
| 126 // LOG_TYPE_UNKNOWN (if there is a file from earlier run). Returns | 176 void InitStateAndCallback(const base::Closure& callback, |
| 127 // false if initialization of |log_path_| fails. | 177 const DefaultLogPathResults& results); |
| 128 bool EnsureInit(); | |
| 129 | 178 |
| 130 // Start collecting NetLog data into chrome-net-export-log.json file in | 179 void StartLogging(const base::FilePath& log_path, |
| 131 // a directory, using the specified capture mode. It is a no-op if we are | 180 net::NetLogCaptureMode capture_mode, |
| 132 // already collecting data into a file, and |capture_mode| is ignored. | 181 const StateCallback& state_callback); |
| 133 // ignored. | |
| 134 // TODO(mmenke): That's rather weird behavior, think about improving it. | |
| 135 void StartNetLog(LogType log_type); | |
| 136 | 182 |
| 137 // Stop collecting NetLog data into the file. It is a no-op if we | 183 // Adds net info from net::GetNetInfo() to |polled_data|. Will run on the |
|
eroman
2017/01/11 19:18:39
Will run on the --> must be run on the
wangyix1
2017/01/14 02:15:47
Done.
| |
| 138 // are not collecting data into a file. | 184 // net task runner. |
| 139 void StopNetLog(); | 185 static std::unique_ptr<base::DictionaryValue> AddNetInfo( |
|
eroman
2017/01/11 19:18:39
Consider moving this declaration to the .cc
(i.e.
wangyix1
2017/01/14 02:15:47
Done.
| |
| 186 scoped_refptr<net::URLRequestContextGetter> context_getter, | |
| 187 std::unique_ptr<base::DictionaryValue> polled_data); | |
| 140 | 188 |
| 141 // Updates |log_path_| to be the base::FilePath to use for log files, which | 189 void StopLogging(const StateCallback& state_callback, |
| 142 // will be inside the base::GetTempDir() directory. Returns false if | 190 std::unique_ptr<base::DictionaryValue> polled_data); |
| 143 // base::GetTempDir() fails, or unable to create a subdirectory for logging | |
| 144 // within that directory. | |
| 145 bool SetUpDefaultNetExportLogPath(); | |
| 146 | 191 |
| 147 // Returns true if a file exists at |log_path_|. | 192 void ResetObserverThenSetStateNotLogging(const StateCallback& state_callback); |
| 148 bool NetExportLogExists() const; | 193 |
| 194 std::unique_ptr<base::DictionaryValue> GetState() const; | |
| 195 | |
| 196 // Gets the state and runs |state_callback|. | |
| 197 void RunStateCallback(const StateCallback& state_callback) const; | |
| 198 | |
| 199 // If running on a POSIX OS, this sets all the permission flags of the file at | |
| 200 // |path| to 1. Returns false if file does not exist. | |
| 201 static bool SetPosixFilePermissionsAll(const base::FilePath& path); | |
|
eroman
2017/01/11 19:18:38
This can also be moved to the .cc file (i.e. remo
wangyix1
2017/01/14 02:15:47
Done.
| |
| 202 | |
| 203 // If |set_file_permissions_success| is true, |path_callback| is executed with | |
| 204 // |path|. Otherwise, |path_callback| is executed with empty path. | |
| 205 static void RunFilePathCallback(const FilePathCallback& path_callback, | |
| 206 const base::FilePath& path, | |
| 207 bool set_file_permissions_success); | |
| 208 | |
| 209 // Helper function for unit tests. | |
| 210 State state() const { return state_; } | |
| 211 | |
| 212 // All members are accessed solely from the main thread (the thread that | |
| 213 // |thread_checker_| is bound to). | |
| 149 | 214 |
| 150 base::ThreadChecker thread_checker_; | 215 base::ThreadChecker thread_checker_; |
| 151 | 216 |
| 152 // Helper function for unit tests. | 217 // Task runners for file-specific and net-specific tasks that must run on a |
| 153 State state() const { return state_; } | 218 // file or net thread. |
| 154 LogType log_type() const { return log_type_; } | 219 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_; |
| 220 scoped_refptr<base::SingleThreadTaskRunner> net_task_runner_; | |
| 155 | 221 |
| 156 State state_; // Current state of NetLogFileWriter. | 222 State state_; // Current logging state of NetLogFileWriter. |
| 157 LogType log_type_; // Type of current log file on disk. | 223 |
| 224 bool log_exists_; // Whether or not the log exists on disk. | |
| 225 bool log_capture_mode_known_; | |
| 226 net::NetLogCaptureMode log_capture_mode_; | |
| 158 | 227 |
| 159 base::FilePath log_path_; // base::FilePath to the NetLog file. | 228 base::FilePath log_path_; // base::FilePath to the NetLog file. |
| 160 | 229 |
| 161 // |write_to_file_observer_| watches the NetLog event stream, and | 230 // |write_to_file_observer_| watches the NetLog event stream, and |
| 162 // sends all entries to the file created in StartNetLog(). | 231 // sends all entries to the file created in StartNetLog(). |
| 163 std::unique_ptr<net::WriteToFileNetLogObserver> write_to_file_observer_; | 232 std::unique_ptr<net::FileNetLogObserver> write_to_file_observer_; |
| 164 | 233 |
| 165 // The |chrome_net_log_| is owned by the browser process, cached here to avoid | 234 // The |chrome_net_log_| is owned by the browser process, cached here to avoid |
| 166 // using global (g_browser_process). | 235 // using global (g_browser_process). |
| 167 ChromeNetLog* chrome_net_log_; | 236 ChromeNetLog* chrome_net_log_; |
| 168 | 237 |
| 169 const base::CommandLine::StringType command_line_string_; | 238 const base::CommandLine::StringType command_line_string_; |
| 170 const std::string channel_string_; | 239 const std::string channel_string_; |
| 171 | 240 |
| 241 base::WeakPtrFactory<NetLogFileWriter> weak_ptr_factory_; | |
| 242 | |
| 172 DISALLOW_COPY_AND_ASSIGN(NetLogFileWriter); | 243 DISALLOW_COPY_AND_ASSIGN(NetLogFileWriter); |
| 173 }; | 244 }; |
| 174 | 245 |
| 175 } // namespace net_log | 246 } // namespace net_log |
| 176 | 247 |
| 177 #endif // COMPONENTS_NET_LOG_NET_LOG_FILE_WRITER_H_ | 248 #endif // COMPONENTS_NET_LOG_NET_LOG_FILE_WRITER_H_ |
| OLD | NEW |