【日志工具】g3log_4_API接口描述

2023-05-16

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.cpp 和 g3log.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.hpp 和 sinkwrapper.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.hpp 和 crashhandler_unix.cpp。

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

致命信号可以被 disabled 或changed/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.

黎明就在眼前

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【日志工具】g3log_4_API接口描述 的相关文章

  • 当前平台不支持桌面 API

    我遇到过这个错误 java lang UnsupportedOperationException 当前平台不支持桌面 API 我将从我的 java 应用程序中打开一个文件 我用这个方法 Desktop getDesktop open new
  • RESTful API:我应该在哪里编码我的工作流程?

    我正在开发一个 RESTful API 这是我的第一个 API 也是我的第一个真正大型的编码项目 因此 我仍在学习很多关于建筑等方面的知识 目前 我的 api 设置分为以下几层 HTTP层 资源层 领域模型 业务逻辑层 数据访问 存储层 持
  • Elasticsearch GET API 获取分片大小

    在 Elasticsearch 2 3 3 中 有没有办法使用返回 JSON 的 GET API 获取分片大小 目前我找到了以下几种获取shard size的方法 这两种方法都存在问题 recovery gt 使用 JSON 进行响应并提供
  • 创建rest api url以连接mysql数据库

    我想学习如何创建一个rest api url 以便我可以使用该url获取信息并将信息发布到我的mysql数据库中 谷歌搜索了很多并阅读了各种文章 但没有找到任何精确的内容可以学习 所有内容均以 about api 开头 以已创建的其余 ur
  • 限制传出 PHP+curl 请求的速率

    有没有办法限制 有延迟 向外部服务器发出 PHP curl 请求的速率 以便每秒只有 n 个请求 PHP 在 Fastcgi 模式下使用 因此无法使用睡眠 是的 有curl 多重处理程序 您可以使用 OOP 方式以 OOP 方式完成此操作这
  • 如何在 .NET 应用程序中使用 W3C 标记验证器 API?

    我发现有一个W3C 标记验证器的 API http validator w3 org docs api html 我之前曾问过 是否有适用于 W3C 标记验证器 API 的 NET 库 https stackoverflow com que
  • Google BigQuery 与 PHP 集成

    我需要帮助将 google bigquery 代码集成到 PHP 中 所以我可以从 php 代码本身执行查询和其他类型的操作 需要您的帮助并建议我一些工作示例链接 提前致谢 这是一段代码 正确地创建一个Google Client using
  • 如何使用 Visual C++ 在 win32 API 中创建圆形/圆形按钮

    我有一个 Visual C 中的 Window Win32 API 应用程序 我没有使用MFC 我必须创建一个带有位图图像的圆形 圆形按钮 我的应用程序有一个皮肤视图 任何人都可以帮助我完成这项任务吗 按钮是窗口 您可以使用 CreateW
  • 访问应用程序,带有表单任务栏图标的隐藏应用程序窗口

    我有一个带有一个主表单的访问应用程序 当您打开应用程序时 AutoExec 宏会通过 Windows API apiShowWindow 隐藏应用程序 然后 AutoExec 打开设置为 Popup 的主窗体 这一切都很顺利 我的数据库内容
  • 如何查询所有国家的所有iTunes店面?

    我的 iTunes appID 为 9 位数 当我在美国商店查询 iTunes 时http itunes apple com us app id508611913 http itunes apple com us app id5086119
  • MongoRuntimeError:连接池已关闭

    我看到我的猫鼬池在插入数据之前似乎已关闭 因为在调用云集群中的猫鼬数据库时出现此错误 MongoRuntimeError Connection pool closed 但我正在等待所有的电话 所以我不确定为什么会看到这个问题 也许这与我定义
  • 如何获取 Twitter 上发布的 foursquare 签到的位置(纬度、经度)?

    我使用 Twitter API 搜索带有 4sq com 的所有公共推文 http search twitter com search json q 4sq com http search twitter com search json q
  • 库和 API 之间还有区别吗?

    每当我询问人们 API 和库之间的区别时 我都会得到不同的意见 有的给这种 http mail python org pipermail tutor 2002 May 014458 html定义 API 是规范 库是实现 有些会告诉你这个类
  • 图形批量API

    这是我在 stackoverflow 上的第一篇文章 我正在使用 Facebook Graph Batch API 一次请求多个用户的 Feed 更新 但我真的不知道如何进行适当的错误处理 下面的例子应该说明我的问题 批量请求 user1
  • org.apache.http 软件包在 API 级别 23 中被删除。替代方案是什么?

    在更新到最新的 android API 级别 23 Marshmallow 后 通过 build gradle 添加以下更改后 所有 org apache http 类都不起作用 android compileSdkVersion 23 b
  • 如何使用 Azure DevOps 的 python 客户端 API 将用户添加到 Azure DevOps?

    我正在编写一个 python 脚本来将用户 来自 AAD 支持的提供商的现有用户 添加到 Azure DevOps 我正在使用 Azure DevOps 的 python 客户端库来实现此目的 身份验证后 我可以从 azure devops
  • 字典 API(词汇)[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有人知道一个好的 NET 字典 API 吗 我对含义不感兴趣 而是我需要能够以多种不同的方式查询单词 返
  • 如何在 Google 知识图谱中搜索具有特定属性的条目?

    应如何制定搜索查询kgsearch googleapis com查找给定类别中的所有条目 例如 如果我想搜索 Schema org 类别中的内容应用类别 http schema org applicationCategory 我该怎么办呢
  • Canvas.drawVertices(...) 不绘制任何内容

    下一类是红色三角形的视图 public class FreeStyleViewII extends View private final Paint paint new Paint private final int colors new
  • Spring @RequestMapping 带有可选参数

    我的控制器在请求映射中存在可选参数的问题 请查看下面的控制器 GetMapping produces MediaType APPLICATION JSON VALUE public ResponseEntity

随机推荐