玩转小项目之日志库

玩转小项目之日志库

今天分享arrow日志库的设计与实现,所有源码均在星球提供(加入方式见末尾),本次项目重写arrow日志库,将arrow日志库提取出来,整个项目基于bazel构建。

目前支持的特性有:

  • 默认日志格式

  • spdlog日志格式

  • 支持堆栈输出

  • 支持日志在终端打印

  • 支持日志输出至文件

  • 支持日志高亮显示

  • 支持日志插件扩展

  • 支持多种日志级别

先来看第一个特性:默认日志格式输出与终端打印:

➜  light-log bazel-bin/tests/log_test    
tests/log_test.cc:13: This is the INFO message
tests/log_test.cc:15: This is the WARNING message
tests/log_test.cc:17: This is the ERROR message
This is the DEBUG message
tests/log_test.cc:13: This is the INFO message
tests/log_test.cc:15: This is the WARNING message
tests/log_test.cc:17: This is the ERROR message
===============================================================================
test cases: 1 | 1 passed
assertions: - none -

第二个特性:spdlog终端与文件输出:

编译时,通过宏参数控制,只需要传递ARROW_USE_SPDLOG即可。

bazel test //tests:log_test --define ARROW_WITH_BACKTRACE=true --define ARROW_USE_SPDLOG=true
  • 终端打印

[2023-08-16 07:15:14,660 I 21004 41898222] log_test.cc:13: This is the INFO message
[2023-08-16 07:15:14,660 W 21004 41898222] log_test.cc:15: This is the WARNING message
[2023-08-16 07:15:14,661 E 21004 41898222] log_test.cc:17: This is the ERROR message
===============================================================================
test cases: 1 | 1 passed
assertions: - none -
  • 文件输出

玩转小项目之日志库_第1张图片

堆栈特性输出:

➜  light-log bazel-bin/main                                                                       
0   main                                0x0000000105e8d8fb _ZN5arrow4util14PrintBackTraceERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEE + 75
1   main                                0x0000000105ef1937 _ZN5arrow4util13SpdLogMessage5FlushEv + 231
2   main                                0x0000000105ef180c _ZN5arrow4util13SpdLogMessageD2Ev + 28
3   main                                0x0000000105e8f395 _ZN5arrow4util13SpdLogMessageD1Ev + 21
4   main                                0x0000000105e8f34e _ZN5arrow4util8ArrowLogD2Ev + 78
5   main                                0x0000000105e8f3b5 _ZN5arrow4util8ArrowLogD1Ev + 21
6   main                                0x0000000105e8c131 main + 113
7   libdyld.dylib                       0x00007fff2041cf3d start + 1
[2023-08-16 07:20:05,798 C 21937 41909787] test:10: hello logginghello2 logginghello3 logging
*** StackTrace Information ***

[1]    21937 abort      bazel-bin/main

1.实现

1.1 可插拔

通过使用宏:

ARROW_USE_SPDLOG

来达到开关spdlog库的功能。

通过使用宏:

ARROW_WITH_BACKTRACE

来达到堆栈是否输出的功能。

实现层面,抽象出公共基类:

class ARROW_EXPORT ArrowLogBase {
 public:
  virtual ~ArrowLogBase() {}

  virtual bool IsEnabled() const { return false; }

  template 
  ArrowLogBase& operator<<(const T& t) {
    if (IsEnabled()) {
      Stream() << t;
    }
    return *this;
  }

 protected:
  virtual std::ostream& Stream() = 0;
};

所有日志扩展通过继承的方式实现这些接口。

对于所有的扩展,采用typedef来实现可扩展性。

#ifdef ARROW_USE_SPDLOG
typedef SpdLogMessage LoggingProvider;
#else
typedef CerrLog LoggingProvider;
#endif

1.2 宏

沿用arrow原始的宏定义,只需要简单的ARROW_LOG便可以输出各种日志级别的日志。

ARROW_LOG(ARROW_DEBUG) << "This is the"
                         << " DEBUG"
                         << " message";

1.3 日志级别

通过枚举实现,覆盖所有日志级别。

enum class ArrowLogLevel : int {
  ARROW_TRACE = -2,
  ARROW_DEBUG = -1,
  ARROW_INFO = 0,
  ARROW_WARNING = 1,
  ARROW_ERROR = 2,
  ARROW_FATAL = 3
};

所有源码已在星球开放,欢迎加入~

玩转小项目之日志库_第2张图片

你可能感兴趣的:(玩转小项目之日志库)