Compare commits
	
		
			1 Commits
		
	
	
		
			v0.5.1
			...
			85ae9d3deb
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 85ae9d3deb | 
							
								
								
									
										16
									
								
								.github/workflows/linux_test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								.github/workflows/linux_test.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,16 +0,0 @@
 | 
				
			|||||||
name: test on Linux
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
on:
 | 
					 | 
				
			||||||
    push:
 | 
					 | 
				
			||||||
        branches: ["main"]
 | 
					 | 
				
			||||||
    pull_request: 
 | 
					 | 
				
			||||||
        branches: ["main"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
jobs:
 | 
					 | 
				
			||||||
    test:
 | 
					 | 
				
			||||||
        runs-on: ubuntu-latest
 | 
					 | 
				
			||||||
        steps:
 | 
					 | 
				
			||||||
            - name: checkout code
 | 
					 | 
				
			||||||
              uses: actions/checkout@v4
 | 
					 | 
				
			||||||
            - name: test
 | 
					 | 
				
			||||||
              run: bash ./script/test.sh
 | 
					 | 
				
			||||||
							
								
								
									
										17
									
								
								.github/workflows/windows_test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								.github/workflows/windows_test.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,17 +0,0 @@
 | 
				
			|||||||
name: test on Windows
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
on:
 | 
					 | 
				
			||||||
    push:
 | 
					 | 
				
			||||||
        branches: ["main","dev"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pull_request: 
 | 
					 | 
				
			||||||
        branches: ["main"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
jobs:
 | 
					 | 
				
			||||||
    test:
 | 
					 | 
				
			||||||
        runs-on: windows-latest
 | 
					 | 
				
			||||||
        steps:
 | 
					 | 
				
			||||||
            - name: checkout code
 | 
					 | 
				
			||||||
              uses: actions/checkout@v4
 | 
					 | 
				
			||||||
            - name: test
 | 
					 | 
				
			||||||
              run: ./script/test_windows.ps1
 | 
					 | 
				
			||||||
@@ -1,18 +1,9 @@
 | 
				
			|||||||
cmake_minimum_required(VERSION 3.28...3.30)
 | 
					cmake_minimum_required( VERSION 3.28)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
project(logging)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(CMAKE_C_STANDARD 99)
 | 
					set(LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
 | 
				
			||||||
 | 
					set(ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
 | 
				
			||||||
if(MSVC)
 | 
					set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)
 | 
				
			||||||
    add_compile_options("/source-charset:utf-8")
 | 
					 | 
				
			||||||
    add_compile_options("/execution-charset:utf-8")
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS yes)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
option(TEST "是否启动单元测试" ON)
 | 
					 | 
				
			||||||
option(SHARED "是否编译为动态库" OFF)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
include_directories(${CMAKE_SOURCE_DIR}/include)
 | 
					include_directories(${CMAKE_SOURCE_DIR}/include)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -20,7 +11,7 @@ include_directories(${CMAKE_SOURCE_DIR}/include)
 | 
				
			|||||||
add_subdirectory(src)
 | 
					add_subdirectory(src)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#测试单元
 | 
					#测试单元
 | 
				
			||||||
if (TEST)
 | 
					if (SKIPTEST)
 | 
				
			||||||
    enable_testing()
 | 
					else()
 | 
				
			||||||
    add_subdirectory(tests)
 | 
					    add_subdirectory(tests)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										163
									
								
								README.en.md
									
									
									
									
									
								
							
							
						
						
									
										163
									
								
								README.en.md
									
									
									
									
									
								
							@@ -1,163 +0,0 @@
 | 
				
			|||||||
# C language logging library logging
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## brief
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Logging is a lightweight and easy-to-use C language log library that supports log level, log format, log output, log files, and other functions.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## function
 | 
					 | 
				
			||||||
- Support log levels: DEBUG, INFO, Warning, ERROR, FATAL
 | 
					 | 
				
			||||||
- Support log formats: timestamp, log level, log content
 | 
					 | 
				
			||||||
- Support log output: console, file
 | 
					 | 
				
			||||||
- Support log files: automatic creation, automatic scrolling, log segmentation
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## install
 | 
					 | 
				
			||||||
- Conan
 | 
					 | 
				
			||||||
```shell
 | 
					 | 
				
			||||||
conan create .
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
- cmake
 | 
					 | 
				
			||||||
```shell
 | 
					 | 
				
			||||||
git clone https://github.com/WangZhongDian/logging.git
 | 
					 | 
				
			||||||
cd logging
 | 
					 | 
				
			||||||
cmake build -B build . && cd build && cmake --build .
 | 
					 | 
				
			||||||
cmake --install .
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## usage
 | 
					 | 
				
			||||||

 | 
					 | 
				
			||||||

 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### console log 
 | 
					 | 
				
			||||||
```c
 | 
					 | 
				
			||||||
#include "logging.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main() {
 | 
					 | 
				
			||||||
    Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    log_info("This is an info message");
 | 
					 | 
				
			||||||
    log_error("This is an error message%s", "123");
 | 
					 | 
				
			||||||
    log_fatal("This is an fatal message");
 | 
					 | 
				
			||||||
    log_debug("This is a debug message");
 | 
					 | 
				
			||||||
    log_warning("This is a warning message%s", "123");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    destroyDefaultLogger();
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### file log
 | 
					 | 
				
			||||||
```c
 | 
					 | 
				
			||||||
#include "logging.h"
 | 
					 | 
				
			||||||
#include "logging/logging-handler.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main() {
 | 
					 | 
				
			||||||
    Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG);
 | 
					 | 
				
			||||||
    logger->addHandler(loggingHandlerFile("test1", 1024*1024));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    log_info("This is an info message");
 | 
					 | 
				
			||||||
    log_error("This is an error message%s", "123");
 | 
					 | 
				
			||||||
    log_fatal("This is an fatal message");
 | 
					 | 
				
			||||||
    log_debug("This is a debug message");
 | 
					 | 
				
			||||||
    log_warning("This is a warning message%s", "123");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    destroyDefaultLogger();
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Logging filter 
 | 
					 | 
				
			||||||
> Support adding custom filters, currently with built-in substring filters
 | 
					 | 
				
			||||||
> The function of an filter is to redirect filtered logs to the filter's dedicated processor
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#### example
 | 
					 | 
				
			||||||
Redirects filtered logs to a dedicated file processor
 | 
					 | 
				
			||||||
```c
 | 
					 | 
				
			||||||
#include "logging.h"
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main() {
 | 
					 | 
				
			||||||
    Logger  *logger = newDefaultLogger("testLogger", LOG_DEBUG);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    log_info("This is an info message");
 | 
					 | 
				
			||||||
    log_error("This is an error message%s", "123");
 | 
					 | 
				
			||||||
    log_fatal("This is an fatal message");
 | 
					 | 
				
			||||||
    log_debug("This is a debug message");
 | 
					 | 
				
			||||||
    log_warning("This is a warning message%s", "123");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char *test1[]         = {"123", "tt", NULL};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    log_filter *tint = loggingFilterSubStr(
 | 
					 | 
				
			||||||
        test1,
 | 
					 | 
				
			||||||
        LOG_DEBUG,
 | 
					 | 
				
			||||||
        loggingHandlerFile("test_interceptor", 1024 * 1024),
 | 
					 | 
				
			||||||
        true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    logger->addFilter(tint);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    printf("\n");
 | 
					 | 
				
			||||||
    printf("filter added\n");
 | 
					 | 
				
			||||||
    printf("\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    log_info("This is an info message");
 | 
					 | 
				
			||||||
    log_error("This is an error message%s", "123");
 | 
					 | 
				
			||||||
    log_fatal("This is an fatal message");
 | 
					 | 
				
			||||||
    log_debug("This is a debug message");
 | 
					 | 
				
			||||||
    log_warning("This is a warning message%s", "123");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    destroyDefaultLogger();
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#### Multiple substring filters
 | 
					 | 
				
			||||||
```c
 | 
					 | 
				
			||||||
#include "logging.h"
 | 
					 | 
				
			||||||
#include <stdbool.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <time.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main() {
 | 
					 | 
				
			||||||
    Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    log_info("This is an info message");
 | 
					 | 
				
			||||||
    log_error("This is an error message%s", "123");
 | 
					 | 
				
			||||||
    log_fatal("This is an fatal message");
 | 
					 | 
				
			||||||
    log_debug("This is a debug message");
 | 
					 | 
				
			||||||
    log_warning("This is a warning message%s", "123");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char *test1[]         = {"This",NULL};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    log_filter *tint = loggingFilterSubStr(
 | 
					 | 
				
			||||||
        test1,
 | 
					 | 
				
			||||||
        LOG_DEBUG,
 | 
					 | 
				
			||||||
        loggingHandlerFile("test_interceptor", 1024 * 1024),
 | 
					 | 
				
			||||||
        false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    logger->addFilter(tint);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char *test2[]         = {"123",NULL};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    log_filter *tint1 = loggingFilterSubStr(
 | 
					 | 
				
			||||||
        test2,
 | 
					 | 
				
			||||||
        LOG_DEBUG,
 | 
					 | 
				
			||||||
        loggingHandlerFile("test_interceptor1", 1024 * 1024),
 | 
					 | 
				
			||||||
        true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    logger->addFilter(tint1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    printf("\n");
 | 
					 | 
				
			||||||
    printf("filter added\n");
 | 
					 | 
				
			||||||
    printf("\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    log_info("This is an info message");
 | 
					 | 
				
			||||||
    log_error("This is an error message%s", "123");
 | 
					 | 
				
			||||||
    log_fatal("This is an fatal message");
 | 
					 | 
				
			||||||
    log_debug("This is a debug message");
 | 
					 | 
				
			||||||
    log_warning("This is a warning message%s", "123");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    destroyDefaultLogger();
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										169
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										169
									
								
								README.md
									
									
									
									
									
								
							@@ -1,7 +1,5 @@
 | 
				
			|||||||
# C语言日志库logging
 | 
					# C语言日志库logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[English](README.en.md)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 简介
 | 
					## 简介
 | 
				
			||||||
 | 
					
 | 
				
			||||||
logging是一个轻量级的简单易用C语言日志库,支持日志级别、日志格式、日志输出、日志文件等功能。
 | 
					logging是一个轻量级的简单易用C语言日志库,支持日志级别、日志格式、日志输出、日志文件等功能。
 | 
				
			||||||
@@ -11,51 +9,25 @@ logging是一个轻量级的简单易用C语言日志库,支持日志级别、
 | 
				
			|||||||
- 支持日志级别:DEBUG、INFO、WARN、ERROR、FATAL
 | 
					- 支持日志级别:DEBUG、INFO、WARN、ERROR、FATAL
 | 
				
			||||||
- 支持日志格式:时间戳、日志级别、日志内容
 | 
					- 支持日志格式:时间戳、日志级别、日志内容
 | 
				
			||||||
- 支持日志输出:控制台、文件
 | 
					- 支持日志输出:控制台、文件
 | 
				
			||||||
- 支持日志文件:自动创建、自动滚动、日志分割
 | 
					- 支持日志文件:自动创建、自动滚动、自动删除(未完成)
 | 
				
			||||||
 | 
					 | 
				
			||||||
## 安装
 | 
					 | 
				
			||||||
### conan安装使用
 | 
					 | 
				
			||||||
```shell
 | 
					 | 
				
			||||||
git clone https://github.com/WangZhongDian/logging.git
 | 
					 | 
				
			||||||
cd logging
 | 
					 | 
				
			||||||
conan create . 
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
在你的项目的conanfile.txt中添加
 | 
					 | 
				
			||||||
```txt
 | 
					 | 
				
			||||||
[requires]
 | 
					 | 
				
			||||||
logging/0.5.0
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```shell
 | 
					 | 
				
			||||||
conan install . --build=missing
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### cmake安装使用
 | 
					 | 
				
			||||||
```shell
 | 
					 | 
				
			||||||
git clone https://github.com/WangZhongDian/logging.git
 | 
					 | 
				
			||||||
cd logging
 | 
					 | 
				
			||||||
cmake build -B build . && cd build && cmake --build .
 | 
					 | 
				
			||||||
cmake --install .
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 使用方法
 | 
					## 使用方法
 | 
				
			||||||

 | 
					 | 
				
			||||||

 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
### 控制台日志
 | 
					### 控制台日志
 | 
				
			||||||
```c
 | 
					```c
 | 
				
			||||||
#include "logging.h"
 | 
					#include "logging.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main() {
 | 
					int main() {
 | 
				
			||||||
    Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG);
 | 
					    Logging *log    = newLogging();
 | 
				
			||||||
 | 
					    Logger  *logger = log->getLogger("testLogger", LOG_DEBUG);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Log_info("This is an info message");
 | 
					    logger->info("This is an info message");
 | 
				
			||||||
    Log_error("This is an error message%s", "123");
 | 
					    logger->error("你好,这是一个错误消息%s", "123");
 | 
				
			||||||
    Log_fatal("This is an fatal message");
 | 
					    logger->fatal("This is an fatal message");
 | 
				
			||||||
    Log_debug("This is a debug message");
 | 
					    logger->debug("This is a debug message");
 | 
				
			||||||
    Log_warning("This is a warning message%s", "123");
 | 
					    logger->warning("This is a warning message%s", "123");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    destroyDefaultLogger();
 | 
					    log->destroyLogging(log);
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
@@ -63,117 +35,72 @@ int main() {
 | 
				
			|||||||
### 文件日志
 | 
					### 文件日志
 | 
				
			||||||
```c
 | 
					```c
 | 
				
			||||||
#include "logging.h"
 | 
					#include "logging.h"
 | 
				
			||||||
#include "logging/logging-handler.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main() {
 | 
					int main() {
 | 
				
			||||||
    Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG);
 | 
					    Logging *log = newLogging();
 | 
				
			||||||
    logger->addHandler(loggingHandlerFile("test1", 1024*1024));
 | 
					    Logger *logger = log->getLogger("testLogger",LOG_DEBUG);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    Log_info("This is an info message");
 | 
					    logger->addHandler(loggingFileHandler("test"));   //为日志对象添加文件处理器
 | 
				
			||||||
    Log_error("This is an error message%s", "123");
 | 
					 | 
				
			||||||
    Log_fatal("This is an fatal message");
 | 
					 | 
				
			||||||
    Log_debug("This is a debug message");
 | 
					 | 
				
			||||||
    Log_warning("This is a warning message%s", "123");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    destroyDefaultLogger();
 | 
					    logger->info("This is an info message");
 | 
				
			||||||
 | 
					    logger->error("你好,这是一个错误消息%s", "123");
 | 
				
			||||||
 | 
					    logger->fatal("This is an fatal message");
 | 
				
			||||||
 | 
					    logger->debug("This is a debug message");
 | 
				
			||||||
 | 
					    logger->warning("This is a warning message%s", "123");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    log->destroyLogging(log);
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### 日志过滤器
 | 
					### 日志拦截器
 | 
				
			||||||
> 支持添加自定义的过滤器, 目前内置了子串过滤器
 | 
					> 支持添加自定义的拦截器, 目前内置了子串拦截器
 | 
				
			||||||
 | 
					
 | 
				
			||||||
> 过滤器的作用:可以将过滤到的日志重定向到过滤器的专属处理器中
 | 
					> 拦截器的作用:可以将拦截到的日志重定向到拦截器的专属处理器中
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#### 单个子串过滤器
 | 
					#### 例子
 | 
				
			||||||
将过滤到的日志重定向到专属处理器中
 | 
					将拦截到的日志重定向到专属文件处理器中
 | 
				
			||||||
```c
 | 
					```c
 | 
				
			||||||
#include "logging.h"
 | 
					#include "logging.h"
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main() {
 | 
					int main() {
 | 
				
			||||||
    Logger  *logger = newDefaultLogger("testLogger", LOG_DEBUG);
 | 
					    Logging *log    = newLogging();
 | 
				
			||||||
 | 
					    Logger  *logger = log->getLogger("testLogger", LOG_DEBUG);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Log_info("This is an info message");
 | 
					    logger->info("This is an info message");
 | 
				
			||||||
    Log_error("This is an error message%s", "123");
 | 
					    logger->error("你好,这是一个错误消息%s", "123");
 | 
				
			||||||
    Log_fatal("This is an fatal message");
 | 
					    logger->fatal("This is an fatal message");
 | 
				
			||||||
    Log_debug("This is a debug message");
 | 
					    logger->debug("This is a debug message");
 | 
				
			||||||
    Log_warning("This is a warning message%s", "123");
 | 
					    logger->warning("This is a warning message%s", "123");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    char *test1[]         = {"123", "tt", NULL};
 | 
					    char *test1[] = {"123", "你好"}; // 要拦截的字符串
 | 
				
			||||||
 | 
					    // 添加拦截器,将拦截到的日志重定向到拦截器的专属处理器中
 | 
				
			||||||
 | 
					    log_Interceptor *tint =
 | 
				
			||||||
 | 
					        loggingSubStringInterceptor(test1, 2, LOG_DEBUG, loggingFileHandler("被拦截"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    log_filter *tint = loggingFilterSubStr(
 | 
					    logger->addInterceptor(tint);
 | 
				
			||||||
        test1,
 | 
					 | 
				
			||||||
        LOG_DEBUG,
 | 
					 | 
				
			||||||
        loggingHandlerFile("test_interceptor", 1024 * 1024),
 | 
					 | 
				
			||||||
        true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    logger->addFilter(tint);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    printf("\n");
 | 
					    printf("\n");
 | 
				
			||||||
    printf("filter added\n");
 | 
					    printf("Interceptor added\n");
 | 
				
			||||||
    printf("\n");
 | 
					    printf("\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Log_info("This is an info message");
 | 
					    logger->info("This is an info message");
 | 
				
			||||||
    Log_error("This is an error message%s", "123");
 | 
					    logger->error("你好,这是一个错误消息%s", "123");
 | 
				
			||||||
    Log_fatal("This is an fatal message");
 | 
					    logger->fatal("This is an fatal message");
 | 
				
			||||||
    Log_debug("This is a debug message");
 | 
					    logger->debug("This is a debug message");
 | 
				
			||||||
    Log_warning("This is a warning message%s", "123");
 | 
					    logger->warning("This is a warning message%s", "123");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    destroyDefaultLogger();
 | 
					    log->destroyLogging(log);
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#### 多个子串过滤器
 | 
					 | 
				
			||||||
```c
 | 
					 | 
				
			||||||
#include "logging.h"
 | 
					 | 
				
			||||||
#include <stdbool.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <time.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main() {
 | 
					# build
 | 
				
			||||||
    Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG);
 | 
					```shell
 | 
				
			||||||
 | 
					conan create . --build=missing
 | 
				
			||||||
    Log_info("This is an info message");
 | 
					 | 
				
			||||||
    Log_error("This is an error message%s", "123");
 | 
					 | 
				
			||||||
    Log_fatal("This is an fatal message");
 | 
					 | 
				
			||||||
    Log_debug("This is a debug message");
 | 
					 | 
				
			||||||
    Log_warning("This is a warning message%s", "123");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char *test1[]         = {"This",NULL};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    log_filter *tint = loggingFilterSubStr(
 | 
					 | 
				
			||||||
        test1,
 | 
					 | 
				
			||||||
        LOG_DEBUG,
 | 
					 | 
				
			||||||
        loggingHandlerFile("test_interceptor", 1024 * 1024),
 | 
					 | 
				
			||||||
        false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    logger->addFilter(tint);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char *test2[]         = {"123",NULL};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    log_filter *tint1 = loggingFilterSubStr(
 | 
					 | 
				
			||||||
        test2,
 | 
					 | 
				
			||||||
        LOG_DEBUG,
 | 
					 | 
				
			||||||
        loggingHandlerFile("test_interceptor1", 1024 * 1024),
 | 
					 | 
				
			||||||
        true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    logger->addFilter(tint1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    printf("\n");
 | 
					 | 
				
			||||||
    printf("filter added\n");
 | 
					 | 
				
			||||||
    printf("\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Log_info("This is an info message");
 | 
					 | 
				
			||||||
    Log_error("This is an error message%s", "123");
 | 
					 | 
				
			||||||
    Log_fatal("This is an fatal message");
 | 
					 | 
				
			||||||
    Log_debug("This is a debug message");
 | 
					 | 
				
			||||||
    Log_warning("This is a warning message%s", "123");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    destroyDefaultLogger();
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										29
									
								
								conanfile.py
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								conanfile.py
									
									
									
									
									
								
							@@ -1,11 +1,14 @@
 | 
				
			|||||||
from conan import ConanFile
 | 
					from conan import ConanFile
 | 
				
			||||||
from conan.tools.cmake import CMake, CMakeToolchain, CMakeDeps, cmake_layout
 | 
					from conan.tools.cmake import CMake, CMakeToolchain, CMakeDeps, cmake_layout
 | 
				
			||||||
from conan.tools.files import copy
 | 
					from conan.tools.files import copy, get
 | 
				
			||||||
 | 
					from conan.tools.build import check_min_cppstd
 | 
				
			||||||
 | 
					from conan import tools
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class loggingRecipe(ConanFile):
 | 
					class loggingRecipe(ConanFile):
 | 
				
			||||||
    name = "logging"
 | 
					    name = "logging"
 | 
				
			||||||
    version = "0.5.1"
 | 
					    version = "0.2.2"
 | 
				
			||||||
    license = "MIT"
 | 
					    license = "MIT"
 | 
				
			||||||
    author = "321640253@qq.com"
 | 
					    author = "321640253@qq.com"
 | 
				
			||||||
    url = "https://github.com/WangZhongDian/logging.git"
 | 
					    url = "https://github.com/WangZhongDian/logging.git"
 | 
				
			||||||
@@ -13,11 +16,11 @@ class loggingRecipe(ConanFile):
 | 
				
			|||||||
    topics = ("logging", "C", "simple", "easy-to-use", "log","Logging")
 | 
					    topics = ("logging", "C", "simple", "easy-to-use", "log","Logging")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    settings = "os", "compiler", "build_type", "arch"
 | 
					    settings = "os", "compiler", "build_type", "arch"
 | 
				
			||||||
    options = {"shared": [True, False], "fPIC": [True, False],"test":[True,False]}
 | 
					    options = {"shared": [True, False], "fPIC": [True, False]}
 | 
				
			||||||
    default_options = {"shared": False, "fPIC": True,"test":True}
 | 
					    default_options = {"shared": False, "fPIC": True}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    exports_sources = "include/*", "CMakeLists.txt", "src/*", "tests/*"
 | 
					    exports_sources = "include/*", "CMakeLists.txt", "src/*"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def config_options(self):
 | 
					    def config_options(self):
 | 
				
			||||||
        if self.settings.os == "Windows":
 | 
					        if self.settings.os == "Windows":
 | 
				
			||||||
@@ -27,6 +30,8 @@ class loggingRecipe(ConanFile):
 | 
				
			|||||||
        if self.options.shared:
 | 
					        if self.options.shared:
 | 
				
			||||||
            self.options.rm_safe("fPIC")
 | 
					            self.options.rm_safe("fPIC")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    def layout(self):
 | 
					    def layout(self):
 | 
				
			||||||
        cmake_layout(self)
 | 
					        cmake_layout(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -34,16 +39,18 @@ class loggingRecipe(ConanFile):
 | 
				
			|||||||
        deps = CMakeDeps(self)
 | 
					        deps = CMakeDeps(self)
 | 
				
			||||||
        deps.generate()
 | 
					        deps.generate()
 | 
				
			||||||
        tc = CMakeToolchain(self)
 | 
					        tc = CMakeToolchain(self)
 | 
				
			||||||
        tc.variables["TEST"] = True if self.options.test else False
 | 
					        tc.variables["SKIPTEST"]=True
 | 
				
			||||||
        tc.variables["SHARED"] = True if self.options.shared else False
 | 
					        if self.options.shared:
 | 
				
			||||||
 | 
					            tc.variables["SHARED"] = True
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            tc.variables["SHARED"] = False
 | 
				
			||||||
        tc.generate()
 | 
					        tc.generate()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def build(self):
 | 
					    def build(self):
 | 
				
			||||||
        cmake = CMake(self)
 | 
					        cmake = CMake(self)
 | 
				
			||||||
        cmake.configure()
 | 
					        cmake.configure()
 | 
				
			||||||
        cmake.build()
 | 
					        cmake.build(target="Logging")
 | 
				
			||||||
        if self.options.test:
 | 
					
 | 
				
			||||||
            cmake.test()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def package(self):
 | 
					    def package(self):
 | 
				
			||||||
        copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"))
 | 
					        copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"))
 | 
				
			||||||
@@ -55,4 +62,4 @@ class loggingRecipe(ConanFile):
 | 
				
			|||||||
        copy(self, pattern="*.dylib", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False)
 | 
					        copy(self, pattern="*.dylib", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def package_info(self):
 | 
					    def package_info(self):
 | 
				
			||||||
        self.cpp_info.libs = ["logging"]
 | 
					        self.cpp_info.libs = ["Logging"]
 | 
				
			||||||
@@ -5,61 +5,33 @@
 | 
				
			|||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "logging/logging-core.h"
 | 
					#include "logging/logging-core.h"
 | 
				
			||||||
#include "logging/logging-filter.h"
 | 
					 | 
				
			||||||
#include "logging/logging-handler.h"
 | 
					#include "logging/logging-handler.h"
 | 
				
			||||||
 | 
					#include "logging/logging-interceptor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					// 日志操作器
 | 
				
			||||||
extern "C" {
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define Log_fatal(format, ...)                                                 \
 | 
					 | 
				
			||||||
    log_fatal(__FILE__, __LINE__, format, ##__VA_ARGS__)
 | 
					 | 
				
			||||||
#define Log_error(format, ...)                                                 \
 | 
					 | 
				
			||||||
    log_error(__FILE__, __LINE__, format, ##__VA_ARGS__)
 | 
					 | 
				
			||||||
#define Log_warning(format, ...)                                               \
 | 
					 | 
				
			||||||
    log_warning(__FILE__, __LINE__, format, ##__VA_ARGS__)
 | 
					 | 
				
			||||||
#define Log_info(format, ...)                                                  \
 | 
					 | 
				
			||||||
    log_info(__FILE__, __LINE__, format, ##__VA_ARGS__)
 | 
					 | 
				
			||||||
#define Log_debug(format, ...)                                                 \
 | 
					 | 
				
			||||||
    log_debug(__FILE__, __LINE__, format, ##__VA_ARGS__)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct Logger {
 | 
					typedef struct Logger {
 | 
				
			||||||
    log_level        level;
 | 
					    log_level        level;
 | 
				
			||||||
    log_Handler     *handler;
 | 
					    log_Handler     *handler;
 | 
				
			||||||
    log_filter  *filter;
 | 
					    log_Interceptor *interceptor;
 | 
				
			||||||
    const char      *name;
 | 
					    const char      *name;
 | 
				
			||||||
    bool (*addHandler)(log_Handler *handler);
 | 
					    void (*fatal)(const char *format, ...);
 | 
				
			||||||
    bool (*addFilter)(log_filter *filter);
 | 
					    void (*error)(const char *format, ...);
 | 
				
			||||||
 | 
					    void (*warning)(const char *format, ...);
 | 
				
			||||||
 | 
					    void (*info)(const char *format, ...);
 | 
				
			||||||
 | 
					    void (*debug)(const char *format, ...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void (*addHandler)(log_Handler *handler);
 | 
				
			||||||
 | 
					    void (*addInterceptor)(log_Interceptor *Interceptor);
 | 
				
			||||||
} Logger;
 | 
					} Logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void log_fatal(const char *file, int line, const char *format, ...);
 | 
					// 日志类对象
 | 
				
			||||||
void log_error(const char *file, int line, const char *format, ...);
 | 
					typedef struct Logging {
 | 
				
			||||||
void log_warning(const char *file, int line, const char *format, ...);
 | 
					    Logger *(*getLogger)(const char *name, log_level level);
 | 
				
			||||||
void log_info(const char *file, int line, const char *format, ...);
 | 
					    log_status (*setLevel)(Logger *logger, log_level level);
 | 
				
			||||||
void log_debug(const char *file, int line, const char *format, ...);
 | 
					    Logger *(*getCurrentLogger)(void);
 | 
				
			||||||
 | 
					    log_status (*destroyLogging)(struct Logging *logging);
 | 
				
			||||||
 | 
					} Logging;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					Logging *newLogging(); // 创建日志类对象
 | 
				
			||||||
* @brief
 | 
					 | 
				
			||||||
创建默认日志对象,日志对象为单例模式,后续可通过getDefaultLogger方法获取,
 | 
					 | 
				
			||||||
        重复调用该方法不会创建新的日志对象,只会返回默认日志对象,并且会修改默认日志对象的名称和等级
 | 
					 | 
				
			||||||
* @param name 日志名称
 | 
					 | 
				
			||||||
* @param level 日志等级
 | 
					 | 
				
			||||||
* @return Logger* 日志对象指针
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
Logger *newDefaultLogger(const char *name, log_level level);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @brief 获取默认日志对象
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
Logger *getDefaultLogger(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @brief 销毁日志对象,该方法会销毁默认日志对象
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
log_status destroyDefaultLogger(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __cplusplus
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // __LOGGING_H__
 | 
					#endif // __LOGGING_H__
 | 
				
			||||||
@@ -1,12 +1,8 @@
 | 
				
			|||||||
#ifndef __LOGGING_CORE_H__
 | 
					#ifndef __LOGGING_CORE_H__
 | 
				
			||||||
#define __LOGGING_CORE_H__
 | 
					#define __LOGGING_CORE_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					 | 
				
			||||||
extern "C" {
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef enum {
 | 
					typedef enum {
 | 
				
			||||||
    LOG_FATAL = 0,
 | 
					    LOG_FATAL,
 | 
				
			||||||
    LOG_ERROR,
 | 
					    LOG_ERROR,
 | 
				
			||||||
    LOG_WARNING,
 | 
					    LOG_WARNING,
 | 
				
			||||||
    LOG_INFO,
 | 
					    LOG_INFO,
 | 
				
			||||||
@@ -18,8 +14,5 @@ typedef enum {
 | 
				
			|||||||
    L_OK,
 | 
					    L_OK,
 | 
				
			||||||
} log_status;
 | 
					} log_status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // __LOGGING_CORE_H__
 | 
					#endif // __LOGGING_CORE_H__
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,41 +0,0 @@
 | 
				
			|||||||
#ifndef __LOGGING_INTERCEPTOR_H__
 | 
					 | 
				
			||||||
#define __LOGGING_INTERCEPTOR_H__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "logging-core.h"
 | 
					 | 
				
			||||||
#include "logging-handler.h"
 | 
					 | 
				
			||||||
#include <stdbool.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __cplusplus
 | 
					 | 
				
			||||||
extern "C" {
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct log_filter {
 | 
					 | 
				
			||||||
    log_level    level;
 | 
					 | 
				
			||||||
    log_Handler *handler;
 | 
					 | 
				
			||||||
    bool         jump_out;
 | 
					 | 
				
			||||||
    bool (*_dispose)(struct log_filter *filter,
 | 
					 | 
				
			||||||
                     log_level          level,
 | 
					 | 
				
			||||||
                     const char        *message,
 | 
					 | 
				
			||||||
                     ...);
 | 
					 | 
				
			||||||
    void (*_free)(struct log_filter *filter);
 | 
					 | 
				
			||||||
    struct log_filter *next;
 | 
					 | 
				
			||||||
} log_filter;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @brief  子字符串过滤器
 | 
					 | 
				
			||||||
 * @param keywords: 关键字数组
 | 
					 | 
				
			||||||
 * @param count: 关键字数组长度
 | 
					 | 
				
			||||||
 * @param level: 过滤截日志等级
 | 
					 | 
				
			||||||
 * @param handler: 日志处理器,用于处理过滤下来的日志
 | 
					 | 
				
			||||||
 * @return log_filter *
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
log_filter *loggingFilterSubStr(char        *keywords[],
 | 
					 | 
				
			||||||
                                log_level    level,
 | 
					 | 
				
			||||||
                                log_Handler *handler,
 | 
					 | 
				
			||||||
                                bool         jump_out);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __cplusplus
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif // __LOGGING_INTERCEPTOR_H__
 | 
					 | 
				
			||||||
@@ -3,34 +3,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					 | 
				
			||||||
extern "C" {
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct log_Handler {
 | 
					typedef struct log_Handler {
 | 
				
			||||||
    void* stream;
 | 
					    void* stream;
 | 
				
			||||||
    bool apply_color;
 | 
					    bool apply_color;
 | 
				
			||||||
    void (*_free)(struct log_Handler *handler);
 | 
					    void (*_free)(struct log_Handler* handler);//释放资源
 | 
				
			||||||
    void (*output)(struct log_Handler* handler,const char* message);
 | 
					    void (*output)(struct log_Handler* handler,const char* message);
 | 
				
			||||||
} log_Handler;
 | 
					} log_Handler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @brief 文件处理器
 | 
					 | 
				
			||||||
 * @param name 文件名
 | 
					 | 
				
			||||||
 * @param max_size 文件最大大小
 | 
					 | 
				
			||||||
 * @return
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
log_Handler *loggingHandlerFile(const char *name, unsigned int max_size);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					log_Handler* loggingFileHandler(const char* name);     
 | 
				
			||||||
 * @brief 控制台处理器
 | 
					log_Handler* loggingConsoleHandler();
 | 
				
			||||||
 * @param
 | 
					 | 
				
			||||||
 * @return
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
log_Handler *loggingHandlerConsole();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __cplusplus
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif  //__LOGGING_HANDLER_H__
 | 
					#endif  //__LOGGING_HANDLER_H__
 | 
				
			||||||
							
								
								
									
										20
									
								
								include/logging/logging-interceptor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								include/logging/logging-interceptor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					#ifndef __LOGGING_INTERCEPTOR_H__
 | 
				
			||||||
 | 
					#define __LOGGING_INTERCEPTOR_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "logging-core.h"
 | 
				
			||||||
 | 
					#include "logging-handler.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct log_Interceptor {
 | 
				
			||||||
 | 
					    log_level    level;   // 拦截级别
 | 
				
			||||||
 | 
					    log_Handler *handler; // 拦截目标处理器
 | 
				
			||||||
 | 
					    bool (*_dispose)(char *level, const char *message, ...); // 拦截触发器
 | 
				
			||||||
 | 
					    void (*_free)(struct log_Interceptor *Interceptor);      // 释放资源
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} log_Interceptor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					log_Interceptor *loggingSubStringInterceptor(char        *keywords[],
 | 
				
			||||||
 | 
					                                             int          count,
 | 
				
			||||||
 | 
					                                             log_level    level,
 | 
				
			||||||
 | 
					                                             log_Handler *handler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // __LOGGING_INTERCEPTOR_H__
 | 
				
			||||||
@@ -1,3 +0,0 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					 | 
				
			||||||
# Run clang-format on all C/C++ files in this directory and below.
 | 
					 | 
				
			||||||
find . -name "*.c" -o -name "*.h" -exec clang-format -style=file -i {} +
 | 
					 | 
				
			||||||
@@ -1,2 +0,0 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					 | 
				
			||||||
cmake build -B build . && cd build && cmake --build . && ctest
 | 
					 | 
				
			||||||
@@ -1,5 +0,0 @@
 | 
				
			|||||||
cmake build -B build . 
 | 
					 | 
				
			||||||
Set-Location -Path "./build"
 | 
					 | 
				
			||||||
cmake --build .
 | 
					 | 
				
			||||||
ctest
 | 
					 | 
				
			||||||
Set-Location -Path ".."
 | 
					 | 
				
			||||||
@@ -1,9 +1,8 @@
 | 
				
			|||||||
project(logging)
 | 
					project(Logging)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRC)
 | 
					aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRC)
 | 
				
			||||||
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/handler SRC)
 | 
					aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/handler SRC)
 | 
				
			||||||
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/filter SRC)
 | 
					aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/interceptor SRC)
 | 
				
			||||||
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/utils SRC)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (SHARED)
 | 
					if (SHARED)
 | 
				
			||||||
    add_library(${PROJECT_NAME} SHARED ${SRC})
 | 
					    add_library(${PROJECT_NAME} SHARED ${SRC})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,133 +0,0 @@
 | 
				
			|||||||
#include "logging/logging-filter.h"
 | 
					 | 
				
			||||||
#include <stdbool.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
#include <time.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct keywords_s {
 | 
					 | 
				
			||||||
    char              *key;
 | 
					 | 
				
			||||||
    struct keywords_s *next;
 | 
					 | 
				
			||||||
} keywords_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void get_next(char *str, int *next) {
 | 
					 | 
				
			||||||
    next[1] = 0;
 | 
					 | 
				
			||||||
    int i   = 1;
 | 
					 | 
				
			||||||
    int j   = 0;
 | 
					 | 
				
			||||||
    while (i < strlen(str)) {
 | 
					 | 
				
			||||||
        if (j == 0 || str[i] == str[j]) {
 | 
					 | 
				
			||||||
            next[++i] = ++j;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            j = next[j];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool kmp_search(char *substr, char *master) {
 | 
					 | 
				
			||||||
    if (substr == NULL)
 | 
					 | 
				
			||||||
        return true; // 空串全匹配
 | 
					 | 
				
			||||||
    if (master == NULL)
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    int  i         = 0;
 | 
					 | 
				
			||||||
    int  j         = 0;
 | 
					 | 
				
			||||||
    int  substrlen = strlen(substr);
 | 
					 | 
				
			||||||
    int  masterlen = strlen(master);
 | 
					 | 
				
			||||||
    int *next      = (int *)malloc(sizeof(int) * (substrlen + 1));
 | 
					 | 
				
			||||||
    get_next(substr, next);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    while (i < masterlen && j < substrlen) {
 | 
					 | 
				
			||||||
        if (master[i] == substr[j]) {
 | 
					 | 
				
			||||||
            i++;
 | 
					 | 
				
			||||||
            j++;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            if (j == 0) {
 | 
					 | 
				
			||||||
                i++;
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                j = next[j];
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    free(next);
 | 
					 | 
				
			||||||
    if (j == substrlen)
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool _disposeSubstring(log_filter *filter,
 | 
					 | 
				
			||||||
                              log_level   level,
 | 
					 | 
				
			||||||
                              const char *message,
 | 
					 | 
				
			||||||
                              ...) {
 | 
					 | 
				
			||||||
    int         count   = 0;
 | 
					 | 
				
			||||||
    keywords_t *keyword = (keywords_t *)(filter + 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (keyword->key == NULL && keyword->next == NULL) {
 | 
					 | 
				
			||||||
        if (level <= filter->level)
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    while (keyword != NULL && level <= filter->level) {
 | 
					 | 
				
			||||||
        if (kmp_search(keyword->key, (char *)message))
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        keyword = keyword->next;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void _freeFilter(log_filter *filter) {
 | 
					 | 
				
			||||||
    keywords_t *it_keyword =
 | 
					 | 
				
			||||||
        (keywords_t *)(filter + 1); // it_keyword 不是起始地址,请勿free
 | 
					 | 
				
			||||||
    keywords_t *keyword = it_keyword->next;
 | 
					 | 
				
			||||||
    keywords_t *next    = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    while (keyword != NULL) {
 | 
					 | 
				
			||||||
        next = keyword->next;
 | 
					 | 
				
			||||||
        free(keyword->key);
 | 
					 | 
				
			||||||
        free(keyword);
 | 
					 | 
				
			||||||
        keyword = next;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (filter->handler != NULL) {
 | 
					 | 
				
			||||||
        filter->handler->_free(filter->handler);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (it_keyword->key != NULL)
 | 
					 | 
				
			||||||
        free(it_keyword->key);
 | 
					 | 
				
			||||||
    free(filter);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
log_filter *loggingFilterSubStr(char        *keywords[],
 | 
					 | 
				
			||||||
                                log_level    level,
 | 
					 | 
				
			||||||
                                log_Handler *handler,
 | 
					 | 
				
			||||||
                                bool         jump_out) {
 | 
					 | 
				
			||||||
    // 分配log_filter和keywords_t的连续内存
 | 
					 | 
				
			||||||
    log_filter *filter =
 | 
					 | 
				
			||||||
        (log_filter *)malloc(sizeof(log_filter) + sizeof(keywords_t));
 | 
					 | 
				
			||||||
    filter->_dispose    = _disposeSubstring;
 | 
					 | 
				
			||||||
    filter->handler     = handler;
 | 
					 | 
				
			||||||
    filter->level       = level;
 | 
					 | 
				
			||||||
    filter->jump_out    = jump_out;
 | 
					 | 
				
			||||||
    filter->_free       = _freeFilter;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    keywords_t *keyword = (keywords_t *)(filter + 1);
 | 
					 | 
				
			||||||
    keyword->key        = NULL;
 | 
					 | 
				
			||||||
    int count           = 0;
 | 
					 | 
				
			||||||
    if (keywords[count] != NULL) {
 | 
					 | 
				
			||||||
        keyword->key = strdup(keywords[count]);
 | 
					 | 
				
			||||||
        count++;
 | 
					 | 
				
			||||||
        keyword->next = NULL;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    while (keywords[count] != NULL) {
 | 
					 | 
				
			||||||
        keyword->next = (keywords_t *)malloc(sizeof(keywords_t));
 | 
					 | 
				
			||||||
        keyword       = keyword->next;
 | 
					 | 
				
			||||||
        keyword->key  = strdup(keywords[count]);
 | 
					 | 
				
			||||||
        count++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    keyword->next = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return filter;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,20 +1,36 @@
 | 
				
			|||||||
 | 
					/********************************************
 | 
				
			||||||
 | 
					 * @Date: 2024 09 18
 | 
				
			||||||
 | 
					 * @Description: 控制台日志处理器
 | 
				
			||||||
 | 
					 ********************************************/
 | 
				
			||||||
#include "logging/logging-handler.h"
 | 
					#include "logging/logging-handler.h"
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void __freeHandlerConsole(log_Handler *handler) { free(handler); }
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief 释放组件
 | 
				
			||||||
 | 
					 * @param handler 处理器
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void __freeConsoleHandler(log_Handler *handler) { free(handler); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void __outputHandlerConsole(log_Handler *handler, const char *message) {
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief 输出组件
 | 
				
			||||||
 | 
					 * @param handler 处理器
 | 
				
			||||||
 | 
					 * @param message 消息
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void outputConsoleHandler(log_Handler *handler, const char *message) {
 | 
				
			||||||
    fputs(message, handler->stream);
 | 
					    fputs(message, handler->stream);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
log_Handler *loggingHandlerConsole() {
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief :控制台日志处理器
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					log_Handler *loggingConsoleHandler() {
 | 
				
			||||||
    log_Handler *handler = (log_Handler *)malloc(sizeof(log_Handler));
 | 
					    log_Handler *handler = (log_Handler *)malloc(sizeof(log_Handler));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    handler->stream      = stdout;
 | 
					    handler->stream      = stdout;
 | 
				
			||||||
    handler->apply_color = true;
 | 
					    handler->apply_color = true;
 | 
				
			||||||
    handler->_free       = __freeHandlerConsole;
 | 
					    handler->_free       = __freeConsoleHandler;
 | 
				
			||||||
    handler->output      = __outputHandlerConsole;
 | 
					    handler->output      = outputConsoleHandler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return handler;
 | 
					    return handler;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,98 +1,45 @@
 | 
				
			|||||||
 | 
					/********************************************
 | 
				
			||||||
 | 
					 * @Date: 2024 09 18
 | 
				
			||||||
 | 
					 * @Description: 文件日志处理器
 | 
				
			||||||
 | 
					 ********************************************/
 | 
				
			||||||
#include "logging/logging-handler.h"
 | 
					#include "logging/logging-handler.h"
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 根据log_Handler结构体指针起始获取log_Handler_file_ex_t结构体指针
 | 
					 | 
				
			||||||
// log_Handler_file_ex_t与log_Handler处于连续内存中
 | 
					 | 
				
			||||||
// 使用char*指针进行偏移,达到以偏移1个字节为单位的偏移
 | 
					 | 
				
			||||||
#define Handler_file_EX_PRT(handler)                                           \
 | 
					 | 
				
			||||||
    ((log_Handler_file_ex_t *)((char *)handler + sizeof(log_Handler)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define FILE_NAME_MAX_SIZE 50
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 文件日志处理器的扩展
 | 
					 | 
				
			||||||
typedef struct log_Handler_file_ex_s {
 | 
					 | 
				
			||||||
    unsigned int file_size;
 | 
					 | 
				
			||||||
    unsigned int file_size_max;
 | 
					 | 
				
			||||||
    unsigned int suffix;
 | 
					 | 
				
			||||||
    char        *file_name;
 | 
					 | 
				
			||||||
} log_Handler_file_ex_t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static unsigned int getFileSize(FILE *fp) {
 | 
					 | 
				
			||||||
    fseek(fp, 0L, SEEK_END);
 | 
					 | 
				
			||||||
    return ftell(fp);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief 文件日志处理器释放组件
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
static void __freeFileHandler(log_Handler *handler) {
 | 
					static void __freeFileHandler(log_Handler *handler) {
 | 
				
			||||||
    fclose(handler->stream);
 | 
					    fclose(handler->stream);
 | 
				
			||||||
    free(Handler_file_EX_PRT(handler)->file_name);
 | 
					 | 
				
			||||||
    free(handler);
 | 
					    free(handler);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void changeFile(log_Handler *handler) {
 | 
					/**
 | 
				
			||||||
    log_Handler_file_ex_t *handler_ex = Handler_file_EX_PRT(handler);
 | 
					 * @brief 文件日志处理器输出组件
 | 
				
			||||||
    fclose(handler->stream);
 | 
					 * @param handler 文件日志处理器
 | 
				
			||||||
    char new_file_name[FILE_NAME_MAX_SIZE];
 | 
					 * @param message 消息
 | 
				
			||||||
    sprintf(new_file_name,
 | 
					 */
 | 
				
			||||||
            "%s_%d.log",
 | 
					 | 
				
			||||||
            handler_ex->file_name,
 | 
					 | 
				
			||||||
            ++handler_ex->suffix);
 | 
					 | 
				
			||||||
    handler->stream       = fopen(new_file_name, "at");
 | 
					 | 
				
			||||||
    handler_ex->file_size = getFileSize(handler->stream);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void outputFileHandler(log_Handler *handler, const char *message) {
 | 
					static void outputFileHandler(log_Handler *handler, const char *message) {
 | 
				
			||||||
    fputs(message, handler->stream);
 | 
					    fputs(message, handler->stream);
 | 
				
			||||||
    log_Handler_file_ex_t *handler_ex = Handler_file_EX_PRT(handler);
 | 
					 | 
				
			||||||
    handler_ex->file_size += strlen(message);
 | 
					 | 
				
			||||||
    if (handler_ex->file_size > handler_ex->file_size_max)
 | 
					 | 
				
			||||||
        changeFile(handler);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
log_Handler *loggingHandlerFile(const char *name, unsigned int max_size) {
 | 
					/**
 | 
				
			||||||
    char                   new_file_name[FILE_NAME_MAX_SIZE];
 | 
					 * @brief 文件日志处理器
 | 
				
			||||||
    int                    suffix = 0;
 | 
					 * @param   name 文件名
 | 
				
			||||||
    unsigned int           file_size;
 | 
					 * @return  log_Handler *
 | 
				
			||||||
    FILE                  *fp         = NULL;
 | 
					 */
 | 
				
			||||||
    log_Handler           *handler    = NULL;
 | 
					log_Handler *loggingFileHandler(const char *name) {
 | 
				
			||||||
    log_Handler_file_ex_t *handler_ex = NULL;
 | 
					    char new_file_name[100];
 | 
				
			||||||
 | 
					    sprintf(new_file_name, "%s.log", name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// 获取未写满于设置最大文件大小的文件名
 | 
					    FILE *fp             = fopen(new_file_name, "at");
 | 
				
			||||||
    do {
 | 
					 | 
				
			||||||
        sprintf(new_file_name, "%s_%d.log", name, suffix++);
 | 
					 | 
				
			||||||
        fp = fopen(new_file_name, "at");
 | 
					 | 
				
			||||||
        if (fp == NULL)
 | 
					 | 
				
			||||||
            goto ERROR;
 | 
					 | 
				
			||||||
        file_size = getFileSize(fp);
 | 
					 | 
				
			||||||
    } while (file_size > max_size);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// 分配log_Handler与记录文件大小的空间
 | 
					    log_Handler *handler = (log_Handler *)malloc(sizeof(log_Handler));
 | 
				
			||||||
    handler = (log_Handler *)malloc(sizeof(log_Handler) +
 | 
					 | 
				
			||||||
                                    sizeof(log_Handler_file_ex_t));
 | 
					 | 
				
			||||||
    if (handler == NULL)
 | 
					 | 
				
			||||||
        goto ERROR;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    handler_ex                = Handler_file_EX_PRT(handler);
 | 
					 | 
				
			||||||
    handler_ex->file_size_max = max_size;
 | 
					 | 
				
			||||||
    handler_ex->file_size     = file_size;
 | 
					 | 
				
			||||||
    handler_ex->suffix        = suffix;
 | 
					 | 
				
			||||||
    handler_ex->file_name     = strdup(name);
 | 
					 | 
				
			||||||
    if (handler_ex->file_name == NULL)
 | 
					 | 
				
			||||||
        goto ERROR;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    handler->stream      = fp;
 | 
					    handler->stream      = fp;
 | 
				
			||||||
    handler->apply_color = false;
 | 
					    handler->apply_color = false;
 | 
				
			||||||
    handler->_free       = __freeFileHandler;
 | 
					    handler->_free       = __freeFileHandler;
 | 
				
			||||||
    handler->output      = outputFileHandler;
 | 
					    handler->output      = outputFileHandler;
 | 
				
			||||||
    return handler;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
ERROR:
 | 
					    return handler;
 | 
				
			||||||
    if (fp)
 | 
					 | 
				
			||||||
        fclose(fp);
 | 
					 | 
				
			||||||
    if (handler) {
 | 
					 | 
				
			||||||
        free(Handler_file_EX_PRT(handler)->file_name); // 直接释放,无需检查NULL
 | 
					 | 
				
			||||||
        free(handler);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return NULL;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										122
									
								
								src/interceptor/logging-interceptor-substr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								src/interceptor/logging-interceptor-substr.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,122 @@
 | 
				
			|||||||
 | 
					/********************************************
 | 
				
			||||||
 | 
					 * @Date: 2024 08 12
 | 
				
			||||||
 | 
					 * @Description: 子串拦截器
 | 
				
			||||||
 | 
					 *********************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "logging/logging-interceptor.h"
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static log_Interceptor *G_interceptor = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char **G_keywords              = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void get_next(char *str, int *next) {
 | 
				
			||||||
 | 
					    next[1] = 0;
 | 
				
			||||||
 | 
					    int i   = 1;
 | 
				
			||||||
 | 
					    int j   = 0;
 | 
				
			||||||
 | 
					    while (i < strlen(str)) {
 | 
				
			||||||
 | 
					        if (j == 0 || str[i] == str[j]) {
 | 
				
			||||||
 | 
					            next[++i] = ++j;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            j = next[j];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool kmp_search(char *substr, char *master) {
 | 
				
			||||||
 | 
					    int  i         = 0;
 | 
				
			||||||
 | 
					    int  j         = 0;
 | 
				
			||||||
 | 
					    int  substrlen = strlen(substr);
 | 
				
			||||||
 | 
					    int  masterlen = strlen(master);
 | 
				
			||||||
 | 
					    int *next      = (int *)malloc(sizeof(int) * substrlen + 1);
 | 
				
			||||||
 | 
					    get_next(substr, next);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (i < masterlen && j < substrlen) {
 | 
				
			||||||
 | 
					        if (master[i] == substr[j]) {
 | 
				
			||||||
 | 
					            i++;
 | 
				
			||||||
 | 
					            j++;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            if (j == 0) {
 | 
				
			||||||
 | 
					                i++;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                j = next[j];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    free(next);
 | 
				
			||||||
 | 
					    if (j == substrlen)
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @description 处理
 | 
				
			||||||
 | 
					 * @param
 | 
				
			||||||
 | 
					 * @return
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static bool _disposeSubstring(char *level, const char *message, ...) {
 | 
				
			||||||
 | 
					    int count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (G_keywords == NULL) {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (G_keywords[count] != NULL) {
 | 
				
			||||||
 | 
					        if (kmp_search(G_keywords[count], (char *)message)) {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        count++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @description : 完成拦截器自我释放内存
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static void _freeSubstring(log_Interceptor *interceptor) {
 | 
				
			||||||
 | 
					    int sum = 0;
 | 
				
			||||||
 | 
					    while (G_keywords[sum] != NULL) {
 | 
				
			||||||
 | 
					        free(G_keywords[sum]);
 | 
				
			||||||
 | 
					        sum++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    free(G_keywords);
 | 
				
			||||||
 | 
					    G_keywords = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (interceptor->handler != NULL) {
 | 
				
			||||||
 | 
					        interceptor->handler->_free(interceptor->handler);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    free(interceptor);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @description : 子字符串拦截器
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					log_Interceptor *loggingSubStringInterceptor(char        *keywords[],
 | 
				
			||||||
 | 
					                                             int          count,
 | 
				
			||||||
 | 
					                                             log_level    level,
 | 
				
			||||||
 | 
					                                             log_Handler *handler) {
 | 
				
			||||||
 | 
					    log_Interceptor *interceptor =
 | 
				
			||||||
 | 
					        (log_Interceptor *)malloc(sizeof(log_Interceptor));
 | 
				
			||||||
 | 
					    interceptor->_dispose = _disposeSubstring;
 | 
				
			||||||
 | 
					    interceptor->handler  = handler;
 | 
				
			||||||
 | 
					    interceptor->level    = level;
 | 
				
			||||||
 | 
					    interceptor->_free    = _freeSubstring;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    G_keywords            = (char **)malloc((sizeof(G_keywords) * count) + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int i = 0; i < count; i++) {
 | 
				
			||||||
 | 
					        G_keywords[i] = (char *)malloc(strlen(keywords[i]) + 1);
 | 
				
			||||||
 | 
					        strcpy(G_keywords[i], keywords[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    G_keywords[count] = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    G_interceptor     = interceptor;
 | 
				
			||||||
 | 
					    return G_interceptor;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										235
									
								
								src/logging.c
									
									
									
									
									
								
							
							
						
						
									
										235
									
								
								src/logging.c
									
									
									
									
									
								
							@@ -1,8 +1,9 @@
 | 
				
			|||||||
 | 
					/********************************************
 | 
				
			||||||
 | 
					 * @Date: 2024 08 12
 | 
				
			||||||
 | 
					 * @Description: 日志模块
 | 
				
			||||||
 | 
					 ********************************************/
 | 
				
			||||||
#include "logging.h"
 | 
					#include "logging.h"
 | 
				
			||||||
#include "logging/logging-core.h"
 | 
					 | 
				
			||||||
#include "logging/logging-handler.h"
 | 
					#include "logging/logging-handler.h"
 | 
				
			||||||
#include "utils/logging-utils.h"
 | 
					 | 
				
			||||||
#include <stdbool.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
@@ -15,71 +16,88 @@
 | 
				
			|||||||
#define BLUE    "\033[0;34m"
 | 
					#define BLUE    "\033[0;34m"
 | 
				
			||||||
#define RESET   "\033[0m"
 | 
					#define RESET   "\033[0m"
 | 
				
			||||||
#define CYAN    "\033[0;36m"
 | 
					#define CYAN    "\033[0;36m"
 | 
				
			||||||
 | 
					#define MAGENTA "\033[0;35m"
 | 
				
			||||||
 | 
					#define WHITE   "\033[0;37m"
 | 
				
			||||||
 | 
					#define BLACK   "\033[0;30m"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define LOG_BUFFER_SIZE 4096 // 日志缓冲区大小,单个日志长度不能超过该值
 | 
					#define LOG_BUFFER_SIZE 1024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Logger *G_LOGGER = NULL; // 全局日志对象,唯一实例
 | 
					Logger *G_LOGGER = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void getTimeStr(char *timeStr) {
 | 
				
			||||||
 | 
					    time_t     t = time(NULL);
 | 
				
			||||||
 | 
					    struct tm *p = localtime(&t);
 | 
				
			||||||
 | 
					    char       _timeStr[20];
 | 
				
			||||||
 | 
					    strftime(_timeStr, sizeof(_timeStr), "%Y-%m-%d %H:%M:%S", p);
 | 
				
			||||||
 | 
					    strcpy(timeStr, _timeStr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief 为日志添加一个handler
 | 
					 * @description : 添加日志处理器
 | 
				
			||||||
 * @param handler 处理器对象
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static bool addHandler(log_Handler *handler) {
 | 
					static void addHandler(log_Handler *handler) {
 | 
				
			||||||
    if (G_LOGGER == NULL || handler == NULL) {
 | 
					    if (G_LOGGER == NULL) {
 | 
				
			||||||
        return false;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (G_LOGGER->handler == NULL) {
 | 
					    if (G_LOGGER->handler == NULL) {
 | 
				
			||||||
        G_LOGGER->handler = handler;
 | 
					        G_LOGGER->handler = handler;
 | 
				
			||||||
        return true;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    G_LOGGER->handler->_free(G_LOGGER->handler);
 | 
					    G_LOGGER->handler->_free(G_LOGGER->handler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    G_LOGGER->handler = handler;
 | 
					    G_LOGGER->handler = handler;
 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief 为日志添加一个filter
 | 
					 * @description : 添加日志拦截器
 | 
				
			||||||
 * @param filter 过滤器对象
 | 
					 * @param
 | 
				
			||||||
 | 
					 * @return
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static bool addFilter(log_filter *filter) {
 | 
					void addInterceptor(log_Interceptor *Interceptor) {
 | 
				
			||||||
    if (G_LOGGER == NULL || filter == NULL) {
 | 
					    if (G_LOGGER == NULL) {
 | 
				
			||||||
        return false;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (G_LOGGER->filter == NULL) {
 | 
					    if (G_LOGGER->interceptor == NULL) {
 | 
				
			||||||
        G_LOGGER->filter       = filter;
 | 
					        G_LOGGER->interceptor = Interceptor;
 | 
				
			||||||
        G_LOGGER->filter->next = NULL;
 | 
					        return;
 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    log_filter *it = G_LOGGER->filter;
 | 
					    G_LOGGER->interceptor->_free(G_LOGGER->interceptor);
 | 
				
			||||||
    while (it->next != NULL) {
 | 
					 | 
				
			||||||
        it = it->next;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it->next     = filter;
 | 
					    G_LOGGER->interceptor = Interceptor;
 | 
				
			||||||
    filter->next = NULL;
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief 输出到handler
 | 
					 * @description : 内置日志记录函数
 | 
				
			||||||
 * @param handler 处理器对象
 | 
					 | 
				
			||||||
 * @param level 日志等级
 | 
					 | 
				
			||||||
 * @param color 应用的颜色
 | 
					 | 
				
			||||||
 * @param message 日志内容
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void output_to_handler(log_Handler *handler,
 | 
					static void
 | 
				
			||||||
                              char        *level,
 | 
					_builtin_log(char *level, const char *color, const char *message, ...) {
 | 
				
			||||||
                              const char  *color,
 | 
					    if (G_LOGGER == NULL) {
 | 
				
			||||||
                              const char  *message) {
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (G_LOGGER->handler == NULL) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    char timeStr[20];
 | 
					    char timeStr[20];
 | 
				
			||||||
    getTimeStr(timeStr);
 | 
					    getTimeStr(timeStr);
 | 
				
			||||||
    char logStr[LOG_BUFFER_SIZE * 2];
 | 
					    char logStr[LOG_BUFFER_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    log_Handler *handler = G_LOGGER->handler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 通过拦截器
 | 
				
			||||||
 | 
					    if (G_LOGGER->interceptor != NULL) {
 | 
				
			||||||
 | 
					        if (G_LOGGER->interceptor->_dispose(level, message)) {
 | 
				
			||||||
 | 
					            if (G_LOGGER->interceptor->handler != NULL) {
 | 
				
			||||||
 | 
					                handler = G_LOGGER->interceptor->handler;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 判断处理器是否应用颜色
 | 
				
			||||||
    if (handler->apply_color)
 | 
					    if (handler->apply_color)
 | 
				
			||||||
        snprintf(logStr,
 | 
					        sprintf(logStr,
 | 
				
			||||||
                 LOG_BUFFER_SIZE * 2,
 | 
					                "%s: %s %s%s%s %s\n",
 | 
				
			||||||
                 "[%s]: %s %s%s%s %s\n",
 | 
					 | 
				
			||||||
                G_LOGGER->name,
 | 
					                G_LOGGER->name,
 | 
				
			||||||
                timeStr,
 | 
					                timeStr,
 | 
				
			||||||
                color,
 | 
					                color,
 | 
				
			||||||
@@ -87,121 +105,75 @@ static void output_to_handler(log_Handler *handler,
 | 
				
			|||||||
                RESET,
 | 
					                RESET,
 | 
				
			||||||
                message);
 | 
					                message);
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        snprintf(logStr,
 | 
					        sprintf(
 | 
				
			||||||
                 LOG_BUFFER_SIZE * 2,
 | 
					            logStr, "%s: %s %s %s\n", G_LOGGER->name, timeStr, level, message);
 | 
				
			||||||
                 "[%s]: %s %s %s\n",
 | 
					 | 
				
			||||||
                 G_LOGGER->name,
 | 
					 | 
				
			||||||
                 timeStr,
 | 
					 | 
				
			||||||
                 level,
 | 
					 | 
				
			||||||
                 message);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    handler->output(handler, logStr);
 | 
					    handler->output(handler, logStr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					//*************************记录日志******************************* */
 | 
				
			||||||
 * @brief 内部日志打印处理核心函数
 | 
					static void fatal(const char *message, ...) {
 | 
				
			||||||
 * @param level 日志等级
 | 
					 | 
				
			||||||
 * @param color 应用的颜色
 | 
					 | 
				
			||||||
 * @param message 日志内容
 | 
					 | 
				
			||||||
 * @param ... 格式化参数列表
 | 
					 | 
				
			||||||
 * @return
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
static void _builtin_cope(log_level   level_e,
 | 
					 | 
				
			||||||
                          char       *level,
 | 
					 | 
				
			||||||
                          const char *color,
 | 
					 | 
				
			||||||
                          const char *message) {
 | 
					 | 
				
			||||||
    if (G_LOGGER == NULL) {
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (G_LOGGER->handler == NULL) {
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    log_filter  *it      = G_LOGGER->filter;
 | 
					 | 
				
			||||||
    log_Handler *handler = G_LOGGER->handler;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    while (it != NULL) {
 | 
					 | 
				
			||||||
        if (it->_dispose(it, level_e, message)) {
 | 
					 | 
				
			||||||
            output_to_handler(it->handler, level, color, message);
 | 
					 | 
				
			||||||
            if (it->jump_out)
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        it = it->next;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    output_to_handler(handler, level, color, message);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void log_fatal(const char *file, int line, const char *message, ...) {
 | 
					 | 
				
			||||||
    if (G_LOGGER->level >= LOG_ERROR) {
 | 
					    if (G_LOGGER->level >= LOG_ERROR) {
 | 
				
			||||||
        char    logStr[LOG_BUFFER_SIZE];
 | 
					        char    logStr[LOG_BUFFER_SIZE];
 | 
				
			||||||
        char    finalLogStr[LOG_BUFFER_SIZE * 2];
 | 
					 | 
				
			||||||
        va_list args;
 | 
					        va_list args;
 | 
				
			||||||
        va_start(args, message);
 | 
					        va_start(args, message);
 | 
				
			||||||
        vsprintf(logStr, message, args);
 | 
					        vsprintf(logStr, message, args);
 | 
				
			||||||
        va_end(args);
 | 
					        va_end(args);
 | 
				
			||||||
        snprintf(
 | 
					        _builtin_log("Fatal", RED_B, logStr, args);
 | 
				
			||||||
            finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr);
 | 
					 | 
				
			||||||
        _builtin_cope(LOG_FATAL, "Fatal", RED_B, finalLogStr);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void log_error(const char *file, int line, const char *message, ...) {
 | 
					static void error(const char *message, ...) {
 | 
				
			||||||
    if (G_LOGGER->level >= LOG_ERROR) {
 | 
					    if (G_LOGGER->level >= LOG_ERROR) {
 | 
				
			||||||
        char    logStr[LOG_BUFFER_SIZE];
 | 
					        char    logStr[LOG_BUFFER_SIZE];
 | 
				
			||||||
        char    finalLogStr[LOG_BUFFER_SIZE * 2];
 | 
					 | 
				
			||||||
        va_list args;
 | 
					        va_list args;
 | 
				
			||||||
        va_start(args, message);
 | 
					        va_start(args, message);
 | 
				
			||||||
        vsprintf(logStr, message, args);
 | 
					        vsprintf(logStr, message, args);
 | 
				
			||||||
        va_end(args);
 | 
					        va_end(args);
 | 
				
			||||||
        snprintf(
 | 
					        _builtin_log("Error", RED, logStr, args);
 | 
				
			||||||
            finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr);
 | 
					 | 
				
			||||||
        _builtin_cope(LOG_ERROR, "Error", RED, finalLogStr);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void log_warning(const char *file, int line, const char *message, ...) {
 | 
					static void warning(const char *message, ...) {
 | 
				
			||||||
    if (G_LOGGER->level >= LOG_WARNING) {
 | 
					    if (G_LOGGER->level >= LOG_WARNING) {
 | 
				
			||||||
        char    logStr[LOG_BUFFER_SIZE];
 | 
					        char    logStr[LOG_BUFFER_SIZE];
 | 
				
			||||||
        char    finalLogStr[LOG_BUFFER_SIZE * 2];
 | 
					 | 
				
			||||||
        va_list args;
 | 
					        va_list args;
 | 
				
			||||||
        va_start(args, message);
 | 
					        va_start(args, message);
 | 
				
			||||||
        vsprintf(logStr, message, args);
 | 
					        vsprintf(logStr, message, args);
 | 
				
			||||||
        va_end(args);
 | 
					        va_end(args);
 | 
				
			||||||
        snprintf(
 | 
					        _builtin_log("Warning", YELLOW, logStr, args);
 | 
				
			||||||
            finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr);
 | 
					 | 
				
			||||||
        _builtin_cope(LOG_WARNING, "Warning", YELLOW, finalLogStr);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void log_info(const char *file, int line, const char *message, ...) {
 | 
					static void info(const char *message, ...) {
 | 
				
			||||||
    if (G_LOGGER->level >= LOG_INFO) {
 | 
					    if (G_LOGGER->level >= LOG_INFO) {
 | 
				
			||||||
        char    logStr[LOG_BUFFER_SIZE];
 | 
					        char    logStr[LOG_BUFFER_SIZE];
 | 
				
			||||||
        char    finalLogStr[LOG_BUFFER_SIZE * 2];
 | 
					 | 
				
			||||||
        va_list args;
 | 
					        va_list args;
 | 
				
			||||||
        va_start(args, message);
 | 
					        va_start(args, message);
 | 
				
			||||||
        vsprintf(logStr, message, args);
 | 
					        vsprintf(logStr, message, args);
 | 
				
			||||||
        va_end(args);
 | 
					        va_end(args);
 | 
				
			||||||
        snprintf(
 | 
					        _builtin_log("Info", GREEN, logStr, args);
 | 
				
			||||||
            finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr);
 | 
					 | 
				
			||||||
        _builtin_cope(LOG_INFO, "Info", GREEN, finalLogStr);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void log_debug(const char *file, int line, const char *message, ...) {
 | 
					static void debug(const char *message, ...) {
 | 
				
			||||||
    if (G_LOGGER->level >= LOG_DEBUG) {
 | 
					    if (G_LOGGER->level >= LOG_DEBUG) {
 | 
				
			||||||
        char    logStr[LOG_BUFFER_SIZE];
 | 
					        char    logStr[LOG_BUFFER_SIZE];
 | 
				
			||||||
        char    finalLogStr[LOG_BUFFER_SIZE * 2];
 | 
					 | 
				
			||||||
        va_list args;
 | 
					        va_list args;
 | 
				
			||||||
        va_start(args, message);
 | 
					        va_start(args, message);
 | 
				
			||||||
        vsprintf(logStr, message, args);
 | 
					        vsprintf(logStr, message, args);
 | 
				
			||||||
        va_end(args);
 | 
					        va_end(args);
 | 
				
			||||||
        snprintf(
 | 
					        _builtin_log("Debug", CYAN, logStr, args);
 | 
				
			||||||
            finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr);
 | 
					 | 
				
			||||||
        _builtin_cope(LOG_DEBUG, "Debug", CYAN, finalLogStr);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					//*************************记录日志******************************* */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Logger *newDefaultLogger(const char *name, log_level level) {
 | 
					/**
 | 
				
			||||||
 | 
					 * @description :获取一个日志操作对象
 | 
				
			||||||
 | 
					 * @param
 | 
				
			||||||
 | 
					 * @return
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static Logger *getLogger(const char *name, log_level level) {
 | 
				
			||||||
    if (G_LOGGER != NULL) {
 | 
					    if (G_LOGGER != NULL) {
 | 
				
			||||||
        G_LOGGER->name  = name;
 | 
					        G_LOGGER->name  = name;
 | 
				
			||||||
        G_LOGGER->level = level;
 | 
					        G_LOGGER->level = level;
 | 
				
			||||||
@@ -209,47 +181,68 @@ Logger *newDefaultLogger(const char *name, log_level level) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Logger *logger         = (Logger *)malloc(sizeof(Logger));
 | 
					    Logger *logger         = (Logger *)malloc(sizeof(Logger));
 | 
				
			||||||
 | 
					    // 方法
 | 
				
			||||||
 | 
					    logger->fatal          = fatal;
 | 
				
			||||||
 | 
					    logger->error          = error;
 | 
				
			||||||
 | 
					    logger->warning        = warning;
 | 
				
			||||||
 | 
					    logger->info           = info;
 | 
				
			||||||
 | 
					    logger->debug          = debug;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    logger->addHandler     = addHandler;
 | 
					    logger->addHandler     = addHandler;
 | 
				
			||||||
    logger->addFilter  = addFilter;
 | 
					    logger->addInterceptor = addInterceptor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 属性
 | 
				
			||||||
    logger->level          = level;
 | 
					    logger->level          = level;
 | 
				
			||||||
    logger->handler    = loggingHandlerConsole();
 | 
					    logger->handler        = loggingConsoleHandler();
 | 
				
			||||||
    logger->name           = name;
 | 
					    logger->name           = name;
 | 
				
			||||||
    logger->filter     = NULL;
 | 
					    logger->interceptor    = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    G_LOGGER               = logger;
 | 
					    G_LOGGER               = logger;
 | 
				
			||||||
    return G_LOGGER;
 | 
					    return G_LOGGER;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @brief 销毁日志对象
 | 
					 * @description :销毁日志对象
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
log_status destroyDefaultLogger(void) {
 | 
					log_status destroyLogging(Logging *logging) {
 | 
				
			||||||
 | 
					    if (logging == NULL) {
 | 
				
			||||||
 | 
					        return L_ERROR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (G_LOGGER != NULL) {
 | 
					    if (G_LOGGER != NULL) {
 | 
				
			||||||
        if (G_LOGGER->handler != NULL) {
 | 
					        if (G_LOGGER->handler != NULL) {
 | 
				
			||||||
            G_LOGGER->handler->_free(G_LOGGER->handler);
 | 
					            G_LOGGER->handler->_free(G_LOGGER->handler);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (G_LOGGER->filter != NULL) {
 | 
					        if (G_LOGGER->interceptor != NULL) {
 | 
				
			||||||
            log_filter *it   = G_LOGGER->filter;
 | 
					            G_LOGGER->interceptor->_free(G_LOGGER->interceptor);
 | 
				
			||||||
            log_filter *next = NULL;
 | 
					 | 
				
			||||||
            while (it != NULL) {
 | 
					 | 
				
			||||||
                next = it->next;
 | 
					 | 
				
			||||||
                it->_free(it);
 | 
					 | 
				
			||||||
                it = next;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        free(G_LOGGER);
 | 
					        free(G_LOGGER);
 | 
				
			||||||
        G_LOGGER = NULL;
 | 
					        G_LOGGER = NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    free(logging);
 | 
				
			||||||
    return L_OK;
 | 
					    return L_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Logger *getDefaultLogger(void) {
 | 
					/**
 | 
				
			||||||
 | 
					 * @description :获取当前日志操作对象
 | 
				
			||||||
 | 
					 * @return 当前唯一的日志操作对象
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					Logger *getCurrentLogger(void) {
 | 
				
			||||||
    if (G_LOGGER == NULL) {
 | 
					    if (G_LOGGER == NULL) {
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return G_LOGGER;
 | 
					    return G_LOGGER;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @description :创建一个日志对象
 | 
				
			||||||
 | 
					 * @return :Logging* 返回一个日志对象
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					Logging *newLogging() {
 | 
				
			||||||
 | 
					    Logging *logging          = (Logging *)malloc(sizeof(Logging));
 | 
				
			||||||
 | 
					    logging->getLogger        = getLogger;
 | 
				
			||||||
 | 
					    logging->destroyLogging   = destroyLogging;
 | 
				
			||||||
 | 
					    logging->getCurrentLogger = getCurrentLogger;
 | 
				
			||||||
 | 
					    return logging;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,15 +0,0 @@
 | 
				
			|||||||
#include "logging-utils.h"
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
#include <time.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @brief 获取当前时间字符串
 | 
					 | 
				
			||||||
 * @param timeStr 存储时间字符串缓冲区指针
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void getTimeStr(char *timeStr) {
 | 
					 | 
				
			||||||
    time_t     t = time(NULL);
 | 
					 | 
				
			||||||
    struct tm *p = localtime(&t);
 | 
					 | 
				
			||||||
    char       _timeStr[20];
 | 
					 | 
				
			||||||
    strftime(_timeStr, sizeof(_timeStr), "%Y-%m-%d %H:%M:%S", p);
 | 
					 | 
				
			||||||
    strcpy(timeStr, _timeStr);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,5 +0,0 @@
 | 
				
			|||||||
#ifndef __LOGGING_UTILS_H__
 | 
					 | 
				
			||||||
#define __LOGGING_UTILS_H__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void getTimeStr(char *timeStr);
 | 
					 | 
				
			||||||
#endif // __LOGGING_UTILS_H__
 | 
					 | 
				
			||||||
@@ -1,30 +1,8 @@
 | 
				
			|||||||
project(test)
 | 
					project(test)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enable_testing()
 | 
					add_executable(${PROJECT_NAME}simple test_simple.c)
 | 
				
			||||||
 | 
					target_link_libraries(${PROJECT_NAME}simple Logging)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#测试简单基本应用
 | 
					 | 
				
			||||||
add_executable(${PROJECT_NAME}simple test-simple.c)
 | 
					 | 
				
			||||||
target_link_libraries(${PROJECT_NAME}simple logging)
 | 
					 | 
				
			||||||
if(UNIX)
 | 
					 | 
				
			||||||
    add_test(test_simple ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}simple)
 | 
					 | 
				
			||||||
elseif(WIN32)
 | 
					 | 
				
			||||||
    add_test(test_simple ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}simple.exe)
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#测试简单基本应用
 | 
					add_executable(${PROJECT_NAME}interceptor test_interceptor.c)
 | 
				
			||||||
add_executable(${PROJECT_NAME}file test-log-file.c)
 | 
					target_link_libraries(${PROJECT_NAME}interceptor Logging)
 | 
				
			||||||
target_link_libraries(${PROJECT_NAME}file logging)
 | 
					 | 
				
			||||||
if(UNIX)
 | 
					 | 
				
			||||||
    add_test(test_file ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}file)
 | 
					 | 
				
			||||||
elseif(WIN32)
 | 
					 | 
				
			||||||
    add_test(test_file ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}file.exe)
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#测试拦截器
 | 
					 | 
				
			||||||
add_executable(${PROJECT_NAME}filter test-filter.c)
 | 
					 | 
				
			||||||
target_link_libraries(${PROJECT_NAME}filter logging)
 | 
					 | 
				
			||||||
if(UNIX)
 | 
					 | 
				
			||||||
    add_test(test_filter ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}filter)
 | 
					 | 
				
			||||||
elseif(WIN32)
 | 
					 | 
				
			||||||
    add_test(test_filter ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}filter.exe)
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,49 +0,0 @@
 | 
				
			|||||||
#include "logging.h"
 | 
					 | 
				
			||||||
#include "logging/logging-core.h"
 | 
					 | 
				
			||||||
#include "logging/logging-filter.h"
 | 
					 | 
				
			||||||
#include <stdbool.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <time.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main() {
 | 
					 | 
				
			||||||
    Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Log_info("This is an info message");
 | 
					 | 
				
			||||||
    Log_error("This is an error message%s", "123");
 | 
					 | 
				
			||||||
    Log_fatal("This is an fatal message");
 | 
					 | 
				
			||||||
    Log_debug("This is a debug message");
 | 
					 | 
				
			||||||
    Log_warning("This is a warning message%s", "123");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char *test1[] = {"This", NULL};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    log_filter *tint =
 | 
					 | 
				
			||||||
        loggingFilterSubStr(test1,
 | 
					 | 
				
			||||||
                            LOG_DEBUG,
 | 
					 | 
				
			||||||
                            loggingHandlerFile("test_interceptor", 1024 * 1024),
 | 
					 | 
				
			||||||
                            false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    logger->addFilter(tint);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char *test2[]     = {"123", NULL};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    log_filter *tint1 = loggingFilterSubStr(
 | 
					 | 
				
			||||||
        test2,
 | 
					 | 
				
			||||||
        LOG_ERROR,
 | 
					 | 
				
			||||||
        loggingHandlerFile("test_interceptor1", 1024 * 1024),
 | 
					 | 
				
			||||||
        true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    logger->addFilter(tint1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    printf("\n");
 | 
					 | 
				
			||||||
    printf("filter added\n");
 | 
					 | 
				
			||||||
    printf("\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Log_info("This is an info message");
 | 
					 | 
				
			||||||
    Log_error("This is an error message%s", "123");
 | 
					 | 
				
			||||||
    Log_fatal("This is an fatal message");
 | 
					 | 
				
			||||||
    Log_debug("This is a debug message");
 | 
					 | 
				
			||||||
    Log_warning("This is a warning message%s", "123");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    destroyDefaultLogger();
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,17 +0,0 @@
 | 
				
			|||||||
#include "logging.h"
 | 
					 | 
				
			||||||
#include "logging/logging-handler.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main() {
 | 
					 | 
				
			||||||
    Logger      *logger = newDefaultLogger("testLogger", LOG_DEBUG);
 | 
					 | 
				
			||||||
    log_Handler *hander = loggingHandlerFile("test_log", 1024 * 1024 * 10);
 | 
					 | 
				
			||||||
    logger->addHandler(hander);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Log_info("This is an info message");
 | 
					 | 
				
			||||||
    Log_error("This is an error message%s", "123");
 | 
					 | 
				
			||||||
    Log_fatal("This is an fatal message");
 | 
					 | 
				
			||||||
    Log_debug("This is a debug message");
 | 
					 | 
				
			||||||
    Log_warning("This is a warning message%s", "123");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    destroyDefaultLogger();
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,14 +0,0 @@
 | 
				
			|||||||
#include "logging.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main() {
 | 
					 | 
				
			||||||
    Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Log_info("This is an info message");
 | 
					 | 
				
			||||||
    Log_error("This is an error message%s", "123");
 | 
					 | 
				
			||||||
    Log_fatal("This is an fatal message");
 | 
					 | 
				
			||||||
    Log_debug("This is a debug message");
 | 
					 | 
				
			||||||
    Log_warning("This is a warning message%s", "123");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    destroyDefaultLogger();
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										33
									
								
								tests/test_interceptor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								tests/test_interceptor.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					#include "logging.h"
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main() {
 | 
				
			||||||
 | 
					    Logging *log    = newLogging();
 | 
				
			||||||
 | 
					    Logger  *logger = log->getLogger("testLogger", LOG_DEBUG);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    logger->info("This is an info message");
 | 
				
			||||||
 | 
					    logger->error("你好,这是一个错误消息%s", "123");
 | 
				
			||||||
 | 
					    logger->fatal("This is an fatal message");
 | 
				
			||||||
 | 
					    logger->debug("This is a debug message");
 | 
				
			||||||
 | 
					    logger->warning("This is a warning message%s", "123");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *test1[] = {"123", "你好"}; // 要拦截的字符串
 | 
				
			||||||
 | 
					    // 添加拦截器,将拦截到的日志重定向到拦截器的专属处理器中
 | 
				
			||||||
 | 
					    log_Interceptor *tint =
 | 
				
			||||||
 | 
					        loggingSubStringInterceptor(test1, 2, LOG_DEBUG, loggingFileHandler("被拦截"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    logger->addInterceptor(tint);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("\n");
 | 
				
			||||||
 | 
					    printf("Interceptor added\n");
 | 
				
			||||||
 | 
					    printf("\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    logger->info("This is an info message");
 | 
				
			||||||
 | 
					    logger->error("你好,这是一个错误消息%s", "123");
 | 
				
			||||||
 | 
					    logger->fatal("This is an fatal message");
 | 
				
			||||||
 | 
					    logger->debug("This is a debug message");
 | 
				
			||||||
 | 
					    logger->warning("This is a warning message%s", "123");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    log->destroyLogging(log);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								tests/test_simple.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tests/test_simple.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					#include "logging.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main() {
 | 
				
			||||||
 | 
					    Logging *log    = newLogging();
 | 
				
			||||||
 | 
					    Logger  *logger = log->getLogger("testLogger", LOG_DEBUG);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    logger->info("This is an info message");
 | 
				
			||||||
 | 
					    logger->error("你好,这是一个错误消息%s", "123");
 | 
				
			||||||
 | 
					    logger->fatal("This is an fatal message");
 | 
				
			||||||
 | 
					    logger->debug("This is a debug message");
 | 
				
			||||||
 | 
					    logger->warning("This is a warning message%s", "123");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    log->destroyLogging(log);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user