11# async_logger
22
3- An industrial-grade, asynchronous C++20 logging library built on a high-performance ring buffer. Designed for easy integration via CMake’s ` find_package ` or ` FetchContent ` .
3+ ![ Build Status] ( https://img.shields.io/github/actions/workflow/status/HuRuilizhen/async_logger/cmake-multi-platform.yml?branch=release )
4+
5+ An industrial-grade, asynchronous C++20 logging library built on a high-performance ring buffer. Unit tests and sample usage provided. Designed for easy integration via CMake’s ` find_package ` or ` FetchContent ` .
46
57## Features
68
79- Five log levels: ` Debug ` , ` Info ` , ` Warn ` , ` Error ` , ` Fatal `
8- - Non-blocking, lock-free enqueue via ring buffer
9- - Background worker thread for file I/O
10- - Configurable log file, level filtering, and formatting (timestamp, level tag, message)
10+ - Non-blocking, lock-free enqueue via mpsc ring buffer
11+ - Background worker thread for file I/O
12+ - Log file rotation on date change
13+ - Configurable log file, level filtering, and formatting (level, timestamp, location, message)
1114- Zero-overhead when log level is below threshold
1215- Simple C++ interface: ` Logger::debug("…") ` , ` Logger::info("…") ` , etc.
1316
1417## Requirements
1518
1619- C++20-compatible compiler
17- - CMake ≥ 3.15
18- - Your ` ring_buffer ` library (headers & CMake config)
20+ - CMake >= 3.15
21+ - [ ` ring_buffer ` ] ( https://github.com/HuRuilizhen/ring_buffer ) library (headers & CMake config)
1922- (Optional) GoogleTest for unit tests
2023
2124## Table of Contents
2225
23- - [ Building] ( #building )
24- - [ Running Tests] ( #running-tests )
25- - [ Using the Library] ( #using-the-library )
26- - [ Using FetchContent] ( #using-fetchcontent )
27- - [ Uninstall] ( #uninstall )
28- - [ Contributing] ( #contributing )
26+ - [ async\_ logger] ( #async_logger )
27+ - [ Features] ( #features )
28+ - [ Requirements] ( #requirements )
29+ - [ Table of Contents] ( #table-of-contents )
30+ - [ Building] ( #building )
31+ - [ Configuration] ( #configuration )
32+ - [ Execution] ( #execution )
33+ - [ Running Examples] ( #running-examples )
34+ - [ Running Tests] ( #running-tests )
35+ - [ Using the Library] ( #using-the-library )
36+ - [ Including the Library] ( #including-the-library )
37+ - [ Supported APIs] ( #supported-apis )
38+ - [ Initialization \& Shutdown] ( #initialization--shutdown )
39+ - [ Logging API (static methods)] ( #logging-api-static-methods )
40+ - [ Logging via Macros] ( #logging-via-macros )
41+ - [ Quick Example] ( #quick-example )
42+ - [ Uninstall] ( #uninstall )
43+ - [ Contributing] ( #contributing )
2944
3045## Building
3146
32- Choose your generator and configure:
47+ ### Configuration
3348
34- ``` bash
35- cmake -S . -B build -G Ninja # or Xcode / "Unix Makefiles"
36- cmake --build build
37- ````
49+ | Option | Default | Description |
50+ | ------------------------------- | ------- | ----------------------------------------- |
51+ | ` ENABLE_TESTS ` | OFF | Build unit tests (requires GTest) |
52+ | ` ENABLE_EXAMPLE ` | OFF | Build examples |
53+ | ` CMAKE_EXPORT_COMPILE_COMMANDS ` | OFF | Generate ` compile_commands.json ` for IDEs |
3854
39- Enable tests (and fetch GoogleTest) in one go:
55+ ### Execution
4056
4157``` bash
42- cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DENABLE_TESTS=ON -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
58+ # Default build
59+ cmake -S . -B build
4360cmake --build build
44- sudo cmake --install build
45- ` ` `
4661
47- Build without tests for a lean installation:
48-
49- ` ` ` bash
50- cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
62+ # Build with tests + examples
63+ cmake -S . -B build -DENABLE_TESTS=ON -DENABLE_EXAMPLE=ON
5164cmake --build build
65+
66+ # Install
5267sudo cmake --install build
5368```
5469
55- # # Running Tests
56-
57- After a test-enabled build:
70+ ## Running Examples
5871
5972``` bash
60- cd build
61- ctest --output-on-failure
73+ cd ./build/bin && ./async_logger_example
6274```
6375
64- # # Using the Library
65-
66- # ## Via `find_package`
67-
68- After installing ` async_logger` , add to your project:
76+ or
6977
70- ` ` ` cmake
71- find_package(async_logger CONFIG REQUIRED)
72-
73- add_executable(my_app main.cpp)
74- target_link_libraries(my_app PRIVATE
75- async_logger::async_logger
76- )
78+ ``` bash
79+ cd ./build/bin && ./async_logger_macro_example
7780```
7881
79- In code:
80-
81- ` ` ` cpp
82- # include <async_logger/logger.h>
82+ ## Running Tests
8383
84- int main () {
85- async_logger::Logger::init(" app.log" , async_logger::Level::Debug);
86- async_logger::Logger::info(" Application started" );
87- // …
88- async_logger::Logger::shutdown ();
89- return 0;
90- }
84+ ``` bash
85+ cd ./build && ctest --output-on-failure
9186```
9287
93- # # Using FetchContent
88+ ## Using the Library
89+
90+ ### Including the Library
9491
9592Without installation, pull both ` ring_buffer ` and ` async_logger ` :
9693
9794``` cmake
9895include(FetchContent)
9996
100- # 1) ring_buffer dependency
97+ # 1) ring_buffer dependency (optional)
10198FetchContent_Declare(
10299 ring_buffer
103100 GIT_REPOSITORY https://github.com/HuRuilizhen/ring_buffer.git
104- GIT_TAG v1.0.0
101+ GIT_TAG v1.0.3
105102)
106103# 2) async_logger itself
107104FetchContent_Declare(
@@ -112,12 +109,106 @@ FetchContent_Declare(
112109
113110FetchContent_MakeAvailable(ring_buffer async_logger)
114111
112+ add_executable(my_app main.cpp)
113+ target_link_libraries(my_app PRIVATE async_logger)
114+ ```
115+
116+ or after installation:
117+
118+ ``` cmake
119+ find_package(async_logger CONFIG REQUIRED)
120+
115121add_executable(my_app main.cpp)
116122target_link_libraries(my_app PRIVATE
117123 async_logger::async_logger
118124)
119125```
120126
127+ ### Supported APIs
128+
129+ Namespace: ` AsyncLogger `
130+
131+ #### Initialization & Shutdown
132+
133+ ``` cpp
134+ // Initialize the logger (default config logs to stdout + file)
135+ static void Logger::init (const Config& config = Config());
136+
137+ // Gracefully stop background thread, flush pending logs
138+ static void Logger::shutdown();
139+ ```
140+
141+ **Config fields:**
142+
143+ ```cpp
144+ struct Config {
145+ std::string filename{}; // log file path (if out_file enabled), if empty use time-stamped filename with rotation
146+ int flag; // output flags, see OutstreamFlag
147+ Level level; // minimum log level
148+ };
149+ ```
150+
151+ ** Flags (` OutstreamFlag ` ):**
152+
153+ * ` out_stdout ` $\rightarrow$ log to stdout
154+ * ` out_stderr ` $\rightarrow$ log to stderr
155+ * ` out_file ` $\rightarrow$ log to file (` Config::filename ` )
156+ * ` out_color ` $\rightarrow$ enable colored log levels (stdout and stderr only)
157+ * ` mode_append ` $\rightarrow$ append to file instead of overwrite
158+
159+ #### Logging API (static methods)
160+
161+ ``` cpp
162+ Logger::debug (const std::string& msg,
163+ const std::source_location& loc = std::source_location::current());
164+
165+ Logger::info(const std::string& msg,
166+ const std::source_location& loc = std::source_location::current());
167+
168+ Logger::warn(const std::string& msg,
169+ const std::source_location& loc = std::source_location::current());
170+
171+ Logger::error(const std::string& msg,
172+ const std::source_location& loc = std::source_location::current());
173+
174+ Logger::fatal(const std::string& msg,
175+ const std::source_location& loc = std::source_location::current());
176+ ```
177+
178+ * All methods automatically capture file/line/function via `std::source_location`.
179+ * Log entries are enqueued into a `MPSCRingBuffer` and written asynchronously by a worker thread.
180+
181+ #### Logging via Macros
182+
183+ Convenient macros are provided for inline logging:
184+
185+ ```cpp
186+ LOG_DEBUG("message");
187+ LOG_INFO("message");
188+ LOG_WARN("message");
189+ LOG_ERROR("message");
190+ LOG_FATAL("message");
191+
192+ LOGF_INFO("formatted number: {}", 42);
193+ LOGF_ERROR("failed: {} ({})", filename, errno);
194+ ```
195+
196+ * ` LOG_* ` $\rightarrow$ plain message
197+ * ` LOGF_* ` $\rightarrow$ formatted message via ` std::format `
198+
199+ ### Quick Example
200+
201+ ``` cpp
202+ #include < async_logger/async_logger.h>
203+
204+ int main () {
205+ AsyncLogger::Logger::info ("Application started");
206+ // …
207+ AsyncLogger::Logger::shutdown();
208+ return 0;
209+ }
210+ ```
211+
121212## Uninstall
122213
123214If you installed via CMake:
@@ -128,4 +219,4 @@ sudo cmake --build build --target uninstall_async_logger
128219
129220## Contributing
130221
131- Contributions are welcome! Feel free to open issues or pull requests on GitHub.
222+ Contributions are welcome! Feel free to open issues or pull requests on GitHub.
0 commit comments