首页 > 其他分享 >GLOG(Google Logging Library) 基本使用

GLOG(Google Logging Library) 基本使用

时间:2024-07-22 10:29:59浏览次数:10  
标签:INFO Google Logging LOG int Library google argv include

安装

Github google logging library
进入glog文件夹

mkdir build
cd build
cmake ..
make -j8
sudo make install

基本demo编译测试

mkdir glog_demo
cd glog_demo
gedit glog_demo.cpp

glog_demo.cpp:

#include <glog/logging.h>

int main(int argc, char* argv[]) {
    // 初始化 glog
    google::InitGoogleLogging(argv[0]);

    // 设置日志输出路径
    google::SetLogDestination(google::INFO, "/path/to/your/logfile.INFO");
    google::SetLogDestination(google::WARNING, "/path/to/your/logfile.WARNING");
    google::SetLogDestination(google::ERROR, "/path/to/your/logfile.ERROR");

    // 记录一些日志
    LOG(INFO) << "This is an informational message";
    LOG(WARNING) << "This is a warning message";
    LOG(ERROR) << "This is an error message";

    // 关闭 glog
    google::ShutdownGoogleLogging();

    return 0;
}

CMakeLists.txt

gedit CMakeLists.txt
cmake_minimum_required (VERSION 3.16)
project (glog_demo VERSION 1.0)

find_package (glog_demo 0.7.0 REQUIRED)

add_executable (glog_demo glog_demo.cpp)
target_link_libraries (glog_demo glog::glog)

Log Level

INFO
WARNING
ERROR
FATAL
如果出现FATAL则终止程序

基本log输出函数

LOG(INFO) << "This is an informational message";
LOG(WARNING) << "This is a warning message";
LOG(ERROR) << "This is an error message";

条件log输出函数

1.判断表达式是否为真,若真则输出:
LOG_IF

#include <glog/logging.h>

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);

    int value = 10;
    LOG_IF(INFO, value > 5) << "Value is greater than 5: " << value;
    LOG_IF(INFO, value < 5) << "This message will not be logged";

    google::ShutdownGoogleLogging();
    return 0;
}

2.每N次调用输出一次log
LOG_EVERY_N

#include <glog/logging.h>

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);

    for (int i = 0; i < 10; ++i) {
        LOG_EVERY_N(INFO, 3) << "This message is logged every 3 iterations. Iteration: " << i;
    }

    google::ShutdownGoogleLogging();
    return 0;
}

3.仅仅前N调用输出log,之后不输出

#include <glog/logging.h>

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);

    for (int i = 0; i < 10; ++i) {
        LOG_FIRST_N(INFO, 3) << "This message is logged only for the first 3 iterations. Iteration: " << i;
    }

    google::ShutdownGoogleLogging();
    return 0;
}

4.每N次调用输出一次log,同时判断表达式条件,为真时输出
LOG_IF_EVERY_N

#include <glog/logging.h>

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);

    int value = 10;
    for (int i = 0; i < 10; ++i) {
        LOG_IF_EVERY_N(INFO, value > 5, 3) << "This message is logged every 3 iterations when value > 5. Iteration: " << i;
    }

    google::ShutdownGoogleLogging();
    return 0;
}

5.当条件为假时记录致命错误并终止程序
LOG_ASSERT

#include <glog/logging.h>

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);

    int value = 10;
    LOG_ASSERT(value == 10) << "Value should be 10";
    // LOG_ASSERT(value == 5) << "This will cause the program to terminate";

    google::ShutdownGoogleLogging();
    return 0;
}

调试模式 DEBUG

提供了一些函数,可以在调试模式下输出log,但是在非调试模式下无效。
DLOG
DLOG_IF
DLOG_EVERY_N
DLOG_IF_EVERY_N
函数使用方法和前面相同。

#include <glog/logging.h>

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);

    int value = 10;
    DLOG(INFO) << "This is a debug message";
    DLOG_IF(INFO, value > 5) << "This debug message is logged when value > 5";
    for (int i = 0; i < 10; ++i) {
        DLOG_EVERY_N(INFO, 3) << "This debug message is logged every 3 iterations. Iteration: " << i;
        DLOG_IF_EVERY_N(INFO, value > 5, 3) << "This debug message is logged every 3 iterations when value > 5. Iteration: " << i;
    }

    google::ShutdownGoogleLogging();
    return 0;
}

判断与断言 CHECK

提供了一系列函数对变量进行关系比较,在必要时终止程序。
CHECK — 检查条件是否为真
具体关系比较函数:
CHECK_EQ 判断是否相等
CHECK_NE 判断是否不相等
CHECK_LT 判断是否小于
CHECK_LE 判断是否小于等于
CHECK_GT 判断是否大于
CHECK_GE 判断是否大于等于

#include <glog/logging.h>

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);

    int x = 5;
    int y = 10;

    CHECK(x < y) << "x should be less than y";
    CHECK_EQ(x + 5, y) << "x + 5 should be equal to y";
    CHECK_NE(x, y) << "x should not be equal to y";
    // CHECK(x > y) << "This will terminate the program because x is not greater than y";

    google::ShutdownGoogleLogging();
    return 0;
}

DEBUG模式下的CHECK

DCHECK_EQ
DCHECK_NE
DCHECK_LT
DCHECK_LE
DCHECK_GT
DCHECK_GE

#include <glog/logging.h>

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);

    int x = 5;
    int y = 10;

    DCHECK(x < y) << "x should be less than y (debug mode only)";
    DCHECK_EQ(x + 5, y) << "x + 5 should be equal to y (debug mode only)";
    DCHECK_NE(x, y) << "x should not be equal to y (debug mode only)";

    google::ShutdownGoogleLogging();
    return 0;
}

其他 Others

1.当条件为真时记录致命日志并终止程序
LOG_IF_FATAL

#include <glog/logging.h>

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);

    int value = 10;
    LOG_IF(FATAL, value > 5) << "Fatal error because value > 5";

    google::ShutdownGoogleLogging();
    return 0;
}

2.只输出一次
LOG_ONCE

#include <glog/logging.h>

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);

    for (int i = 0; i < 10; ++i) {
        LOG_ONCE(INFO) << "This message is logged only once.";
    }

    google::ShutdownGoogleLogging();
    return 0;
}

3.每隔一段时间输出一次
LOG_EVERY_T

#include <glog/logging.h>
#include <chrono>
#include <thread>

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);

    using namespace std::chrono_literals;

    for (int i = 0; i < 100; ++i) {
        LOG_EVERY_T(INFO, 5) << "This message is logged every 5 seconds.";
        std::this_thread::sleep_for(1s);
    }

    google::ShutdownGoogleLogging();
    return 0;
}

4.在某个log级别上输出
LOG_AT_LEVEL

#include <glog/logging.h>

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);

    int log_level = 1; // 0: INFO, 1: WARNING, 2: ERROR, 3: FATAL

    LOG_AT_LEVEL(log_level) << "This message is logged at the specified log level.";

    google::ShutdownGoogleLogging();
    return 0;
}

5.指定级别并判断表达式条件
LOG_IF_AT_LEVEL

#include <glog/logging.h>

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);

    int value = 10;
    int log_level = 1; // 0: INFO, 1: WARNING, 2: ERROR, 3: FATAL

    LOG_IF_AT_LEVEL(log_level, value > 5) << "This message is logged at the specified log level if condition is true.";

    google::ShutdownGoogleLogging();
    return 0;
}

6.将log存入一个string 而不是立即输出
LOG_STRING

#include <glog/logging.h>
#include <sstream>
#include <string>

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);

    std::ostringstream log_stream;
    LOG_STRING(INFO, &log_stream) << "This message is logged to a string stream.";
    std::string log_output = log_stream.str();
    std::cout << "Logged string: " << log_output << std::endl;

    google::ShutdownGoogleLogging();
    return 0;
}

自定义log输出函数(对接接口)

由于LOG等函数仅提供使用<<输出的方式,很多应用场景需要格式化输出。或者是需要自定义log输出函数的使用场景,则可以使用如下方式自定义输出:

#include <glog/logging.h>
#include <cstdarg>
#include <cstdio>

void log_info(const char* format, ...) {
    va_list args;
    va_start(args, format);
    char buffer[1024];
    vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);
    LOG(INFO) << buffer;
}

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);

    // 使用自定义函数进行日志记录
    log_info("This is an informational message with number: %d", 42);

    google::ShutdownGoogleLogging();
    return 0;
}

例如这里通过log_info函数实现了和LOG(INFO)函数同样的功能并提供了格式化输出。
更为简单的,可以使用sprintf函数进行格式化:

#include <glog/logging.h>
#include <string>
#include <cstdio>

int main(int argc, char* argv[]) {
    google::InitGoogleLogging(argv[0]);

    // 使用 sprintf 格式化字符串
    char buffer[100];
    sprintf(buffer, "This is an informational message with number: %d", 42);
    LOG(INFO) << buffer;

    // 使用 fmt::format (如果你使用了 fmt 库)
    // #include <fmt/format.h>
    // std::string msg = fmt::format("This is an informational message with number: {}", 42);
    // LOG(INFO) << msg;

    google::ShutdownGoogleLogging();
    return 0;
}

输出log文件与格式

在前面的demo中,执行后生成3个log文件:
1.INFO output
filename: logfile.INFO20240722-092418.3462

Log file created at: 2024/07/22 09:24:18
Running on machine: wakkk-virtual-machine
Running duration (h:mm:ss): 0:00:00
Log line format: [IWEF]yyyymmdd hh:mm:ss.uuuuuu threadid file:line] msg
I20240722 09:24:18.244402 137523320286784 glog_test.cpp:13] This is an informational message
W20240722 09:24:18.244973 137523320286784 glog_test.cpp:14] This is a warning message
E20240722 09:24:18.245163 137523320286784 glog_test.cpp:15] This is an error message

2.WARNING output
filename: logfile.WARNING20240722-092418.3462

Log file created at: 2024/07/22 09:24:18
Running on machine: wakkk-virtual-machine
Running duration (h:mm:ss): 0:00:00
Log line format: [IWEF]yyyymmdd hh:mm:ss.uuuuuu threadid file:line] msg
W20240722 09:24:18.244973 137523320286784 glog_test.cpp:14] This is a warning message
E20240722 09:24:18.245163 137523320286784 glog_test.cpp:15] This is an error message

3.ERROR output
filename: logfile.ERROR20240722-092418.3462

Log file created at: 2024/07/22 09:24:18
Running on machine: wakkk-virtual-machine
Running duration (h:mm:ss): 0:00:00
Log line format: [IWEF]yyyymmdd hh:mm:ss.uuuuuu threadid file:line] msg
E20240722 09:24:18.245163 137523320286784 glog_test.cpp:15] This is an error message

可见,INFO中会输出INFO WARNING ERROR信息,WARNING中会输出WARNING和ERROR,而ERROR中只有ERROR。
同时,对于ERROR,也会输出至程序所在的终端中(stderr输出)。

LOG输出格式

example:

W20240722 09:24:18.244973 137523320286784 glog_test.cpp:14] This is a warning message

格式描述:

Lyyyymmdd hh:mm:ss.uuuuuu threadid file:line] msg...

在这里插入图片描述

附: logging.h 注释

// Make a bunch of macros for logging.  The way to log things is to stream
// things to LOG(<a particular severity level>).  E.g.,
//
//   LOG(INFO) << "Found " << num_cookies << " cookies";
//
// You can capture log messages in a string, rather than reporting them
// immediately:
//
//   vector<string> errors;
//   LOG_STRING(ERROR, &errors) << "Couldn't parse cookie #" << cookie_num;
//
// This pushes back the new error onto 'errors'; if given a nullptr pointer,
// it reports the error via LOG(ERROR).
//
// You can also do conditional logging:
//
//   LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
//
// You can also do occasional logging (log every n'th occurrence of an
// event):
//
//   LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie";
//
// The above will cause log messages to be output on the 1st, 11th, 21st, ...
// times it is executed.  Note that the special google::COUNTER value is used
// to identify which repetition is happening.
//
// You can also do occasional conditional logging (log every n'th
// occurrence of an event, when condition is satisfied):
//
//   LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << google::COUNTER
//                                           << "th big cookie";
//
// You can log messages the first N times your code executes a line. E.g.
//
//   LOG_FIRST_N(INFO, 20) << "Got the " << google::COUNTER << "th cookie";
//
// Outputs log messages for the first 20 times it is executed.
//
// Analogous SYSLOG, SYSLOG_IF, and SYSLOG_EVERY_N macros are available.
// These log to syslog as well as to the normal logs.  If you use these at
// all, you need to be aware that syslog can drastically reduce performance,
// especially if it is configured for remote logging!  Don't use these
// unless you fully understand this and have a concrete need to use them.
// Even then, try to minimize your use of them.
//
// There are also "debug mode" logging macros like the ones above:
//
//   DLOG(INFO) << "Found cookies";
//
//   DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
//
//   DLOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie";
//
// All "debug mode" logging is compiled away to nothing for non-debug mode
// compiles.
//
// We also have
//
//   LOG_ASSERT(assertion);
//   DLOG_ASSERT(assertion);
//
// which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion;
//
// There are "verbose level" logging macros.  They look like
//
//   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";
//
// These always log at the INFO log level (when they log at all).
// The verbose logging can also be turned on module-by-module.  For instance,
//    --vmodule=mapreduce=2,file=1,gfs*=3 --v=0
// will cause:
//   a. VLOG(2) and lower messages to be printed from mapreduce.{h,cc}
//   b. VLOG(1) and lower messages to be printed from file.{h,cc}
//   c. VLOG(3) and lower messages to be printed from files prefixed with "gfs"
//   d. VLOG(0) and lower messages to be printed from elsewhere
//
// The wildcarding functionality shown by (c) supports both '*' (match
// 0 or more characters) and '?' (match any single character) wildcards.
//
// There's also VLOG_IS_ON(n) "verbose level" condition macro. To be used as
//
//   if (VLOG_IS_ON(2)) {
//     // do some logging preparation and logging
//     // that can't be accomplished with just VLOG(2) << ...;
//   }
//
// There are also VLOG_IF, VLOG_EVERY_N and VLOG_IF_EVERY_N "verbose level"
// condition macros for sample cases, when some extra computation and
// preparation for logs is not needed.
//   VLOG_IF(1, (size > 1024))
//      << "I'm printed when size is more than 1024 and when you run the "
//         "program with --v=1 or more";
//   VLOG_EVERY_N(1, 10)
//      << "I'm printed every 10th occurrence, and when you run the program "
//         "with --v=1 or more. Present occurrence is " << google::COUNTER;
//   VLOG_IF_EVERY_N(1, (size > 1024), 10)
//      << "I'm printed on every 10th occurrence of case when size is more "
//         " than 1024, when you run the program with --v=1 or more. ";
//         "Present occurrence is " << google::COUNTER;
//
// The supported severity levels for macros that allow you to specify one
// are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL.
// Note that messages of a given severity are logged not only in the
// logfile for that severity, but also in all logfiles of lower severity.
// E.g., a message of severity FATAL will be logged to the logfiles of
// severity FATAL, ERROR, WARNING, and INFO.
//
// There is also the special severity of DFATAL, which logs FATAL in
// debug mode, ERROR in normal mode.
//
// Very important: logging a message at the FATAL severity level causes
// the program to terminate (after the message is logged).
//
// Unless otherwise specified, logs will be written to the filename
// "<program name>.<hostname>.<user name>.log.<severity level>.", followed
// by the date, time, and pid (you can't prevent the date, time, and pid
// from being in the filename).
//
// The logging code takes two flags:
//     --v=#           set the verbose level
//     --logtostderr   log all the messages to stderr instead of to logfiles

// LOG LINE PREFIX FORMAT
//
// Log lines have this form:
//
//     Lyyyymmdd hh:mm:ss.uuuuuu threadid file:line] msg...
//
// where the fields are defined as follows:
//
//   L                A single character, representing the log level
//                    (eg 'I' for INFO)
//   yyyy             The year
//   mm               The month (zero padded; ie May is '05')
//   dd               The day (zero padded)
//   hh:mm:ss.uuuuuu  Time in hours, minutes and fractional seconds
//   threadid         The space-padded thread ID as returned by GetTID()
//                    (this matches the PID on Linux)
//   file             The file name
//   line             The line number
//   msg              The user-supplied message
//
// Example:
//
//   I1103 11:57:31.739339 24395 google.cc:2341] Command line: ./some_prog
//   I1103 11:57:31.739403 24395 google.cc:2342] Process id 24395
//
// NOTE: although the microseconds are useful for comparing events on
// a single machine, clocks on different machines may not be well
// synchronized.  Hence, use caution when comparing the low bits of
// timestamps from different machines.

// Log messages below the GOOGLE_STRIP_LOG level will be compiled away for
// security reasons. See LOG(severity) below.

// A few definitions of macros that don't generate much code.  Since
// LOG(INFO) and its ilk are used all over our code, it's
// better to have compact code for these operations.

标签:INFO,Google,Logging,LOG,int,Library,google,argv,include
From: https://blog.csdn.net/m0_54943420/article/details/140601340

相关文章

  • 哪个 Python 框架可以在 Google Collab 中显示和更改图像?
    我希望能够在使用GoogleCollab时为RL绘制高fps的位图。我现在可以使用OpenCV绘制图像cv2_imshowgoogle替换cv2.imshow但是,它无法替换现有图像,它下面绘制了新的我能够在替换imshow函数中使用一些JavaScript来修复它。但刷新率约为......
  • 如何使用Python进行“google”“bing”“yahoo”搜索?
    我一直在谷歌上搜索要使用的API,但它们似乎都已弃用或不再使用。还有其他方法可以进行搜索并获取结果吗?我的目标是“重新创建”|||盲目搜索但我将使用一组预定义的术语来使用python进行搜索,而不是用户输入术语。感谢您的任何输入!Thanksforanyinput!......
  • Standard Template Libary or C++ Standard Library
    C++提供一套标准的library称为C++standardlibrary完全以template完成,所以又被称为StandardTemplateLibrary。这套library专门有于实现常用的据结构(例如arry、list......)以及常用的算法(例如push,pop,insert,delete,query,retrieval......)。一般来说,STL包含六个主要的组件......
  • Google OAuth2 redirect_uri_mismatch 在生产中出现错误,但在本地工作
    我正在开发一个项目,需要使用OAuth2身份验证更新组织的GoogleDrive令牌。我的代码在本地计算机上运行良好,但是当我将其部署到服务器时,遇到无效的错误redirect_url。这是我的代码的相关部分:defupdate_drive_gtoken(data:schema.UpdateDriveToken,sql:Session,......
  • Libtorch与QTOpenCV 和 Point Cloud Library 一起使用时出现错误
    我正在尝试在项目中使用libtorch、qt小部件、点云库(pcl)和opencv。对于这个项目,我使用的是cmake列表。问题是当我同时使用所有四个库时,libtorch会抛出错误。如果我使用libtorch、opencv和qt,一切正常,如果我使用pclqt和opencv,一切也都很好。我得到的错误列在下面:/libto......
  • 用于检查 Google Gemini 支持的所有 GenerativeAI 模型的 Python 代码是什么?
    作为GenerativeAI世界的新手,我正在尝试加载预先训练的文本生成模型并做一些不起作用的事情。这就是我加载GenerativeAI模型的方式。fromvertexai.generative_modelsimportGenerativeModelgeneration_model=GenerativeModel("gemini-pro")由于它不......
  • 使用Java和Google Guava简化开发
    使用Java和GoogleGuava简化开发大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!GoogleGuava是Google开发的一个Java开源库,它提供了许多工具和库来简化Java开发。Guava提供了从集合类到缓存、字符串处理、并发工具等多种功能。本篇文章将介绍如......
  • 日常记录-GoogleASuth 认证
     1.依赖<!--googleauth--><dependency>      <groupId>com.warrenstrange</groupId>      <artifactId>googleauth</artifactId>      <version>1.4.0</version></dependency><dependency>     ......
  • 如何利用谷歌日历(Google Calendar)高效时间管理「超详细版」
    前言接上篇,回顾点击进入:如何实现高效的时间管理?推荐两款你一定在用的软件如何实现高效的时间管理?推荐两款你一定在用的软件在这个快节奏的时代,时间管理对于提高工作效率和生活质量至关重要。谷歌日历(GoogleCalendar)是一个强大的时间管理工具,可以帮助你更好地规划和跟踪你......
  • Google 常用语法说明
    Google常用语法说明背景GoogleHacking,作为一种利用谷歌搜索引擎的强大能力来挖掘互联网中敏感或未公开信息的技巧,已成为安全研究、漏洞挖掘及信息搜集领域的重要工具。通过精心构造的搜索查询,用户可以轻松地发现从轻微的安全疏忽(如遗留的后门、未加密的后台入口)到严重的信息......