From ff4904ca96d14672124b3375db56f92b645252ca Mon Sep 17 00:00:00 2001 From: Kevin Li Date: Thu, 25 Jul 2024 19:07:02 +0800 Subject: [PATCH] add example with glog --- README.md | 1 + example/anyflow/MODULE.bazel | 2 +- example/depend-use-bzlmod/MODULE.bazel | 2 +- example/depend-use-bzlmod/README.md | 2 +- example/depend-use-cmake-fetch/CMakeLists.txt | 4 +- example/depend-use-cmake-fetch/README.md | 4 +- example/depend-use-cmake-find/build.sh | 6 +- example/depend-use-cmake-subdir/build.sh | 6 +- example/use-arena-with-brpc/MODULE.bazel | 2 +- example/use-async-logger/.bazelrc | 1 - example/use-async-logger/README.md | 2 +- example/use-async-logger/example.cpp | 23 +++-- example/use-counter-with-bvar/MODULE.bazel | 2 +- example/use-with-bthread/MODULE.bazel | 2 +- example/use-with-glog/.bazelrc | 5 + example/use-with-glog/.bazelversion | 1 + example/use-with-glog/BUILD | 8 ++ example/use-with-glog/MODULE.bazel | 2 + example/use-with-glog/README.md | 82 ++++++++++++++++ example/use-with-glog/build.sh | 4 + example/use-with-glog/example.cpp | 96 +++++++++++++++++++ 21 files changed, 230 insertions(+), 27 deletions(-) create mode 100644 example/use-with-glog/.bazelrc create mode 100644 example/use-with-glog/.bazelversion create mode 100644 example/use-with-glog/BUILD create mode 100644 example/use-with-glog/MODULE.bazel create mode 100644 example/use-with-glog/README.md create mode 100755 example/use-with-glog/build.sh create mode 100644 example/use-with-glog/example.cpp diff --git a/README.md b/README.md index 3fbb390f..9337e8c8 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ Babylon也支持使用[CMake](https://cmake.org)进行构建,并支持通过[f - [:future](docs/future.md) - [:logging](docs/logging/index.md) - [Use async logger](example/use-async-logger) + - [Use with glog](example/use-with-glog) - [:reusable](docs/reusable/index.md) - [:serialization](docs/serialization.md) - [:time](docs/time.md) diff --git a/example/anyflow/MODULE.bazel b/example/anyflow/MODULE.bazel index 127e7433..44e670d1 100644 --- a/example/anyflow/MODULE.bazel +++ b/example/anyflow/MODULE.bazel @@ -1 +1 @@ -bazel_dep(name = 'babylon', version = '1.2.2') +bazel_dep(name = 'babylon', version = '1.3.0') diff --git a/example/depend-use-bzlmod/MODULE.bazel b/example/depend-use-bzlmod/MODULE.bazel index 127e7433..44e670d1 100644 --- a/example/depend-use-bzlmod/MODULE.bazel +++ b/example/depend-use-bzlmod/MODULE.bazel @@ -1 +1 @@ -bazel_dep(name = 'babylon', version = '1.2.2') +bazel_dep(name = 'babylon', version = '1.3.0') diff --git a/example/depend-use-bzlmod/README.md b/example/depend-use-bzlmod/README.md index 04d40b06..b62b5711 100644 --- a/example/depend-use-bzlmod/README.md +++ b/example/depend-use-bzlmod/README.md @@ -15,7 +15,7 @@ common --registry=https://raw.githubusercontent.com/bazelboost/registry/main - 增加依赖项 ``` # in MODULE.bazel -bazel_dep(name = 'babylon', version = '1.2.2') +bazel_dep(name = 'babylon', version = '1.3.0') ``` - 添加依赖的子模块到编译目标,全部可用子模块可以参照[模块功能文档](../../README.md#模块功能文档),或者[BUILD](../../BUILD)文件,也可以直接添加All in One依赖目标`@babylon` diff --git a/example/depend-use-cmake-fetch/CMakeLists.txt b/example/depend-use-cmake-fetch/CMakeLists.txt index fc8f47bd..d30102c5 100644 --- a/example/depend-use-cmake-fetch/CMakeLists.txt +++ b/example/depend-use-cmake-fetch/CMakeLists.txt @@ -5,8 +5,8 @@ set(BUILD_DEPS ON) include(FetchContent) FetchContent_Declare( babylon - URL "https://github.com/baidu/babylon/archive/refs/tags/v1.2.2.tar.gz" - URL_HASH SHA256=241d0d3e8bf89c9b47765c794aa5153f73b32a7f419c48d8aeeeb4461cf8aec7 + URL "https://github.com/baidu/babylon/archive/refs/tags/v1.3.0.tar.gz" + URL_HASH SHA256=4a8582db91e1931942555400096371586d0cf06ecaac0841aca652ef6d77aef0 ) FetchContent_MakeAvailable(babylon) diff --git a/example/depend-use-cmake-fetch/README.md b/example/depend-use-cmake-fetch/README.md index 8b6aaf4b..6390c123 100644 --- a/example/depend-use-cmake-fetch/README.md +++ b/example/depend-use-cmake-fetch/README.md @@ -10,8 +10,8 @@ set(BUILD_DEPS ON) include(FetchContent) FetchContent_Declare( babylon - URL "https://github.com/baidu/babylon/archive/refs/tags/v1.2.2.tar.gz" - URL_HASH SHA256=241d0d3e8bf89c9b47765c794aa5153f73b32a7f419c48d8aeeeb4461cf8aec7 + URL "https://github.com/baidu/babylon/archive/refs/tags/v1.3.0.tar.gz" + URL_HASH SHA256=4a8582db91e1931942555400096371586d0cf06ecaac0841aca652ef6d77aef0 ) FetchContent_MakeAvailable(babylon) ``` diff --git a/example/depend-use-cmake-find/build.sh b/example/depend-use-cmake-find/build.sh index 4435bad2..9a3d1ba8 100755 --- a/example/depend-use-cmake-find/build.sh +++ b/example/depend-use-cmake-find/build.sh @@ -1,9 +1,9 @@ #!/bin/sh set -ex -URL=https://github.com/baidu/babylon/archive/refs/tags/v1.2.2.tar.gz -NAME=babylon-1.2.2 -SHA256=241d0d3e8bf89c9b47765c794aa5153f73b32a7f419c48d8aeeeb4461cf8aec7 +URL=https://github.com/baidu/babylon/archive/refs/tags/v1.3.0.tar.gz +NAME=babylon-1.3.0 +SHA256=4a8582db91e1931942555400096371586d0cf06ecaac0841aca652ef6d77aef0 if ! echo "$SHA256 $NAME.tar.gz" | sha256sum -c; then wget $URL --continue -O $NAME.tar.gz fi diff --git a/example/depend-use-cmake-subdir/build.sh b/example/depend-use-cmake-subdir/build.sh index 299094af..37ab9397 100755 --- a/example/depend-use-cmake-subdir/build.sh +++ b/example/depend-use-cmake-subdir/build.sh @@ -1,9 +1,9 @@ #!/bin/sh set -ex -URL=https://github.com/baidu/babylon/archive/refs/tags/v1.2.2.tar.gz -NAME=babylon-1.2.2 -SHA256=241d0d3e8bf89c9b47765c794aa5153f73b32a7f419c48d8aeeeb4461cf8aec7 +URL=https://github.com/baidu/babylon/archive/refs/tags/v1.3.0.tar.gz +NAME=babylon-1.3.0 +SHA256=4a8582db91e1931942555400096371586d0cf06ecaac0841aca652ef6d77aef0 if ! echo "$SHA256 $NAME.tar.gz" | sha256sum -c; then wget $URL --continue -O $NAME.tar.gz fi diff --git a/example/use-arena-with-brpc/MODULE.bazel b/example/use-arena-with-brpc/MODULE.bazel index 4cc8799c..895acd9e 100644 --- a/example/use-arena-with-brpc/MODULE.bazel +++ b/example/use-arena-with-brpc/MODULE.bazel @@ -1,4 +1,4 @@ -bazel_dep(name = 'babylon', version = '1.2.2') +bazel_dep(name = 'babylon', version = '1.3.0') bazel_dep(name = 'brpc', version = '1.9.0') bazel_dep(name = 'tcmalloc', version = '0.0.0-20240411-5ed309d') single_version_override(module_name = 'protobuf', version = '25.3.arenastring') diff --git a/example/use-async-logger/.bazelrc b/example/use-async-logger/.bazelrc index c621be71..6cf21e09 100644 --- a/example/use-async-logger/.bazelrc +++ b/example/use-async-logger/.bazelrc @@ -1,6 +1,5 @@ common --registry=https://bcr.bazel.build common --registry=https://baidu.github.io/babylon/registry -common --registry=file:///home/oathdruid/src/babylon/registry common --registry=https://raw.githubusercontent.com/bazelboost/registry/main build --compilation_mode opt --copt=-O3 --cxxopt=-std=c++17 diff --git a/example/use-async-logger/README.md b/example/use-async-logger/README.md index b7ade615..8b21b3d6 100644 --- a/example/use-async-logger/README.md +++ b/example/use-async-logger/README.md @@ -1,4 +1,4 @@ -# Use concurrent counter optimize bvar +# Use async logger ## 示例构成 diff --git a/example/use-async-logger/example.cpp b/example/use-async-logger/example.cpp index d9dc3c08..3771b6f4 100644 --- a/example/use-async-logger/example.cpp +++ b/example/use-async-logger/example.cpp @@ -3,7 +3,6 @@ #include "brpc/server.h" #include "gflags/gflags.h" - #include "spdlog/async.h" #include "spdlog/sinks/basic_file_sink.h" #include "spdlog/spdlog.h" @@ -73,10 +72,14 @@ void setup_babylon() { return ::bvar::Stat {summary.sum, static_cast(summary.num)}; } }; - static ::bvar::PassiveStatus pending_size {"test-babylon-pending", S::get_pending_size, nullptr}; - static ::bvar::PassiveStatus free_page_num {"test-babylon-free", S::get_free_page_num, nullptr}; - static ::bvar::PassiveStatus<::bvar::Stat> hit_summary {S::get_hit_summary, nullptr}; - static ::bvar::Window<::bvar::PassiveStatus<::bvar::Stat>> hit_summary_win {"test-babylon-hit", &hit_summary, -1}; + static ::bvar::PassiveStatus pending_size { + "test-babylon-pending", S::get_pending_size, nullptr}; + static ::bvar::PassiveStatus free_page_num { + "test-babylon-free", S::get_free_page_num, nullptr}; + static ::bvar::PassiveStatus<::bvar::Stat> hit_summary {S::get_hit_summary, + nullptr}; + static ::bvar::Window<::bvar::PassiveStatus<::bvar::Stat>> hit_summary_win { + "test-babylon-hit", &hit_summary, -1}; } void setup_brpc() { @@ -94,7 +97,8 @@ void setup_brpc() { void setup_spdlog() { ::spdlog::set_pattern("%l %Y-%m-%d %H:%M:%S.%f %t %s:%#] %v"); ::spdlog::init_thread_pool(262144, 1); - auto async_file = ::spdlog::basic_logger_mt<::spdlog::async_factory>("async_file_logger", FLAGS_benchmark ? "/dev/null" : "log/name.log"); + auto async_file = ::spdlog::basic_logger_mt<::spdlog::async_factory>( + "async_file_logger", FLAGS_benchmark ? "/dev/null" : "log/name.log"); ::spdlog::set_default_logger(async_file); } @@ -115,14 +119,15 @@ void run_once_spdlog(size_t round) { void run_loop() { ::bvar::LatencyRecorder latency {"test-" + FLAGS_mode}; - int64_t expect_us = 1000.0 * 1000 / FLAGS_qps * FLAGS_batch * FLAGS_concurrency; + int64_t expect_us = + 1000.0 * 1000 / FLAGS_qps * FLAGS_batch * FLAGS_concurrency; void (*run_once)(size_t); if (FLAGS_mode == "babylon") { run_once = run_once_babylon; - } else if (FLAGS_mode == "brpc") { + } else if (FLAGS_mode == "brpc") { run_once = run_once_brpc; - } else if (FLAGS_mode == "spdlog") { + } else if (FLAGS_mode == "spdlog") { run_once = run_once_spdlog; } ::std::vector<::std::thread> threads; diff --git a/example/use-counter-with-bvar/MODULE.bazel b/example/use-counter-with-bvar/MODULE.bazel index 751d2176..8e190bc0 100644 --- a/example/use-counter-with-bvar/MODULE.bazel +++ b/example/use-counter-with-bvar/MODULE.bazel @@ -1,4 +1,4 @@ -bazel_dep(name = 'babylon', version = '1.2.2') +bazel_dep(name = 'babylon', version = '1.3.0') bazel_dep(name = 'brpc', version = '1.9.0') bazel_dep(name = 'tcmalloc', version = '0.0.0-20240411-5ed309d') single_version_override(module_name = 'protobuf', version = '3.19.6') diff --git a/example/use-with-bthread/MODULE.bazel b/example/use-with-bthread/MODULE.bazel index 92943a5e..5affac38 100644 --- a/example/use-with-bthread/MODULE.bazel +++ b/example/use-with-bthread/MODULE.bazel @@ -1,2 +1,2 @@ -bazel_dep(name = 'babylon', version = '1.2.2') +bazel_dep(name = 'babylon', version = '1.3.0') bazel_dep(name = 'brpc', version = '1.9.0') diff --git a/example/use-with-glog/.bazelrc b/example/use-with-glog/.bazelrc new file mode 100644 index 00000000..4ac1d61f --- /dev/null +++ b/example/use-with-glog/.bazelrc @@ -0,0 +1,5 @@ +common --registry=https://bcr.bazel.build +common --registry=https://baidu.github.io/babylon/registry +common --registry=https://raw.githubusercontent.com/bazelboost/registry/main + +build --cxxopt=-std=c++17 diff --git a/example/use-with-glog/.bazelversion b/example/use-with-glog/.bazelversion new file mode 100644 index 00000000..b26a34e4 --- /dev/null +++ b/example/use-with-glog/.bazelversion @@ -0,0 +1 @@ +7.2.1 diff --git a/example/use-with-glog/BUILD b/example/use-with-glog/BUILD new file mode 100644 index 00000000..e43bf697 --- /dev/null +++ b/example/use-with-glog/BUILD @@ -0,0 +1,8 @@ +cc_binary( + name = 'example', + srcs = ['example.cpp'], + deps = [ + '@babylon//:logging', + '@glog', + ], +) diff --git a/example/use-with-glog/MODULE.bazel b/example/use-with-glog/MODULE.bazel new file mode 100644 index 00000000..5dd42bdd --- /dev/null +++ b/example/use-with-glog/MODULE.bazel @@ -0,0 +1,2 @@ +bazel_dep(name = 'babylon', version = '1.3.0') +bazel_dep(name = 'glog', version = '0.7.1') diff --git a/example/use-with-glog/README.md b/example/use-with-glog/README.md new file mode 100644 index 00000000..c58063fc --- /dev/null +++ b/example/use-with-glog/README.md @@ -0,0 +1,82 @@ +# Use with glog + +## glog to babylon + +程序整体日志系统使用babylon::LoggerManager,但部分不方便修改的子模块采用glog作为日志接口,可以采用定制google::LogSink的方法将日志重定向到babylon::LoggerManager日志框架 + +```c++ +class BabylonLogSink : public ::google::LogSink { + public: + virtual void send(::google::LogSeverity glog_severity, + const char* full_filename, const char*, + int line, const ::google::LogMessageTime&, + const char* message, size_t message_len) noexcept override { + // severity mapping + static ::babylon::LogSeverity mapping[] = { + [::google::INFO] = ::babylon::LogSeverity::INFO, + [::google::WARNING] = ::babylon::LogSeverity::WARNING, + [::google::ERROR] = ::babylon::LogSeverity::FATAL, + [::google::FATAL] = ::babylon::LogSeverity::FATAL, + }; + + // root logger severity pre-check + auto severity = mapping[glog_severity]; + auto& logger = ::babylon::LoggerManager::instance().get_root_logger(); + if (logger.min_severity() > severity) { + return; + } + + // write to root logger + auto& stream = logger.stream(severity, full_filename, line); + stream.begin(); + stream.write(message, message_len); + stream.end(); + } +}; + +// glog -> babylon sink -> babylon +BabylonLogSink sink; +::google::AddLogSink(&sink); +``` + +## babylon to glog + +程序整体日志系统使用glog,可以采用定制babylon::LogStream的方法将babylon内部日志重定向到glog + +```c++ +class GLogStream : public ::babylon::LogStream { + public: + GLogStream() noexcept : LogStream(*reinterpret_cast(0)) {} + + virtual void do_begin() noexcept override { + // severity mapping + static ::google::LogSeverity mapping[] = { + [::babylon::LogSeverity::DEBUG] = ::google::INFO, + [::babylon::LogSeverity::INFO] = ::google::INFO, + [::babylon::LogSeverity::WARNING] = ::google::WARNING, + [::babylon::LogSeverity::FATAL] = ::google::FATAL, + }; + + // get underlying std::streambuf from glog. set to babylon::LogStream + auto& message = reinterpret_cast<::google::LogMessage&>(_message_storage); + new (&message) ::google::LogMessage(file().data(), line(), mapping[severity()]); + rdbuf(message.stream().rdbuf()); + } + + virtual void do_end() noexcept override { + // destruct google::LogMessage to flush + auto& message = reinterpret_cast<::google::LogMessage&>(_message_storage); + message.~LogMessage(); + } + + ::std::aligned_storage::type _message_storage; +}; + +// babylon -> logger -> glog stream -> glog +::babylon::LoggerBuilder builder; +builder.set_log_stream_creator([] { + return ::std::make_unique(); +}); +::babylon::LoggerManager::instance().set_root_builder(::std::move(builder)); +::babylon::LoggerManager::instance().apply(); +``` diff --git a/example/use-with-glog/build.sh b/example/use-with-glog/build.sh new file mode 100755 index 00000000..82f05b52 --- /dev/null +++ b/example/use-with-glog/build.sh @@ -0,0 +1,4 @@ +#!/bin/sh +set -ex + +bazel build example diff --git a/example/use-with-glog/example.cpp b/example/use-with-glog/example.cpp new file mode 100644 index 00000000..28489e22 --- /dev/null +++ b/example/use-with-glog/example.cpp @@ -0,0 +1,96 @@ +#include "babylon/logging/logger.h" +#include "gflags/gflags.h" +#include "glog/logging.h" + +class BabylonLogSink : public ::google::LogSink { + public: + virtual void send(::google::LogSeverity glog_severity, + const char* full_filename, const char*, + int line, const ::google::LogMessageTime&, + const char* message, size_t message_len) noexcept override { + // severity mapping + static ::babylon::LogSeverity mapping[] = { + [::google::INFO] = ::babylon::LogSeverity::INFO, + [::google::WARNING] = ::babylon::LogSeverity::WARNING, + [::google::ERROR] = ::babylon::LogSeverity::FATAL, + [::google::FATAL] = ::babylon::LogSeverity::FATAL, + }; + + // root logger severity pre-check + auto severity = mapping[glog_severity]; + auto& logger = ::babylon::LoggerManager::instance().get_root_logger(); + if (logger.min_severity() > severity) { + return; + } + + // write to root logger + auto& stream = logger.stream(severity, full_filename, line); + stream.begin(); + stream.write(message, message_len); + stream.end(); + } +}; + +class GLogStream : public ::babylon::LogStream { + public: + GLogStream() noexcept : LogStream(*reinterpret_cast(0)) {} + + virtual void do_begin() noexcept override { + // severity mapping + static ::google::LogSeverity mapping[] = { + [::babylon::LogSeverity::DEBUG] = ::google::INFO, + [::babylon::LogSeverity::INFO] = ::google::INFO, + [::babylon::LogSeverity::WARNING] = ::google::WARNING, + [::babylon::LogSeverity::FATAL] = ::google::FATAL, + }; + + // get underlying std::streambuf from glog. set to babylon::LogStream + auto& message = reinterpret_cast<::google::LogMessage&>(_message_storage); + new (&message) ::google::LogMessage(file().data(), line(), mapping[severity()]); + rdbuf(message.stream().rdbuf()); + } + + virtual void do_end() noexcept override { + // destruct google::LogMessage to flush + auto& message = reinterpret_cast<::google::LogMessage&>(_message_storage); + message.~LogMessage(); + } + + ::std::aligned_storage::type _message_storage; +}; + +int main(int argc, char* argv[]) { + ::gflags::ParseCommandLineFlags(&argc, &argv, true); + + ::gflags::SetCommandLineOption( + "stderrthreshold", ::std::to_string(::google::NUM_SEVERITIES).c_str()); + ::google::InitGoogleLogging(argv[0]); + + // glog -> babylon sink -> babylon + BabylonLogSink sink; + ::google::AddLogSink(&sink); + + LOG(INFO) << "1 glog to babylon"; + LOG(WARNING) << "2 glog to babylon"; + LOG(ERROR) << "3 glog to babylon"; + //LOG(FATAL) << "4 glog to babylon"; + + ::google::RemoveLogSink(&sink); + + ::gflags::SetCommandLineOption("alsologtostderr", "true"); + + // babylon -> logger -> glog stream -> glog + ::babylon::LoggerBuilder builder; + builder.set_log_stream_creator([] { + return ::std::make_unique(); + }); + ::babylon::LoggerManager::instance().set_root_builder(::std::move(builder)); + ::babylon::LoggerManager::instance().apply(); + + BABYLON_LOG(DEBUG) << "1 babylon to glog"; + BABYLON_LOG(INFO) << "2 babylon to glog"; + BABYLON_LOG(WARNING) << "3 babylon to glog"; + //BABYLON_LOG(FATAL) << "4 babylon to glog"; + + return 0; +}