chromium中logging日志系统初始化:
void InitLogging(const base::CommandLine& command_line) {
base::FilePath log_filename =
command_line.GetSwitchValuePath(switches::kLogFile);
if (log_filename.empty()) {
#if defined(OS_FUCHSIA)
base::PathService::Get(base::DIR_TEMP, &log_filename);
#else
base::PathService::Get(base::DIR_EXE, &log_filename);
#endif
log_filename = log_filename.AppendASCII("content_shell.log");
}
logging::LoggingSettings settings;
settings.logging_dest = logging::LOG_TO_ALL;//日志保存到文件和系统调式日志
settings.log_file_path = log_filename.value().c_str();//指定日志文件content_shell.log
settings.delete_old = logging::DELETE_OLD_LOG_FILE;//删除旧日志
logging::InitLogging(settings);
logging::SetLogItems(true /* Process ID */, true /* Thread ID */,
true /* Timestamp */, false /* Tick count */);//日志保存项: 进程ID、线程ID、时间戳、tick数
}
日志使用:
1)LOG宏:
LOG就像c++标准库的输出一样重载<<,它有几个常用的等级,
像”VERBOSE“,“INFO”, “WARNING”, “ERROR”, “FATAL”,”NUM_SEVERITIES“等
比如”FATAL”LOG会触发一个断点,并打印出栈回溯信息。
#include "base/logging.h"
LOG(INFO) << "enter " << __FILE__<< " , "<<__FUNCTION__ <<"," << __LINE__;
LOG(INFO) << "info等级 = " << logging::LOG_INFO;
LOG(WARNING) << "WARNING等级 = " << logging::LOG_WARNING;
LOG(ERROR) << "ERROR等级 = " << logging::LOG_ERROR;
LOG(FATAL) << "FATAL等级 = " << logging::LOG_FATAL;
2)LOG_IF宏:
使用LOG_IF宏可以在表达式条件为真的情况下才输出log:
int if_int = 5;
LOG_IF(INFO, if_int < 10 ) << "if_int < 10";
3)CHECK宏:
CHECK宏在表达式为假的情况下执行LOG(FATAL)的效果,
如果没有附加调试器,还会生成一个crash dump。
//CHECK宏,条件失败则产生一个LOG(FATAL)
CHECK(0);
4)DLOG宏:
DLOG跟LOG类似,不同的是DLOG只在DEBUG模式下才生效,
在非DEBUG模式下,这部分代码都不会被编译进程序。
DLOG(INFO) << "DLOG onlg debug";
DLOG_IF(INFO, if_int < 10) << "DLOG_IF onlg debug";
LOG_ASSERT(0);
DLOG_ASSERT(0);
5)VLOG宏:
这是一种可以通过命令行参数动态调整输出log策略的宏,这些宏都是INFO级别的。
VLOG(1) << "I'm printed when you run the program with --v=1 or more";
VLOG(2) << "I'm printed when you run the program with --v=2 or more";
如果不好用命令行传递参数,可以直接在代码中添加如下:
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
// Don't bother initializing |g_vlog_info| unless we use one of the
// vlog switches.
+++ command_line->AppendSwitchASCII(switches::kV,"1");
+++ command_line->AppendSwitchASCII(switches::kVModule,"profile=2,icon_loader=1,browser_*=3,*/chromeos/*=4 --v=0");
if (command_line->HasSwitch(switches::kV) ||
command_line->HasSwitch(switches::kVModule)) {
// NOTE: If |g_vlog_info| has already been initialized, it might be in use
// by another thread. Don't delete the old VLogInfo, just create a second
// one. We keep track of both to avoid memory leak warnings.
CHECK(!g_vlog_info_prev);
g_vlog_info_prev = g_vlog_info;
g_vlog_info =
new VlogInfo(command_line->GetSwitchValueASCII(switches::kV),
command_line->GetSwitchValueASCII(switches::kVModule),
&g_min_log_level);
}
6)trace_event调用跟踪添加log输出:
trace_event原来是chromium用于统计函数体执行时间的方法,稍加改造就可以用于输出特定模块的log。
TRACE_EVENT0("audio", "AudioInputDevice::Start");//例如需要打开audio模块的log
//TRACE_EVENT0宏定义
#define TRACE_EVENT0(category_group, name) \
INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name)
//INTERNAL_TRACE_EVENT_ADD_SCOPED宏定义
#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, ...) \
base::trace_event::BuiltinCategories::TRACE_EVENT0_LOG(category_group,name);\//此处是为了添加log新增的代码
INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
TRACE_EVENT0_LOG的实现如下:
const char* kCategoriesForTbrw3Testing[]= {
"audio"};//可以增加需要打开log的种类
void BuiltinCategories::TRACE_EVENT0_LOG(const char* category, const char* name) {
if (IsStringInArray(category, kCategoriesForTbrw3Testing,
base::size(kCategoriesForTbrw3Testing)))
LOG(INFO) << "suzg---: " << "enter " << category<< " , "<<name;
}
7)web_rtc模块的RTC_LOG:
src\third_party\webrtc_overrides\rtc_base\logging.cc
把log_to_chrome_改为true,即可使用base/logging.cc的logging::LogMessage输出。
打开RTC_DLOG
src\third_party\webrtc_overrides\rtc_base\logging.h
-#define RTC_DLOG_IS_ON 0 //原来是0,强制改为1
+#define RTC_DLOG_IS_ON 1
7)media模块的DVLOG:
DVLOG(1) << "HTMLMediaElement(" << (void*)this << ")";//HTMLMediaElement构造函数里面的log
输出media模块的DVLOG需要media/media_options.gni添加use_t_embedded宏
- enable_logging_override = !use_jumbo_build && is_chromecast
+ enable_logging_override = !use_jumbo_build && (is_chromecast || use_t_embedded)
之后DVLOG即可使用LOG输出,级别的INFO
#define DVLOG(verboselevel) LOG(INFO)