【日志工具】g3log_4_API接口描述

g3log是一个日志库,提供了如LOG和LOG_IF这样的API用于流式和printf样式的日志记录。LOG_IF允许条件性记录日志,而CHECK宏用于契约式编程,当条件不满足时会导致进程关闭。日志级别包括DEBUG,INFO,WARNING和FATAL,可以在运行时启用或禁用。CMake选项可用于定制如改变日志级别、动态启用/禁用级别等。此外,g3log支持自定义日志级别和多种sink(如文件接收器),并且在致命错误发生时能捕获堆栈信息并确保日志刷新。
摘要由CSDN通过智能技术生成

API描述

使用g3log所需的大部分API都在本文件中进行了描述,有关更多API文档和示例,请继续阅读 API readme,你会找到一些例子如这里所示:

日志API: LOG调用

LOG调用可以采用流LOG(INFO) << "some text" 或类似printf的 LOGF(WARNING, "some number %d", 123)语法。

条件日志记录可以采用LOG_IF(INFO, <boolean-expression>) << " some text" LOGF_IF(WARNING, <boolean-expression>) << " some text". 的方式,且仅当表达式值为 true才会被记录到日志中。

例如: LOG_IF(INFO, 1 != 200) << " some text";LOG_IF(FATAL, SomeFunctionCall()) << " some text";

一段使用致命崩溃级别的日志调用, 例如LOG_IF(FATAL,...) , 日志会将FATAL级别的消息记录,同时也会杀死进程,它的本质和 CHECK(<boolea-expression>) << ...类似,不同的是 CHECK(<boolean-expression) 结果为false

契约式API: CHECK调用

契约式API和日志API类似,都有 CHECK(<boolean-expression>) << ... 流方式,或 (*) CHECKF(<boolean-expression>, ...)printf方式。

如果<boolean-expression> 值为false,检查失败的消息将以FIFO的顺序与之前已经生成的消息被一起记录,在消息被发送到接收器并且接收器已经处理了致命的契约消息之后,该进程将关闭。

(* * CHECK_F(<boolean-expression>, ...); 类似之前的CHECK类printf式API,它跟 CHECKF 完全相同,且保持向后兼容性 * )

日志级别

默认的日志记录级别是DEBUG, INFO, WARNINGFATAL (参考FATAL用法above),日志记录级别定义在loglevels.hpp.

在某些windows框架中,有一个跟DEBUG日志级别的冲突For some windows framework there is a clash with the logging level. CMake的Build options 有一个选项可以将默认的故障级别从DEBUG 改完 DBUG.

**CMake option: (default OFF) ** cmake -DCHANGE_G3LOG_DEBUG_TO_DBUG=ON ..

在运行时禁用/启用级别

日志记录级别可以在运行时被禁用。这种情况会发生在loglevels.hpp, loglevels.cppg3log.hpp.

有一个cmake选项来使能动态启用/禁用级别,当使能这个选项后,每一个日志记录都会检查这个开关的使能状态,从而导致有一个轻微的运行开销,对于大多数意图和目的,这个运行时开销是可以忽略的。

如果cmake选项被关闭了,那内部的开关检查基本不会有运行开销。如果关闭了动态日志记录cmake选项,则将启用所有日志记录级别。

CMake option: (default OFF) cmake -DUSE_DYNAMIC_LOGGING_LEVELS=ON ..

自定义日志级别

你可以创建和使用自定义日志记录级别,Custom logging levels can be created and used. 当自定义自定义日志记录级别时,您可以设置它的值以及它的文本。你可以重新利用诸如INFO, WARNING 等其他或你自己定义的值, 任何一个等于或大于FATAL的日志都将被记录到FATAL级别的日志中。

添加你自己的自定义级别时请记住

  1. 如果cmake 选项 G3_DYNAMIC_LOGGING 被使能,你必须使用 g3::only_change_at_initialization::addLogLevel(...) 来给g3log一个你的日志级别的记录,同时确定它是否启用。
  2. 如果cmake选项 G3_DYNAMIC_LOGGING 被关闭,那么利用addLogLevel(...) 给g3log一个你的日志级别的记录是不需要的,同时所有的日志记录级别都被被视为已启用。

例如:

// In CustomLoggingLevels.hpp
#include <g3log/loglevels.hpp>

// all values with a + 1 higher than their closest equivalet
// they could really have the same value as well.

const LEVELS FYI {DEBUG.value + 1, {"For Your Information"}}; 
const LEVELS CUSTOM {INFO.value + 1, {"CUSTOM"}}; 
const LEVELS SEVERE {WARNING.value +1, {"SEVERE"}};
const LEVELS DEADLY {FATAL.value + 1, {"DEADLY"}}; 

更多的例子可以参考 unit tests.

Sink的创建和使用

g3log默认的sink是g2log中使用的sink,它是一个具有有限API的简单文件接收器,有关默认文件接收器的详细信息,你可以在这里查阅 filesink.hpp, filesink.cpp, filesinkhelper.ipp

更多的sinks可以在g3sinks 找到(log rotate, log rotate with filtering on levels)

日志记录接收器不必是特定类型的子类。日志接收器的唯一要求是,它可以接收日志消息。

使用默认sink

Sink的创建被定义在logworker.hpp ,使用在 logworker.cpp. 有关更深层的调用可以查阅 sinkhandle.hppsinkwrapper.hpp

  std::unique_ptr<FileSinkHandle> addDefaultLogger(
            const std::string& log_prefix
            , const std::string& log_directory
            , const std::string& default_id = "g3log");

在单元测试"test_filechange"中创建的默认的日志记录器如下所示:

  const std::string directory = "./";
  const std::string name = "(ReplaceLogFile)";
  auto worker = g3::LogWorker::createLogWorker();
  auto handle = worker->addDefaultLogger(name, directory);

得到的文件名应该是这样的:

   ./(ReplaceLogFile).g3log.20160217-001406.log

指定sink的日志接收函数

默认的日志格式可以被任意sink覆盖重写,如果sink接收函数调用 toString() ,默认日志格式将被启用The default log formatting look can be overriden by any sink. If the sink receiving function calls toString() then the default log formatting will be used. 如果sink接收 toString(&XFunc) 函数被调用,那么将会被XFunc替代使用(如果代码细节不清楚,请查阅 LogMessage.h/cpp ). (XFunc 是可以选择放置自定义函数的地方)。

这里有一个传递指针的函数:

std::string (*) (const LogMessage&)

也可以在 LogMessage.h 被定义:

using LogDetailsFunc = std::string (*) (const LogMessage&);

日志格式自定义

请查阅API_custom_formatting.md

日志刷新(记录)

默认的文件接收器将在每个日志进入时刷新(记录)它,对于不同的刷新(记录)策略,请查看g3sinks logrotate and LogRotateWithFilters.

在程序关闭时,所有加入队列的日志都将被刷新(记录)到接收器。
在发现致命崩溃事件(SIGSEGV等)时,所有加入队列的日志都将刷新(记录)到接收器。

以编程方式触发的突然进程退出,例如调用 exit(0) 将不会记录已加入队列的日志。这就类似于一个bug,它不会触发一个致命的信号,但是进程退出也不会使加入队列的日志条目被刷新(记录)。G3log可以捕获几个致命的崩溃,它可以很好地处理RAII退出,但魔术是如此遥不可及。

G3log和sink用法代码示例

加入了 logrotate sink (g3sinks) 的示例用法. 在这个例子中,我们展示了如何调用logrotate API ,logrotate的限制从默认值更改为10MB,通过调用sink处理程序来更改限制,该处理程序将函数调用传递给实际的logrotate sink对象。

// main.cpp
#include <g3log/g3log.hpp>
#include <g3log/logworker.h>
#include <g3sinks/LogRotate.h>
#include <memory>

int main(int argc, char**argv) {
   using namespace g3;
   std::unique_ptr<LogWorker> logworker{ LogWorker::createLogWorker() };
   auto sinkHandle = logworker->addSink(std::make_unique<LogRotate>(),
                                          &LogRotate::save);
   
   // initialize the logger before it can receive LOG calls
   initializeLogging(logworker.get());            
            
   // You can call in a thread safe manner public functions on the logrotate sink
   // The call is asynchronously executed on your custom sink.
   const int k10MBInBytes = 10 * 1024 * 1024;
   std::future<void> received = sinkHandle->call(&LogRotate::setMaxLogSize, k10MBInBytes);
   
   // Run the main part of the application. This can be anything of course, in this example
   // we'll call it "RunApplication". Once this call exits we are in shutdown mode
   RunApplication();

   // If the LogWorker is initialized then at scope exit the g3::shutDownLogging() will be 
   // called automatically. 
   //  
   // This is important since it protects from LOG calls from static or other entities that will go out of
   // scope at a later time. 
   //
   // It can also be called manually if for some reason your setup is different then the one highlighted in
   // this example
   g3::shutDownLogging();
}

动态消息大小调整

默认构建使用固定大小的缓冲区格式化消息。这个缓冲区的大小是2048字节。如果传入消息导致大于2048字节的格式化消息,则该消息将绑定到2048字节,并使用 [...truncated...] 附加到绑定消息的结尾,在某些情况下,我们希望在运行时动态地改变大小。例如,在调试服务器的有效负载时,为了检查整个有效负载,可能需要处理更大的消息大小。比起强迫开发人员重建服务器,在运行时用一个配置文件配置消息的大小的动态调整消息大小得功能是更好的。

作为CMake选项支持此功能:

CMake option: (default OFF) cmake -DUSE_G3_DYNAMIC_MAX_MESSAGE_SIZE=ON ..

下面是更改消息大小的示例。

    g3::only_change_at_initialization::setMaxMessageSize(10000);

致命处理

G3log的默认行为是在强制进程退出之前捕获多个致命事件。 在捕获致命之间后将生成一个堆栈,并且知道堆栈前的所有日志都将被刷新(记录)到sink中。

Linux/*nix

linux的默认致命处理是处理致命信号,在编写诸如 SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM的 信号时, Linux致命处理是在 crashhandler.hppcrashhandler_unix.cpp

通常与自愿进程退出的相关联信号 SIGINT (ctrl + c) G3log不做处理。

致命信号可以被 disabledchanged/added .

Linux 堆栈的一个示例,如致命示例的输出所示g3log-FATAL-sigsegv*. ```***** FATAL SIGNAL RECEIVED ******* "Received fatal signal: SIGSEGV(11) PID: 6571

***** SIGNAL SIGSEGV(11)

******* STACKDUMP *******
        stack dump [1]  ./g3log-FATAL-sigsegv() [0x42a500]
        stack dump [2]  /lib/x86_64-linux-gnu/libpthread.so.0+0x10340 [0x7f83636d5340]

        stack dump [3]  ./g3log-FATAL-sigsegv : example_fatal::tryToKillWithAccessingIllegalPointer(std::unique_ptr<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >)+0x119 [0x4107b9]
        stack dump [4]  ./g3log-FATAL-sigsegvmain+0xdec [0x40e51c]
        stack dump [5]  /lib/x86_64-linux-gnu/libc.so.6__libc_start_main+0xf5 [0x7f8363321ec5]
        stack dump [6]  ./g3log-FATAL-sigsegv() [0x40ffa2]

Exiting after fatal event  (FATAL_SIGNAL). Fatal type:  SIGSEGV
Log content flushed sucessfully to sink

"
g3log g3FileSink shutdown at: 16:33:18

```

自定义致命处理-覆盖默认值

默认情况下,致命信号定义在 https://github.com/KjellKod/g3log/tree/master/src/g3log.cpp as

SIGABRT
SIGFPE
SIGILL
SIGSEGV
SIGTERM

如果您想定义自己的一组致命信号,请覆盖默认信号,那么可以这样做,如src/g3log/crashhandler.hpp

// Example when SIGTERM is skipped due to ZMQ usage
g3::overrideSetupSignals({ {SIGABRT, "SIGABRT"}, 
                           {SIGFPE, "SIGFPE"},
                           {SIGILL, "SIGILL"},
                           {SIGSEGV, "SIGSEGV"}});

前致命钩hook

可以定义一个自定义回调函数,该函数将在致命信号处理重新发出fatal 信号。请查阅 src/g3log/g3log.hpp 获取更多细节

// Example of how to enforce important shutdown cleanup even in the event of a fatal crash: 
g3::setFatalPreLoggingHook([]{ cleanup(); });

禁用致命处理

可以使用CMake选项禁用致命信号处理: ENABLE_FATAL_SIGNALHANDLING. 请查阅 Options.cmake 获取更多细节

PID1致命信号建议

如果你在一个PID1进程上使用g3log,那么你绝对应该提供自己的信号处理(参考:第269期),因为g3log在恢复了该信号的前一个信号处理程序之后重新发射该致命信号。PID1处理完毕关闭一个正常的致命信号的进程,所以在这样的信号后退出PID1进程的选择必须由编码器作出,而不是由g3log作出。

Windows

Windows致命处理也像Linux一样处理致命信号。除了致命的信号之外,它还处理未定义的异常,向量异常。Windows致命处理是在crashhandler.hpp](https://github.com/KjellKod/g3log/tree/master/src/g3log/crashhandler.hpp), crashhandler_windows.cpp, stacktrace_windows.hpp, stacktrace_windows.cpp

Windows堆栈转储的一个示例,如致命示例的输出所示 g3log-FATAL-sigsegv.

黎明就在眼前

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 这是一个URL中的参数串,其中sr_channel=1是指在访问该URL时使用的渠道编号为1,spreader_id=b5g_g3oy_e3d47_e4d是指该URL的传播者ID为b5g_g3oy_e3d47_e4d。一般来说,sr_channel用于统计和区分访问来源,而spreader_id用于追踪该URL的传播者,以方便分析传播效果和进行奖励。例如,在一次营销推广活动中,为了增加参与度,可以让传播者分享该URL,并设置一个spreader_id作为识别码,当其他用户通过该传播者分享的URL进行注册或消费时,可以根据该spreader_id追踪和统计该传播者的贡献,并根据结果给予相应的奖励或回报。所以,在URL中使用sr_channel和spreader_id参数可以方便地实现用户来源和传播者跟踪,为网站运营和营销带来诸多便利。 ### 回答2: 这串代码是一个参数串,其中sr_channel=1表示该链接是从搜索引擎的自然搜索结果中进入的;spreader_id=b5g_g3oy_e3d47_e4d是一个推广者ID,可能是为了追踪和统计某个推广者的推广效果。这种参数串多用于营销等领域,在网站访问统计和分析中也有应用。通过加入参数串,可以方便追踪和分析用户来源和用户行为,为企业的推广和营销带来效益。 ### 回答3: 这个字符串是一个URL中的参数,其中分隔符%3D表示等号,%26表示&符号的编码。sr_channel=1表示搜索通道为1,即使用了特定的搜索渠道进行搜索。spreader_id=b5g_g3oy_e3d47_e4d表示这个搜索是通过某个推广渠道传播的,并且通过这个参数可以追踪传播效果。这种推广方式常见于网页或APP的营销推广,通过不同的推广渠道来吸引更多的流量和用户,并进行推广效果的跟踪分析,以便对推广方式进行优化和改进。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泡泡吐泡泡啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值