Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Side by Side Diff: base/logging.h

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/lock_ptr_unittest.cc ('k') | base/logging.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2003-2009 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15 //
16 // logging.h
17 //
18 // Tracing and logging system.
19 // Allows filtering of the log messages based on logging categories and levels.
20
21 #ifndef OMAHA_BASE_LOGGING_H_
22 #define OMAHA_BASE_LOGGING_H_
23
24 #include "omaha/base/constants.h"
25 #include "omaha/base/synchronized.h"
26 #include "omaha/base/time.h"
27
28 #ifdef LOGGING
29
30 // Logging levels.
31 enum LogLevel {
32 LEVEL_FATALERROR = -3, // crashing fatal error
33 LEVEL_ERROR = -2, // errors - recoverable but shouldn't happen
34 LE = -2,
35 LEVEL_WARNING = -1, // warnings
36 LW = -1,
37 L1 = 1, // for aprox. 10 logs per run
38 L2, // for aprox. 100 logs per run
39 L3, // for aprox. 1,000 logs per run
40 L4, // for aprox. 10,000 logs per run
41 L5, // for aprox. 100,000 logs per run
42 L6, // for > 1,000,000 logs per run
43
44 // add above
45 LEVEL_ALL // all errors
46 };
47
48 #endif
49
50 namespace omaha {
51
52 #define kDefaultLoggingEnabled 1
53 #define kLogConfigFileName MAIN_EXE_BASE_NAME _T(".ini")
54 #define kDefaultLogFileName MAIN_EXE_BASE_NAME _T(".log")
55 #define kDefaultLogFileWide 1
56 #define kDefaultShowTime 1
57 #define kDefaultAppendToFile 1
58
59 #ifdef _DEBUG
60 #define kDefaultMaxLogFileSize 0xFFFFFFFF // 4GB
61 #define kDefaultLogToFile 1
62 #define kDefaultLogToOutputDebug 1
63 #define kDefaultLogLevel L3
64 #else
65 #define kDefaultMaxLogFileSize 10000000 // 10MB
66 #define kDefaultLogToFile 0
67 #define kDefaultLogToOutputDebug 0
68 #define kDefaultLogLevel L1
69 #endif
70
71 // Truncates the log file when the size of the log file is this many
72 // times over the MaxLogFileSize to prevent disk overfill.
73 #define kStopGapLogFileSizeFactor 10
74
75 // config file sections
76 #define kConfigSectionLoggingLevel L"LoggingLevel"
77 #define kConfigSectionLoggingSettings L"LoggingSettings"
78
79 // config file attributes
80 #define kConfigAttrEnableLogging L"EnableLogging"
81 #define kConfigAttrShowTime L"ShowTime"
82 #define kConfigAttrLogToFile L"LogToFile"
83 #define kConfigAttrLogFilePath L"LogFilePath"
84 #define kConfigAttrLogFileWide L"LogFileWide"
85 #define kConfigAttrLogToOutputDebug L"LogToOutputDebug"
86 #define kConfigAttrAppendToFile L"AppendToFile"
87 #define kConfigAttrMaxLogFileSize L"MaxLogFileSize"
88
89 #define kLoggingMutexName kLockPrefix L"logging_mutex"
90 #define kMaxMutexWaitTimeMs 500
91
92 // Does not allow messages bigger than 1 MB.
93 #define kMaxLogMessageSize (1024 * 1024)
94
95 #define kLogSettingsCheckInterval (5 * kSecsTo100ns)
96
97 #define kStartOfLogMessage \
98 L"********************* NEW LOG *********************"
99 #define kEndOfLogMessage \
100 L"********************* END LOG *********************"
101
102 // TODO(omaha): Allow these defaults to be overriden in the config file.
103 #define kMaxLevelToStoreInLogHistory L2
104 #define kMaxHistoryBufferSize 1024
105
106 #ifdef LOGGING
107
108 #define LC_LOG(cat, level, msg) \
109 do { \
110 omaha::Logging* logger = omaha::GetLogging(); \
111 if (logger) { \
112 omaha::LoggingHelper(logger, cat, level, \
113 logger->IsCatLevelEnabled(cat, level)) msg; \
114 } \
115 } while (0)
116
117 #define LC_LOG_OPT(cat, level, msg) LC_LOG(cat, level, msg)
118
119 #else
120 #define LC_LOG(cat, level, msg) ((void)0)
121 #endif
122
123 #ifdef _DEBUG
124 #define LC_LOG_DEBUG(cat, level, msg) LC_LOG(cat, level, msg)
125 #else
126 #define LC_LOG_DEBUG(cat, level, msg) ((void)0)
127 #endif
128
129 // Shortcuts for different logging categories - no need to specify the category.
130 #define CORE_LOG(x, y) LC_LOG_DEBUG(omaha::LC_CORE, x, y)
131 #define NET_LOG(x, y) LC_LOG_DEBUG(omaha::LC_NET, x, y)
132 #define PLUGIN_LOG(x, y) LC_LOG_DEBUG(omaha::LC_PLUGIN, x, y)
133 #define SERVICE_LOG(x, y) LC_LOG_DEBUG(omaha::LC_SERVICE, x, y)
134 #define SETUP_LOG(x, y) LC_LOG_DEBUG(omaha::LC_SETUP, x, y)
135 #define SHELL_LOG(x, y) LC_LOG_DEBUG(omaha::LC_SHELL, x, y)
136 #define UTIL_LOG(x, y) LC_LOG_DEBUG(omaha::LC_UTIL, x, y)
137
138 #define OPT_LOG(x, y) LC_LOG_OPT(omaha::LC_OPT, x, y)
139 #define REPORT_LOG(x, y) LC_LOG_OPT(omaha::LC_REPORT, x, y)
140
141 #ifdef LOGGING
142
143 // Logging components.
144 // Maximum 32 categories unless mask is increased to 64 bits.
145 enum LogCategory {
146 LC_LOGGING = 0,
147
148 // ADD BELOW - AND REMEMBER:
149 // - Add a line to the LogCategoryNames table in logging.cc!!!
150 // - Add to C:\GoogleUpdate.ini.
151
152 LC_UTIL,
153 LC_SETUP,
154 LC_SHELL,
155 LC_CORE,
156 LC_JS,
157 LC_PLUGIN,
158 LC_SERVICE,
159 LC_OPT,
160 LC_NET,
161 LC_REPORT,
162
163 // ADD ABOVE
164
165 LC_MAX_CAT
166 };
167
168 #define kCatEnabledField L"Enabled"
169 #define kCatLevelField L"Level"
170
171 struct CategoryInfo {
172 bool enabled;
173 LogLevel log_level;
174 };
175
176 // If you want to log anything else, add it to this structure. This structure
177 // basically says that each logged message is composed of two parts, and they
178 // are output one after the other. Intended to be used for a message "prefix"
179 // and the message itself (the prefix can contain the component name, the time,
180 // and any other logging system boilerplate, while the message is supplied by
181 // the component). (This basically saves having to copy a variable length -
182 // possibly very large - message just to tack it onto the end of the message
183 // prefix.)
184 struct OutputInfo {
185 LogCategory category;
186 LogLevel level;
187 const wchar_t* msg1;
188 const wchar_t* msg2;
189
190 OutputInfo(LogCategory cat, LogLevel log_level,
191 const wchar_t* m1, const wchar_t* m2)
192 : category(cat),
193 level(log_level),
194 msg1(m1),
195 msg2(m2) {}
196 };
197
198 // The LogWriter - can decide whether to process message or not, then
199 // will process it. Actually, the message is processed if either a) the
200 // individual LogWriter wants to process it or b) it is marked as processable
201 // by settings in config ini.
202 //
203 // Included LogWriters:
204 // OutputDebugStringLogWriter - Logs to OutputDebugString() API
205 // FileLogWriter - Logs to a file
206 // OverrideConfigLogWriter - Overrides the level settings of a
207 // particular category, uses another writer to actually do the writing.
208 // Used, e.g., in installer to force SETUP_LOG messages to go to a file
209 // tr_setup_log.info even if the there is no trconfig.ini file.
210 //
211 // Not included LogWriters:
212 // StdLogWriter - Logs to stdout or stderr
213 // SubmitToGoogleLogWriter - When done logging submits the log file to
214 // Google's status-receiving server
215 class LogWriter {
216 protected:
217 LogWriter();
218 virtual void Cleanup();
219 public:
220 virtual ~LogWriter();
221
222 // Returns true if this Logging object wants to log even if the global
223 // "enable logging" flag is off. Useful for always creating a log, e.g., an
224 // install log, even without a GoogleUpdate.ini.
225 virtual bool WantsToLogRegardless() const;
226
227 // Returns true if this Logging object wants to handle the message,
228 // regardless of other settings.
229 virtual bool IsCatLevelEnabled(LogCategory category, LogLevel level) const;
230
231 virtual void OutputMessage(const OutputInfo* output_info);
232
233 // Registers and unregisters this LogWriter with the Logging system. When
234 // registered, the Logging class assumes ownership.
235 bool Register();
236 bool Unregister();
237
238 private:
239 DISALLOW_EVIL_CONSTRUCTORS(LogWriter);
240 };
241
242 // A LogWriter that writes to a named file.
243 class FileLogWriter : public LogWriter {
244 protected:
245 FileLogWriter(const wchar_t* file_name, bool append);
246 ~FileLogWriter();
247 virtual void Cleanup();
248
249 public:
250 static FileLogWriter* Create(const wchar_t* file_name, bool append);
251 virtual void OutputMessage(const OutputInfo* output_info);
252
253 private:
254 void Initialize();
255 bool CreateLoggingMutex();
256 bool CreateLoggingFile();
257 bool ArchiveLoggingFile();
258 bool TruncateLoggingFile();
259 bool GetMutex();
260 void ReleaseMutex();
261
262 // Returns true if archiving of the log file is pending a computer restart.
263 bool IsArchivePending();
264
265 // Returns the first position of str inside of a MULTI_SZ of count characters
266 // including the terminating zeros.
267 static int FindFirstInMultiString(const wchar_t* multi_str,
268 size_t count,
269 const wchar_t* str);
270
271 uint32 max_file_size_;
272 bool initialized_;
273 bool valid_;
274 bool append_;
275 bool log_file_wide_;
276 CString log_file_mutex_name_;
277 HANDLE log_file_mutex_;
278 CString file_name_;
279 HANDLE log_file_;
280 CString proc_name_;
281
282 friend class FileLogWriterTest;
283
284 DISALLOW_EVIL_CONSTRUCTORS(FileLogWriter);
285 };
286
287 // A LogWriter that uses OutputDebugString() to write messages.
288 class OutputDebugStringLogWriter : public LogWriter {
289 protected:
290 OutputDebugStringLogWriter();
291 ~OutputDebugStringLogWriter();
292 public:
293 static OutputDebugStringLogWriter* Create();
294 virtual void OutputMessage(const OutputInfo* info);
295 private:
296 DISALLOW_EVIL_CONSTRUCTORS(OutputDebugStringLogWriter);
297 };
298
299 // A LogWriter that overrides the settings in trconfig.ini and sends messages
300 // to another LogWriter. Takes ownership of the other LogWriter.
301 class OverrideConfigLogWriter : public LogWriter {
302 protected:
303 OverrideConfigLogWriter(LogCategory category, LogLevel level,
304 LogWriter* log_writer, bool force_logging_enabled);
305 virtual void Cleanup();
306 public:
307 static OverrideConfigLogWriter* Create(LogCategory category, LogLevel level,
308 LogWriter* log_writer, bool force_logging_enabled);
309 virtual bool WantsToLogRegardless() const;
310 virtual bool IsCatLevelEnabled(LogCategory category, LogLevel level) const;
311 virtual void OutputMessage(const OutputInfo* output_info);
312 private:
313 LogCategory category_;
314 LogLevel level_;
315 LogWriter* log_writer_;
316 bool force_logging_enabled_;
317 DISALLOW_EVIL_CONSTRUCTORS(OverrideConfigLogWriter);
318 };
319
320 // This log writer outputs to Event Tracing for Windows.
321 class EtwLogWriter;
322
323 // The Logging class - Singleton class
324 // Fine-grain logging based on categories and levels.
325 // Can log to a file, stdout or debugger.
326 class Logging {
327 public:
328 // constructor
329 Logging();
330
331 // destructor
332 ~Logging();
333
334 // Enables/disables the logging mechanism. Allows turning logging on/off
335 // in mid-run. Returns true for success (not for 'logging enabled').
336 void EnableLogging();
337 void DisableLogging();
338
339 // Checks if logging is enabled - and updates logging settings from the
340 // configuration file every kLogSettingsCheckInterval seconds
341 bool IsLoggingEnabled();
342
343 // Checks if logging is already enabled. It does not try to enable it.
344 bool IsLoggingAlreadyEnabled() const;
345
346 // Overrides the config file settings for showing the time stamps.
347 void ForceShowTimestamp(bool force_show_time);
348
349 // Checks if logging is enabled for a given category and level.
350 DWORD IsCatLevelEnabled(LogCategory category, LogLevel level);
351 LogLevel GetCatLevel(LogCategory category) const;
352
353 // Logs a message.
354 void LogMessage(LogCategory cat, LogLevel level, const wchar_t* fmt, ...);
355 void LogMessageVA(LogCategory cat, LogLevel level, const wchar_t* fmt,
356 va_list args);
357
358 // Retrieves the default location of the log directory.
359 CString GetDefaultLogDirectory() const;
360
361 // Computes and returns the complete path of the log file.
362 CString GetLogFilePath() const;
363
364 // Retrieves in-memory history buffer.
365 CString GetHistory();
366
367 // Returns the file path of the current GoogleUpdate.ini.
368 CString GetCurrentConfigurationFilePath() const;
369
370 const CString& proc_name() const { return proc_name_; }
371
372 bool IsCategoryEnabledForBuffering(LogCategory cat);
373 private:
374 bool InternalInitialize();
375 void InternalLogMessageMaskedVA(DWORD writer_mask,
376 LogCategory cat,
377 LogLevel level,
378 CString* log_buffer,
379 CString* prefix,
380 const wchar_t* fmt,
381 va_list args);
382
383 friend class LoggingHelper;
384 void LogMessageMaskedVA(DWORD writer_mask, LogCategory cat, LogLevel level,
385 const wchar_t* fmt, va_list args);
386
387 // Stores log message in in-memory history buffer.
388 void StoreInHistory(const OutputInfo* output_info);
389
390 // Appends string to in-memory history buffer.
391 void AppendToHistory(const wchar_t* msg);
392
393 // Initializes the logging engine. Harmless to call multiple times.
394 bool InitializeLogging();
395
396 // Configures/unconfigures the log writers for the current settings. That
397 // is, given the current settings from GoogleUpdate.ini, either initializes
398 // and registers the file-out and debug-out logwriters, or unregisters them.
399 void ConfigureETWLogWriter();
400 void ConfigureFileLogWriter();
401 void ConfigureDebugOutLogWriter();
402 bool ConfigureLogging();
403 void UnconfigureLogging();
404
405 void UpdateCatAndLevel(const wchar_t* cat_name, LogCategory cat);
406 void ReadLoggingSettings();
407
408 // Returns the primary file path of the GoogleUpdate.ini.
409 CString GetConfigurationFilePath() const;
410
411 // Returns the alternate file path of the GoogleUpdate.ini.
412 CString GetAltConfigurationFilePath() const;
413
414 public:
415
416 // Passes the messages along to other OutputMessage()
417 void OutputMessage(DWORD writer_mask, LogCategory cat, LogLevel level,
418 const wchar_t* msg1, const wchar_t* msg2);
419
420 // Broadcasts the message to each LogWriter.
421 // It should be private but the function we want to be able to use this,
422 // debugASSERT is extern "C" and thus can't be declared a friend of
423 // Logging.
424 void OutputMessage(DWORD writer_mask, const OutputInfo* output_info);
425
426 private:
427
428 CategoryInfo category_list_[LC_MAX_CAT];
429
430 // Checks if logging is initialized.
431 bool logging_initialized_;
432
433 // Is logging in the process of initializing?
434 bool is_initializing_;
435
436 // The logging process name including the calling module.
437 CString proc_name_;
438
439 // Serializes changing logging init/uninit/enable/disable status.
440 LLock lock_;
441
442 // Bunch of settings from the config .ini file.
443 bool logging_enabled_; // Checks if logging is enabled.
444 bool force_show_time_;
445 bool show_time_;
446 bool log_to_file_;
447 CString log_file_name_;
448 bool log_to_debug_out_;
449 bool append_to_file_;
450
451 // Signals the logging system is shutting down.
452 bool logging_shutdown_;
453
454 // Checkpoint time for dynamic category updates.
455 time64 g_last_category_check_time;
456
457 // The file path of the optional ini file which defines the logging
458 // configuration.
459 CString config_file_path_;
460
461 private:
462 bool InternalRegisterWriter(LogWriter* log_writer);
463 bool InternalUnregisterWriter(LogWriter* log_writer);
464
465 public:
466 bool RegisterWriter(LogWriter* log_writer);
467 bool UnregisterWriter(LogWriter* log_writer);
468 enum { all_writers_mask = -1 };
469
470 private:
471 enum { max_writers = 15 };
472 int num_writers_;
473 LogWriter* writers_[max_writers];
474
475 LogWriter* file_log_writer_;
476 LogWriter* debug_out_writer_;
477 LogWriter* etw_log_writer_;
478
479 friend class HistoryTest;
480
481 DISALLOW_EVIL_CONSTRUCTORS(Logging);
482 };
483
484 // In order to make the logging macro LC_LOG work out we need to pass a
485 // parameter (the mask of loggers to write to) (*) to the actual logging
486 // method. However, the last parameter to the macro LC_LOG has its own
487 // parenthesis - it encloses multiple expressions (a format string and
488 // arguments). So this function object is used as an intermediary in order to
489 // hold the writer mask.
490 //
491 // (*) The mask needs to be transferred separately because we want to keep the
492 // LC_LOG structure of asking if the message is going to be logged before
493 // evaluating the arguments, and we can't store it in the singleton Logging
494 // object - wouldn't be thread-safe.
495
496 class LoggingHelper {
497 public:
498 LoggingHelper(Logging* logger, LogCategory cat,
499 LogLevel level, DWORD writer_mask)
500 : logger_(logger),
501 category_(cat),
502 level_(level),
503 writer_mask_(writer_mask) {}
504
505 void operator()(const wchar_t* fmt, ...) {
506 va_list args;
507 va_start(args, fmt);
508 logger_->LogMessageMaskedVA(writer_mask_, category_, level_, fmt, args);
509 va_end(args);
510 }
511
512 private:
513 Logging* logger_;
514 DWORD writer_mask_;
515 LogLevel level_;
516 LogCategory category_;
517
518 DISALLOW_EVIL_CONSTRUCTORS(LoggingHelper);
519 };
520
521 // Getter for the Logging singleton class.
522 Logging* GetLogging();
523
524 #endif // LOGGING
525
526 } // namespace omaha
527
528 #endif // OMAHA_BASE_LOGGING_H_
OLDNEW
« no previous file with comments | « base/lock_ptr_unittest.cc ('k') | base/logging.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698