Compare commits
59 Commits
86cf4c4526
...
github_mai
| Author | SHA1 | Date | |
|---|---|---|---|
| ef62dc2075 | |||
| 359c9f247a | |||
| aecfbbb74a | |||
| b273fd86e8 | |||
| 8fef266119 | |||
| 6ff484fef8 | |||
| e04a960777 | |||
| b2eec437cd | |||
|
|
8e512563e4 | ||
| 3f5153b110 | |||
| 09dd534675 | |||
| 633e91f80b | |||
|
|
9d3a7bbb8d | ||
|
|
fde26f4f42 | ||
| 214665ec91 | |||
|
|
064881c0ad | ||
| 942970336c | |||
| 1c09c41ea3 | |||
|
|
f0c3a5d56a | ||
|
|
56e1ac52ff | ||
| 9b777e4862 | |||
|
|
0b749c8d1d | ||
| 5c24b070bb | |||
|
|
cc53e07788 | ||
| 915c18640a | |||
|
|
a4b4ad7452 | ||
|
|
feca0ef8e3 | ||
| b9abf6c7d3 | |||
| 6ac7afd4c2 | |||
|
|
f4494515ca | ||
| 7afc3d3b41 | |||
|
|
d0bfc31563 | ||
|
|
a6392e27ce | ||
| 8a57c43180 | |||
| e57f0fa02c | |||
| de03985fef | |||
|
|
650ce0dc3f | ||
|
|
81cebc7a18 | ||
| 41004e5735 | |||
| de141cbafc | |||
|
|
3ef229ed65 | ||
| 668f88f8af | |||
| 34f818196e | |||
| 78341d522c | |||
| 2ecdefa239 | |||
| be445cdfe7 | |||
| 24f7124dfb | |||
| 8eb324ad23 | |||
|
|
b7f49188ad | ||
|
|
406dbc5a79 | ||
| 0fa6097bbf | |||
| f6e2c31c85 | |||
|
|
d61f7b6fde | ||
|
|
c7c6af7dcf | ||
| 0d78195e4e | |||
| 01273809da | |||
| 4213c38730 | |||
| 9963f68175 | |||
| 85ae9d3deb |
92
.clang-tidy
Normal file
92
.clang-tidy
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
Checks: '-*,
|
||||
clang-analyzer-core.*,
|
||||
clang-analyzer-cplusplus.*,
|
||||
modernize-redundant-void-arg,
|
||||
modernize-use-bool-literals,
|
||||
modernize-use-equals-default,
|
||||
modernize-use-nullptr,
|
||||
modernize-use-override,
|
||||
google-explicit-constructor,
|
||||
google-readability-casting,
|
||||
readability-braces-around-statements,
|
||||
readability-identifier-naming.ClassCase,
|
||||
readability-identifier-naming.StructCase,
|
||||
readability-identifier-naming.TypedefCase,
|
||||
readability-identifier-naming.EnumCase,
|
||||
readability-non-const-parameter,
|
||||
cert-dcl21-cpp,
|
||||
bugprone-undelegated-constructor,
|
||||
bugprone-macro-parentheses,
|
||||
bugprone-macro-repeated-side-effects,
|
||||
bugprone-forward-declaration-namespace,
|
||||
bugprone-bool-pointer-implicit-conversion,
|
||||
bugprone-misplaced-widening-cast,
|
||||
cppcoreguidelines-narrowing-conversions,
|
||||
misc-unconventional-assign-operator,
|
||||
misc-unused-parameters'
|
||||
WarningsAsErrors: ''
|
||||
HeaderFilterRegex: ''
|
||||
CheckOptions:
|
||||
# 现代化(Modernize)
|
||||
- key: modernize-redundant-void-arg
|
||||
value: 'true' # 检查并移除函数声明中冗余的 void 参数。
|
||||
- key: modernize-use-bool-literals
|
||||
value: 'true' # 建议使用布尔字面量 true 和 false 代替整数值 0 和 1。
|
||||
- key: modernize-use-equals-default
|
||||
value: 'true' # 建议在默认构造函数、复制构造函数和赋值运算符中使用 = default,以简化代码。
|
||||
- key: modernize-use-nullptr
|
||||
value: 'true' # 建议使用 nullptr 代替 NULL 或 0 来表示空指针。
|
||||
- key: modernize-use-override
|
||||
value: 'true' # 建议在覆盖基类虚函数时使用 override 关键字,以增加代码的清晰性和安全性。
|
||||
|
||||
# Google 代码风格(Google)
|
||||
- key: google-explicit-constructor
|
||||
value: 'true' # 检查并建议在单参数构造函数中使用 explicit 关键字,以防止隐式转换。
|
||||
- key: google-readability-casting
|
||||
value: 'true' # 检查并建议使用 C++ 风格的类型转换(如 static_cast、dynamic_cast、const_cast 和 reinterpret_cast)代替 C 风格的类型转换。
|
||||
|
||||
# 可读性(Readability)
|
||||
- key: readability-braces-around-statements
|
||||
value: 'true' # 建议在单行语句周围添加大括号,以提高代码的可读性和一致性。
|
||||
- key: readability-identifier-naming.ClassCase
|
||||
value: 'CamelCase' # 类名应使用 CamelCase 风格,例如 MyClassName。
|
||||
- key: readability-identifier-naming.StructCase
|
||||
value: 'CamelCase' # 结构体名应使用 CamelCase 风格,例如 MyStructName。
|
||||
- key: readability-identifier-naming.TypedefCase
|
||||
value: 'CamelCase' # 类型定义应使用 CamelCase 风格,例如 MyTypeDef。
|
||||
- key: readability-identifier-naming.EnumCase
|
||||
value: 'CamelCase' # 枚举名应使用 CamelCase 风格,例如 MyEnumName。
|
||||
- key: readability-non-const-parameter
|
||||
value: 'true' # 检查并标识非 const 参数,以提高代码的可读性和安全性。
|
||||
|
||||
# CERT 安全编码标准(CERT)
|
||||
- key: cert-dcl21-cpp
|
||||
value: 'true' # 检查并标识在头文件中不应包含无命名空间的 using 声明和指令,以防止命名空间污染。
|
||||
|
||||
# Bug 检测(Bugprone)
|
||||
- key: bugprone-undelegated-constructor
|
||||
value: 'true' # 检查并标识未委托的构造函数,以确保构造函数的正确性。
|
||||
- key: bugprone-macro-parentheses
|
||||
value: 'true' # 检查并建议在宏定义中使用括号,以防止潜在的错误。
|
||||
- key: bugprone-macro-repeated-side-effects
|
||||
value: 'true' # 检查并标识宏中重复的副作用,以防止潜在的错误。
|
||||
- key: bugprone-forward-declaration-namespace
|
||||
value: 'true' # 检查并标识命名空间前向声明的潜在问题。
|
||||
- key: bugprone-bool-pointer-implicit-conversion
|
||||
value: 'true' # 检查并标识布尔指针的隐式转换,以防止潜在的错误。
|
||||
- key: bugprone-misplaced-widening-cast
|
||||
value: 'true' # 检查并标识错误的宽化转换,以防止潜在的错误。
|
||||
|
||||
# C++ 核心指南(CppCoreGuidelines)
|
||||
- key: cppcoreguidelines-narrowing-conversions
|
||||
value: 'true' # 检查并标识可能导致数据丢失的窄化转换。
|
||||
|
||||
# 杂项(Miscellaneous)
|
||||
- key: misc-unconventional-assign-operator
|
||||
value: 'true' # 检查并标识不常见的赋值操作符重载,以确保代码的一致性和可维护性。
|
||||
- key: misc-unused-parameters
|
||||
value: 'true' # 检测未使用的参数。
|
||||
...
|
||||
|
||||
|
||||
16
.github/workflows/linux_test.yml
vendored
Normal file
16
.github/workflows/linux_test.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
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
Normal file
17
.github/workflows/windows_test.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
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
.python-version
Normal file
1
.python-version
Normal file
@@ -0,0 +1 @@
|
||||
3.12
|
||||
@@ -1,9 +1,19 @@
|
||||
cmake_minimum_required( VERSION 3.28)
|
||||
cmake_minimum_required(VERSION 3.28...3.30)
|
||||
|
||||
project(logging)
|
||||
|
||||
set(LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
|
||||
set(ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_CLANG_TIDY "clang-tidy")
|
||||
|
||||
if(MSVC)
|
||||
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)
|
||||
|
||||
@@ -11,7 +21,13 @@ include_directories(${CMAKE_SOURCE_DIR}/include)
|
||||
add_subdirectory(src)
|
||||
|
||||
#测试单元
|
||||
if (SKIPTEST)
|
||||
else()
|
||||
if (TEST)
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
|
||||
install(FILES include/logging.h DESTINATION include)
|
||||
install(FILES include/logging/logging-core.h DESTINATION include/logging)
|
||||
install(FILES include/logging/logging-filter.h DESTINATION include/logging)
|
||||
install(FILES include/logging/logging-handler.h DESTINATION include/logging)
|
||||
|
||||
163
README.en.md
Normal file
163
README.en.md
Normal file
@@ -0,0 +1,163 @@
|
||||
# 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,5 +1,7 @@
|
||||
# C语言日志库logging
|
||||
|
||||
[English](README.en.md)
|
||||
|
||||
## 简介
|
||||
|
||||
logging是一个轻量级的简单易用C语言日志库,支持日志级别、日志格式、日志输出、日志文件等功能。
|
||||
@@ -9,25 +11,51 @@ logging是一个轻量级的简单易用C语言日志库,支持日志级别、
|
||||
- 支持日志级别: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
|
||||
#include "logging.h"
|
||||
|
||||
int main() {
|
||||
Logging *log = newLogging();
|
||||
Logger *logger = log->getLogger("testLogger", LOG_DEBUG);
|
||||
Logger *logger = newDefaultLogger("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_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");
|
||||
|
||||
log->destroyLogging(log);
|
||||
destroyDefaultLogger();
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
@@ -35,72 +63,117 @@ int main() {
|
||||
### 文件日志
|
||||
```c
|
||||
#include "logging.h"
|
||||
#include "logging/logging-handler.h"
|
||||
|
||||
int main() {
|
||||
Logging *log = newLogging();
|
||||
Logger *logger = log->getLogger("testLogger",LOG_DEBUG);
|
||||
Logger *logger = newDefaultLogger("testLogger", LOG_DEBUG);
|
||||
logger->addHandler(loggingHandlerFile("test1", 1024*1024));
|
||||
|
||||
logger->addHandler(loggingFileHandler("test")); //为日志对象添加文件处理器
|
||||
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");
|
||||
|
||||
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);
|
||||
destroyDefaultLogger();
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### 日志拦截器
|
||||
> 支持添加自定义的拦截器, 目前内置了子串拦截器
|
||||
### 日志过滤器
|
||||
> 支持添加自定义的过滤器, 目前内置了子串过滤器
|
||||
|
||||
> 拦截器的作用:可以将拦截到的日志重定向到拦截器的专属处理器中
|
||||
> 过滤器的作用:可以将过滤到的日志重定向到过滤器的专属处理器中
|
||||
|
||||
|
||||
#### 例子
|
||||
将拦截到的日志重定向到专属文件处理器中
|
||||
#### 单个子串过滤器
|
||||
将过滤到的日志重定向到专属处理器中
|
||||
```c
|
||||
#include "logging.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
Logging *log = newLogging();
|
||||
Logger *logger = log->getLogger("testLogger", LOG_DEBUG);
|
||||
Logger *logger = newDefaultLogger("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_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", "你好"}; // 要拦截的字符串
|
||||
// 添加拦截器,将拦截到的日志重定向到拦截器的专属处理器中
|
||||
log_Interceptor *tint =
|
||||
loggingSubStringInterceptor(test1, 2, LOG_DEBUG, loggingFileHandler("被拦截"));
|
||||
char *test1[] = {"123", "tt", NULL};
|
||||
|
||||
logger->addInterceptor(tint);
|
||||
log_filter *tint = loggingFilterSubStr(
|
||||
test1,
|
||||
LOG_DEBUG,
|
||||
loggingHandlerFile("test_interceptor", 1024 * 1024),
|
||||
true);
|
||||
|
||||
logger->addFilter(tint);
|
||||
|
||||
printf("\n");
|
||||
printf("Interceptor added\n");
|
||||
printf("filter 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_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");
|
||||
|
||||
log->destroyLogging(log);
|
||||
destroyDefaultLogger();
|
||||
return 0;
|
||||
}
|
||||
```
|
||||

|
||||

|
||||
|
||||
#### 多个子串过滤器
|
||||
```c
|
||||
#include "logging.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
# build
|
||||
```shell
|
||||
conan create . --build=missing
|
||||
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;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
29
conanfile.py
29
conanfile.py
@@ -1,14 +1,11 @@
|
||||
from conan import ConanFile
|
||||
from conan.tools.cmake import CMake, CMakeToolchain, CMakeDeps, cmake_layout
|
||||
from conan.tools.files import copy, get
|
||||
from conan.tools.build import check_min_cppstd
|
||||
from conan import tools
|
||||
from conan.tools.files import copy
|
||||
import os
|
||||
|
||||
|
||||
class loggingRecipe(ConanFile):
|
||||
name = "logging"
|
||||
version = "0.2.3"
|
||||
version = "0.5.1"
|
||||
license = "MIT"
|
||||
author = "321640253@qq.com"
|
||||
url = "https://github.com/WangZhongDian/logging.git"
|
||||
@@ -16,11 +13,11 @@ class loggingRecipe(ConanFile):
|
||||
topics = ("logging", "C", "simple", "easy-to-use", "log","Logging")
|
||||
|
||||
settings = "os", "compiler", "build_type", "arch"
|
||||
options = {"shared": [True, False], "fPIC": [True, False]}
|
||||
default_options = {"shared": False, "fPIC": True}
|
||||
options = {"shared": [True, False], "fPIC": [True, False],"test":[True,False]}
|
||||
default_options = {"shared": False, "fPIC": True,"test":True}
|
||||
|
||||
|
||||
exports_sources = "include/*", "CMakeLists.txt", "src/*"
|
||||
exports_sources = "include/*", "CMakeLists.txt", "src/*", "tests/*"
|
||||
|
||||
def config_options(self):
|
||||
if self.settings.os == "Windows":
|
||||
@@ -30,8 +27,6 @@ class loggingRecipe(ConanFile):
|
||||
if self.options.shared:
|
||||
self.options.rm_safe("fPIC")
|
||||
|
||||
|
||||
|
||||
def layout(self):
|
||||
cmake_layout(self)
|
||||
|
||||
@@ -39,18 +34,16 @@ class loggingRecipe(ConanFile):
|
||||
deps = CMakeDeps(self)
|
||||
deps.generate()
|
||||
tc = CMakeToolchain(self)
|
||||
tc.variables["SKIPTEST"]=True
|
||||
if self.options.shared:
|
||||
tc.variables["SHARED"] = True
|
||||
else:
|
||||
tc.variables["SHARED"] = False
|
||||
tc.variables["TEST"] = True if self.options.test else False
|
||||
tc.variables["SHARED"] = True if self.options.shared else False
|
||||
tc.generate()
|
||||
|
||||
def build(self):
|
||||
cmake = CMake(self)
|
||||
cmake.configure()
|
||||
cmake.build(target="Logging")
|
||||
|
||||
cmake.build()
|
||||
if self.options.test:
|
||||
cmake.test()
|
||||
|
||||
def package(self):
|
||||
copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"))
|
||||
@@ -62,4 +55,4 @@ class loggingRecipe(ConanFile):
|
||||
copy(self, pattern="*.dylib", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False)
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.libs = ["Logging"]
|
||||
self.cpp_info.libs = ["logging"]
|
||||
|
||||
@@ -5,33 +5,61 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "logging/logging-core.h"
|
||||
#include "logging/logging-filter.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 {
|
||||
log_level level;
|
||||
log_Handler *handler;
|
||||
log_Interceptor *interceptor;
|
||||
const char *name;
|
||||
void (*fatal)(const char *format, ...);
|
||||
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);
|
||||
log_level level;
|
||||
log_Handler *handler;
|
||||
log_filter *filter;
|
||||
const char *name;
|
||||
bool (*addHandler)(log_Handler *handler);
|
||||
bool (*addFilter)(log_filter *filter);
|
||||
} Logger;
|
||||
|
||||
// 日志类对象
|
||||
typedef struct Logging {
|
||||
Logger *(*getLogger)(const char *name, log_level level);
|
||||
log_status (*setLevel)(Logger *logger, log_level level);
|
||||
Logger *(*getCurrentLogger)(void);
|
||||
log_status (*destroyLogging)(struct Logging *logging);
|
||||
} Logging;
|
||||
void log_fatal(const char *file, int line, const char *format, ...);
|
||||
void log_error(const char *file, int line, const char *format, ...);
|
||||
void log_warning(const char *file, int line, const char *format, ...);
|
||||
void log_info(const char *file, int line, const char *format, ...);
|
||||
void log_debug(const char *file, int line, const char *format, ...);
|
||||
|
||||
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__
|
||||
@@ -1,8 +1,12 @@
|
||||
#ifndef __LOGGING_CORE_H__
|
||||
#define __LOGGING_CORE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
LOG_FATAL,
|
||||
LOG_FATAL = 0,
|
||||
LOG_ERROR,
|
||||
LOG_WARNING,
|
||||
LOG_INFO,
|
||||
@@ -14,5 +18,8 @@ typedef enum {
|
||||
L_OK,
|
||||
} log_status;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LOGGING_CORE_H__
|
||||
|
||||
41
include/logging/logging-filter.h
Normal file
41
include/logging/logging-filter.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#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,15 +3,34 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct log_Handler {
|
||||
void* stream;
|
||||
bool apply_color;
|
||||
void (*_free)(struct log_Handler* handler);//释放资源
|
||||
void (*output)(struct log_Handler* handler,const char* message);
|
||||
void *stream;
|
||||
bool apply_color;
|
||||
void (*_free)(struct log_Handler *handler);
|
||||
void (*output)(struct log_Handler *handler, const char *message);
|
||||
} log_Handler;
|
||||
|
||||
/**
|
||||
* @brief 文件处理器
|
||||
* @param file_name 文件名
|
||||
* @param max_size 文件最大大小
|
||||
* @return
|
||||
*/
|
||||
log_Handler *loggingHandlerFile(const char *file_name, unsigned int max_size);
|
||||
|
||||
log_Handler* loggingFileHandler(const char* name);
|
||||
log_Handler* loggingConsoleHandler();
|
||||
/**
|
||||
* @brief 控制台处理器
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
log_Handler *loggingHandlerConsole();
|
||||
|
||||
#endif //__LOGGING_HANDLER_H__
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__LOGGING_HANDLER_H__
|
||||
@@ -1,20 +0,0 @@
|
||||
#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__
|
||||
16
makefile
Normal file
16
makefile
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
|
||||
.PHONY:format
|
||||
|
||||
format:
|
||||
bash script/format.sh
|
||||
|
||||
build:
|
||||
cmake -S . -B build
|
||||
cmake --build build
|
||||
|
||||
test: build
|
||||
cd build && ctest
|
||||
|
||||
clean:
|
||||
rm -rf build
|
||||
9
pyproject.toml
Normal file
9
pyproject.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[project]
|
||||
name = "logging"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"conan>=2.18.1",
|
||||
]
|
||||
3
script/format.sh
Normal file
3
script/format.sh
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/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 {} +
|
||||
2
script/test.sh
Executable file
2
script/test.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
cmake build -B build . && cd build && cmake --build . && ctest
|
||||
5
script/test_windows.ps1
Normal file
5
script/test_windows.ps1
Normal file
@@ -0,0 +1,5 @@
|
||||
cmake build -B build .
|
||||
Set-Location -Path "./build"
|
||||
cmake --build .
|
||||
ctest
|
||||
Set-Location -Path ".."
|
||||
@@ -1,8 +1,9 @@
|
||||
project(Logging)
|
||||
project(logging)
|
||||
|
||||
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRC)
|
||||
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/handler SRC)
|
||||
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/interceptor SRC)
|
||||
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/filter SRC)
|
||||
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/utils SRC)
|
||||
|
||||
if (SHARED)
|
||||
add_library(${PROJECT_NAME} SHARED ${SRC})
|
||||
@@ -10,3 +11,4 @@ else()
|
||||
add_library(${PROJECT_NAME} ${SRC})
|
||||
endif()
|
||||
|
||||
install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib)
|
||||
139
src/filter/logging-filter-substr.c
Normal file
139
src/filter/logging-filter-substr.c
Normal file
@@ -0,0 +1,139 @@
|
||||
#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;
|
||||
size_t substrlen = strlen(substr);
|
||||
size_t 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,36 +1,20 @@
|
||||
/********************************************
|
||||
* @Date: 2024 09 18
|
||||
* @Description: 控制台日志处理器
|
||||
********************************************/
|
||||
#include "logging/logging-handler.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* @brief 释放组件
|
||||
* @param handler 处理器
|
||||
*/
|
||||
static void __freeConsoleHandler(log_Handler *handler) { free(handler); }
|
||||
static void __freeHandlerConsole(log_Handler *handler) { free(handler); }
|
||||
|
||||
/**
|
||||
* @brief 输出组件
|
||||
* @param handler 处理器
|
||||
* @param message 消息
|
||||
*/
|
||||
static void outputConsoleHandler(log_Handler *handler, const char *message) {
|
||||
static void __outputHandlerConsole(log_Handler *handler, const char *message) {
|
||||
fputs(message, handler->stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief :控制台日志处理器
|
||||
*/
|
||||
log_Handler *loggingConsoleHandler() {
|
||||
log_Handler *loggingHandlerConsole() {
|
||||
log_Handler *handler = (log_Handler *)malloc(sizeof(log_Handler));
|
||||
|
||||
handler->stream = stdout;
|
||||
handler->apply_color = true;
|
||||
handler->_free = __freeConsoleHandler;
|
||||
handler->output = outputConsoleHandler;
|
||||
handler->_free = __freeHandlerConsole;
|
||||
handler->output = __outputHandlerConsole;
|
||||
|
||||
return handler;
|
||||
}
|
||||
@@ -1,45 +1,103 @@
|
||||
/********************************************
|
||||
* @Date: 2024 09 18
|
||||
* @Description: 文件日志处理器
|
||||
********************************************/
|
||||
#include "logging/logging-handler.h"
|
||||
#include <stdio.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) {
|
||||
fclose(handler->stream);
|
||||
free(Handler_file_EX_PRT(handler)->file_name);
|
||||
free(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 文件日志处理器输出组件
|
||||
* @param handler 文件日志处理器
|
||||
* @param message 消息
|
||||
*/
|
||||
static void outputFileHandler(log_Handler *handler, const char *message) {
|
||||
fputs(message, handler->stream);
|
||||
static void changeFile(log_Handler *handler) {
|
||||
log_Handler_file_ex_t *handler_ex = Handler_file_EX_PRT(handler);
|
||||
fclose(handler->stream);
|
||||
char new_file_name[FILE_NAME_MAX_SIZE];
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 文件日志处理器
|
||||
* @param name 文件名
|
||||
* @return log_Handler *
|
||||
*/
|
||||
log_Handler *loggingFileHandler(const char *name) {
|
||||
char new_file_name[100];
|
||||
sprintf(new_file_name, "%s.log", name);
|
||||
static void outputFileHandler(log_Handler *handler, const char *message) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
FILE *fp = fopen(new_file_name, "at");
|
||||
log_Handler *loggingHandlerFile(const char *file_name, unsigned int max_size) {
|
||||
char new_file_name[FILE_NAME_MAX_SIZE];
|
||||
int suffix = 0;
|
||||
unsigned int file_size;
|
||||
FILE *fp = NULL;
|
||||
log_Handler *handler = NULL;
|
||||
log_Handler_file_ex_t *handler_ex = NULL;
|
||||
|
||||
log_Handler *handler = (log_Handler *)malloc(sizeof(log_Handler));
|
||||
/// 获取未写满于设置最大文件大小的文件名
|
||||
do {
|
||||
sprintf(new_file_name, "%s_%d.log", file_name, suffix++);
|
||||
fp = fopen(new_file_name, "at");
|
||||
if (fp == NULL) {
|
||||
goto ERROR;
|
||||
}
|
||||
file_size = getFileSize(fp);
|
||||
} while (file_size > max_size);
|
||||
|
||||
/// 分配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(file_name);
|
||||
if (handler_ex->file_name == NULL) {
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
handler->stream = fp;
|
||||
handler->apply_color = false;
|
||||
handler->_free = __freeFileHandler;
|
||||
handler->output = outputFileHandler;
|
||||
|
||||
return handler;
|
||||
|
||||
ERROR:
|
||||
if (fp) {
|
||||
fclose(fp);
|
||||
}
|
||||
if (handler) {
|
||||
free(Handler_file_EX_PRT(handler)->file_name); // 直接释放,无需检查NULL
|
||||
free(handler);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
/********************************************
|
||||
* @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;
|
||||
}
|
||||
370
src/logging.c
370
src/logging.c
@@ -1,248 +1,268 @@
|
||||
/********************************************
|
||||
* @Date: 2024 08 12
|
||||
* @Description: 日志模块
|
||||
********************************************/
|
||||
#include "logging.h"
|
||||
#include "logging/logging-core.h"
|
||||
#include "logging/logging-handler.h"
|
||||
#include "utils/logging-utils.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#define RED "\033[0;31m"
|
||||
#define RED_B "\033[0;41m"
|
||||
#define GREEN "\033[0;32m"
|
||||
#define YELLOW "\033[0;33m"
|
||||
#define BLUE "\033[0;34m"
|
||||
#define RESET "\033[0m"
|
||||
#define CYAN "\033[0;36m"
|
||||
#define MAGENTA "\033[0;35m"
|
||||
#define WHITE "\033[0;37m"
|
||||
#define BLACK "\033[0;30m"
|
||||
#define RED "\033[0;31m"
|
||||
#define RED_B "\033[0;41m"
|
||||
#define GREEN "\033[0;32m"
|
||||
#define YELLOW "\033[0;33m"
|
||||
#define BLUE "\033[0;34m"
|
||||
#define RESET "\033[0m"
|
||||
#define CYAN "\033[0;36m"
|
||||
|
||||
#define LOG_BUFFER_SIZE 1024
|
||||
#define LOG_BUFFER_SIZE 4096 // 日志缓冲区大小,单个日志长度不能超过该值
|
||||
|
||||
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);
|
||||
}
|
||||
static Logger *G_LOGGER = NULL; // 全局日志对象,唯一实例
|
||||
|
||||
/**
|
||||
* @description : 添加日志处理器
|
||||
* @brief 为日志添加一个handler
|
||||
* @param handler 处理器对象
|
||||
*/
|
||||
static void addHandler(log_Handler *handler) {
|
||||
if (G_LOGGER == NULL) {
|
||||
return;
|
||||
static bool addHandler(log_Handler *handler) {
|
||||
if (G_LOGGER == NULL || handler == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (G_LOGGER->handler == NULL) {
|
||||
G_LOGGER->handler = handler;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
G_LOGGER->handler->_free(G_LOGGER->handler);
|
||||
|
||||
G_LOGGER->handler = handler;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : 添加日志拦截器
|
||||
* @param
|
||||
* @return
|
||||
* @brief 为日志添加一个filter
|
||||
* @param filter 过滤器对象
|
||||
*/
|
||||
void addInterceptor(log_Interceptor *Interceptor) {
|
||||
if (G_LOGGER == NULL) {
|
||||
return;
|
||||
/**
|
||||
* @brief 为日志添加一个filter
|
||||
* @param filter 过滤器对象
|
||||
*/
|
||||
static bool addFilter(log_filter *filter) {
|
||||
if (G_LOGGER == NULL || filter == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (G_LOGGER->interceptor == NULL) {
|
||||
G_LOGGER->interceptor = Interceptor;
|
||||
return;
|
||||
if (G_LOGGER->filter == NULL) {
|
||||
G_LOGGER->filter = filter;
|
||||
G_LOGGER->filter->next = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
G_LOGGER->interceptor->_free(G_LOGGER->interceptor);
|
||||
log_filter *it = G_LOGGER->filter;
|
||||
while (it->next != NULL) {
|
||||
it = it->next;
|
||||
}
|
||||
|
||||
G_LOGGER->interceptor = Interceptor;
|
||||
it->next = filter;
|
||||
filter->next = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : 内置日志记录函数
|
||||
* @brief 输出到handler
|
||||
* @param handler 处理器对象
|
||||
* @param level 日志等级
|
||||
* @param color 应用的颜色
|
||||
* @param message 日志内容
|
||||
*/
|
||||
static void
|
||||
_builtin_log(char *level, const char *color, const char *message, ...) {
|
||||
if (G_LOGGER == NULL) {
|
||||
return;
|
||||
}
|
||||
if (G_LOGGER->handler == NULL) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* @brief 输出到handler
|
||||
* @param handler 处理器对象
|
||||
* @param level 日志等级
|
||||
* @param color 应用的颜色
|
||||
* @param message 日志内容
|
||||
*/
|
||||
static void output_to_handler(log_Handler *handler,
|
||||
char *level,
|
||||
const char *color,
|
||||
const char *message) {
|
||||
char timeStr[20];
|
||||
getTimeStr(timeStr);
|
||||
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;
|
||||
}
|
||||
}
|
||||
char logStr[LOG_BUFFER_SIZE * 2];
|
||||
if (handler->apply_color) {
|
||||
snprintf(logStr,
|
||||
LOG_BUFFER_SIZE * 2,
|
||||
"[%s]: %s %s%s%s %s\n",
|
||||
G_LOGGER->name,
|
||||
timeStr,
|
||||
color,
|
||||
level,
|
||||
RESET,
|
||||
message);
|
||||
} else {
|
||||
snprintf(logStr,
|
||||
LOG_BUFFER_SIZE * 2,
|
||||
"[%s]: %s %s %s\n",
|
||||
G_LOGGER->name,
|
||||
timeStr,
|
||||
level,
|
||||
message);
|
||||
}
|
||||
|
||||
// 判断处理器是否应用颜色
|
||||
if (handler->apply_color)
|
||||
sprintf(logStr,
|
||||
"%s: %s %s%s%s %s\n",
|
||||
G_LOGGER->name,
|
||||
timeStr,
|
||||
color,
|
||||
level,
|
||||
RESET,
|
||||
message);
|
||||
else
|
||||
sprintf(
|
||||
logStr, "%s: %s %s %s\n", G_LOGGER->name, timeStr, level, message);
|
||||
|
||||
handler->output(handler, logStr);
|
||||
}
|
||||
|
||||
//*************************记录日志******************************* */
|
||||
static void fatal(const char *message, ...) {
|
||||
if (G_LOGGER->level >= LOG_ERROR) {
|
||||
char logStr[LOG_BUFFER_SIZE];
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
vsprintf(logStr, message, args);
|
||||
va_end(args);
|
||||
_builtin_log("Fatal", RED_B, logStr, args);
|
||||
}
|
||||
}
|
||||
|
||||
static void error(const char *message, ...) {
|
||||
if (G_LOGGER->level >= LOG_ERROR) {
|
||||
char logStr[LOG_BUFFER_SIZE];
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
vsprintf(logStr, message, args);
|
||||
va_end(args);
|
||||
_builtin_log("Error", RED, logStr, args);
|
||||
}
|
||||
}
|
||||
|
||||
static void warning(const char *message, ...) {
|
||||
if (G_LOGGER->level >= LOG_WARNING) {
|
||||
char logStr[LOG_BUFFER_SIZE];
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
vsprintf(logStr, message, args);
|
||||
va_end(args);
|
||||
_builtin_log("Warning", YELLOW, logStr, args);
|
||||
}
|
||||
}
|
||||
|
||||
static void info(const char *message, ...) {
|
||||
if (G_LOGGER->level >= LOG_INFO) {
|
||||
char logStr[LOG_BUFFER_SIZE];
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
vsprintf(logStr, message, args);
|
||||
va_end(args);
|
||||
_builtin_log("Info", GREEN, logStr, args);
|
||||
}
|
||||
}
|
||||
|
||||
static void debug(const char *message, ...) {
|
||||
if (G_LOGGER->level >= LOG_DEBUG) {
|
||||
char logStr[LOG_BUFFER_SIZE];
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
vsprintf(logStr, message, args);
|
||||
va_end(args);
|
||||
_builtin_log("Debug", CYAN, logStr, args);
|
||||
}
|
||||
}
|
||||
//*************************记录日志******************************* */
|
||||
|
||||
/**
|
||||
* @description :获取一个日志操作对象
|
||||
* @param
|
||||
* @brief 内部日志打印处理核心函数
|
||||
* @param level 日志等级
|
||||
* @param color 应用的颜色
|
||||
* @param message 日志内容
|
||||
* @param ... 格式化参数列表
|
||||
* @return
|
||||
*/
|
||||
static Logger *getLogger(const char *name, log_level level) {
|
||||
static void log_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) {
|
||||
char logStr[LOG_BUFFER_SIZE];
|
||||
char finalLogStr[LOG_BUFFER_SIZE * 2];
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
vsprintf(logStr, message, args);
|
||||
va_end(args);
|
||||
snprintf(
|
||||
finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr);
|
||||
log_cope(LOG_FATAL, "Fatal", RED_B, finalLogStr);
|
||||
}
|
||||
}
|
||||
|
||||
void log_error(const char *file, int line, const char *message, ...) {
|
||||
if (G_LOGGER->level >= LOG_ERROR) {
|
||||
char logStr[LOG_BUFFER_SIZE];
|
||||
char finalLogStr[LOG_BUFFER_SIZE * 2];
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
vsprintf(logStr, message, args);
|
||||
va_end(args);
|
||||
snprintf(
|
||||
finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr);
|
||||
log_cope(LOG_ERROR, "Error", RED, finalLogStr);
|
||||
}
|
||||
}
|
||||
|
||||
void log_warning(const char *file, int line, const char *message, ...) {
|
||||
if (G_LOGGER->level >= LOG_WARNING) {
|
||||
char logStr[LOG_BUFFER_SIZE];
|
||||
char finalLogStr[LOG_BUFFER_SIZE * 2];
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
vsprintf(logStr, message, args);
|
||||
va_end(args);
|
||||
snprintf(
|
||||
finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr);
|
||||
log_cope(LOG_WARNING, "Warning", YELLOW, finalLogStr);
|
||||
}
|
||||
}
|
||||
|
||||
void log_info(const char *file, int line, const char *message, ...) {
|
||||
if (G_LOGGER->level >= LOG_INFO) {
|
||||
char logStr[LOG_BUFFER_SIZE];
|
||||
char finalLogStr[LOG_BUFFER_SIZE * 2];
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
vsprintf(logStr, message, args);
|
||||
va_end(args);
|
||||
snprintf(
|
||||
finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr);
|
||||
log_cope(LOG_INFO, "Info", GREEN, finalLogStr);
|
||||
}
|
||||
}
|
||||
|
||||
void log_debug(const char *file, int line, const char *message, ...) {
|
||||
if (G_LOGGER->level >= LOG_DEBUG) {
|
||||
char logStr[LOG_BUFFER_SIZE];
|
||||
char finalLogStr[LOG_BUFFER_SIZE * 2];
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
vsprintf(logStr, message, args);
|
||||
va_end(args);
|
||||
snprintf(
|
||||
finalLogStr, LOG_BUFFER_SIZE * 2, "[%s:%d] %s", file, line, logStr);
|
||||
log_cope(LOG_DEBUG, "Debug", CYAN, finalLogStr);
|
||||
}
|
||||
}
|
||||
|
||||
Logger *newDefaultLogger(const char *name, log_level level) {
|
||||
if (G_LOGGER != NULL) {
|
||||
G_LOGGER->name = name;
|
||||
G_LOGGER->level = level;
|
||||
return G_LOGGER;
|
||||
}
|
||||
|
||||
Logger *logger = (Logger *)malloc(sizeof(Logger));
|
||||
// 方法
|
||||
logger->fatal = fatal;
|
||||
logger->error = error;
|
||||
logger->warning = warning;
|
||||
logger->info = info;
|
||||
logger->debug = debug;
|
||||
Logger *logger = (Logger *)malloc(sizeof(Logger));
|
||||
|
||||
logger->addHandler = addHandler;
|
||||
logger->addInterceptor = addInterceptor;
|
||||
logger->addHandler = addHandler;
|
||||
logger->addFilter = addFilter;
|
||||
|
||||
// 属性
|
||||
logger->level = level;
|
||||
logger->handler = loggingConsoleHandler();
|
||||
logger->name = name;
|
||||
logger->interceptor = NULL;
|
||||
logger->level = level;
|
||||
logger->handler = loggingHandlerConsole();
|
||||
logger->name = name;
|
||||
logger->filter = NULL;
|
||||
|
||||
G_LOGGER = logger;
|
||||
G_LOGGER = logger;
|
||||
return G_LOGGER;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description :销毁日志对象
|
||||
* @brief 销毁日志对象
|
||||
*/
|
||||
log_status destroyLogging(Logging *logging) {
|
||||
if (logging == NULL) {
|
||||
return L_ERROR;
|
||||
}
|
||||
log_status destroyDefaultLogger(void) {
|
||||
if (G_LOGGER != NULL) {
|
||||
if (G_LOGGER->handler != NULL) {
|
||||
G_LOGGER->handler->_free(G_LOGGER->handler);
|
||||
}
|
||||
|
||||
if (G_LOGGER->interceptor != NULL) {
|
||||
G_LOGGER->interceptor->_free(G_LOGGER->interceptor);
|
||||
if (G_LOGGER->filter != NULL) {
|
||||
log_filter *it = G_LOGGER->filter;
|
||||
log_filter *next = NULL;
|
||||
while (it != NULL) {
|
||||
next = it->next;
|
||||
it->_free(it);
|
||||
it = next;
|
||||
}
|
||||
}
|
||||
|
||||
free(G_LOGGER);
|
||||
G_LOGGER = NULL;
|
||||
}
|
||||
free(logging);
|
||||
return L_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description :获取当前日志操作对象
|
||||
* @return 当前唯一的日志操作对象
|
||||
*/
|
||||
Logger *getCurrentLogger(void) {
|
||||
Logger *getDefaultLogger(void) {
|
||||
if (G_LOGGER == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
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;
|
||||
}
|
||||
15
src/utils/logging-utils.c
Normal file
15
src/utils/logging-utils.c
Normal file
@@ -0,0 +1,15 @@
|
||||
#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);
|
||||
}
|
||||
5
src/utils/logging-utils.h
Normal file
5
src/utils/logging-utils.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#ifndef __LOGGING_UTILS_H__
|
||||
#define __LOGGING_UTILS_H__
|
||||
|
||||
void getTimeStr(char *timeStr);
|
||||
#endif // __LOGGING_UTILS_H__
|
||||
@@ -1,8 +1,19 @@
|
||||
project(test)
|
||||
|
||||
add_executable(${PROJECT_NAME}simple test_simple.c)
|
||||
target_link_libraries(${PROJECT_NAME}simple Logging)
|
||||
enable_testing()
|
||||
|
||||
#测试简单基本应用
|
||||
add_executable(${PROJECT_NAME}simple test-simple.c)
|
||||
target_link_libraries(${PROJECT_NAME}simple logging)
|
||||
add_test(test_simple ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}simple${CMAKE_EXECUTEABLE_SUFFIX})
|
||||
|
||||
#测试简单基本应用
|
||||
add_executable(${PROJECT_NAME}file test-log-file.c)
|
||||
target_link_libraries(${PROJECT_NAME}file logging)
|
||||
add_test(test_file ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}file${CMAKE_EXECUTEABLE_SUFFIX})
|
||||
|
||||
|
||||
add_executable(${PROJECT_NAME}interceptor test_interceptor.c)
|
||||
target_link_libraries(${PROJECT_NAME}interceptor Logging)
|
||||
#测试拦截器
|
||||
add_executable(${PROJECT_NAME}filter test-filter.c)
|
||||
target_link_libraries(${PROJECT_NAME}filter logging)
|
||||
add_test(test_filter ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}filter${CMAKE_EXECUTEABLE_SUFFIX})
|
||||
|
||||
49
tests/test-filter.c
Normal file
49
tests/test-filter.c
Normal file
@@ -0,0 +1,49 @@
|
||||
#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(__FILE__, 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;
|
||||
}
|
||||
17
tests/test-log-file.c
Normal file
17
tests/test-log-file.c
Normal file
@@ -0,0 +1,17 @@
|
||||
#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;
|
||||
}
|
||||
14
tests/test-simple.c
Normal file
14
tests/test-simple.c
Normal file
@@ -0,0 +1,14 @@
|
||||
#include "logging.h"
|
||||
|
||||
int main() {
|
||||
Logger *logger = newDefaultLogger(__FILE__, 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;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
238
uv.lock
generated
Normal file
238
uv.lock
generated
Normal file
@@ -0,0 +1,238 @@
|
||||
version = 1
|
||||
revision = 2
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2025.6.15"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/73/f7/f14b46d4bcd21092d7d3ccef689615220d8a08fb25e564b65d20738e672e/certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b", size = 158753, upload-time = "2025-06-15T02:45:51.329Z" }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/84/ae/320161bd181fc06471eed047ecce67b693fd7515b16d495d8932db763426/certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", size = 157650, upload-time = "2025-06-15T02:45:49.977Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "charset-normalizer"
|
||||
version = "3.4.2"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e4/33/89c2ced2b67d1c2a61c19c6751aa8902d46ce3dacb23600a283619f5a12d/charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63", size = 126367, upload-time = "2025-05-02T08:34:42.01Z" }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/d7/a4/37f4d6035c89cac7930395a35cc0f1b872e652eaafb76a6075943754f095/charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7", size = 199936, upload-time = "2025-05-02T08:32:33.712Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/ee/8a/1a5e33b73e0d9287274f899d967907cd0bf9c343e651755d9307e0dbf2b3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3", size = 143790, upload-time = "2025-05-02T08:32:35.768Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/66/52/59521f1d8e6ab1482164fa21409c5ef44da3e9f653c13ba71becdd98dec3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a", size = 153924, upload-time = "2025-05-02T08:32:37.284Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/2d/fb55fdf41964ec782febbf33cb64be480a6b8f16ded2dbe8db27a405c09f/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214", size = 146626, upload-time = "2025-05-02T08:32:38.803Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/8c/73/6ede2ec59bce19b3edf4209d70004253ec5f4e319f9a2e3f2f15601ed5f7/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a", size = 148567, upload-time = "2025-05-02T08:32:40.251Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/09/14/957d03c6dc343c04904530b6bef4e5efae5ec7d7990a7cbb868e4595ee30/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd", size = 150957, upload-time = "2025-05-02T08:32:41.705Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/0d/c8/8174d0e5c10ccebdcb1b53cc959591c4c722a3ad92461a273e86b9f5a302/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981", size = 145408, upload-time = "2025-05-02T08:32:43.709Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/58/aa/8904b84bc8084ac19dc52feb4f5952c6df03ffb460a887b42615ee1382e8/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c", size = 153399, upload-time = "2025-05-02T08:32:46.197Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/c2/26/89ee1f0e264d201cb65cf054aca6038c03b1a0c6b4ae998070392a3ce605/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b", size = 156815, upload-time = "2025-05-02T08:32:48.105Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/07/68e95b4b345bad3dbbd3a8681737b4338ff2c9df29856a6d6d23ac4c73cb/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d", size = 154537, upload-time = "2025-05-02T08:32:49.719Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/77/1a/5eefc0ce04affb98af07bc05f3bac9094513c0e23b0562d64af46a06aae4/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f", size = 149565, upload-time = "2025-05-02T08:32:51.404Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/37/a0/2410e5e6032a174c95e0806b1a6585eb21e12f445ebe239fac441995226a/charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c", size = 98357, upload-time = "2025-05-02T08:32:53.079Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/6c/4f/c02d5c493967af3eda9c771ad4d2bbc8df6f99ddbeb37ceea6e8716a32bc/charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e", size = 105776, upload-time = "2025-05-02T08:32:54.573Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/ea/12/a93df3366ed32db1d907d7593a94f1fe6293903e3e92967bebd6950ed12c/charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0", size = 199622, upload-time = "2025-05-02T08:32:56.363Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/04/93/bf204e6f344c39d9937d3c13c8cd5bbfc266472e51fc8c07cb7f64fcd2de/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf", size = 143435, upload-time = "2025-05-02T08:32:58.551Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/22/2a/ea8a2095b0bafa6c5b5a55ffdc2f924455233ee7b91c69b7edfcc9e02284/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e", size = 153653, upload-time = "2025-05-02T08:33:00.342Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/b6/57/1b090ff183d13cef485dfbe272e2fe57622a76694061353c59da52c9a659/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1", size = 146231, upload-time = "2025-05-02T08:33:02.081Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/e2/28/ffc026b26f441fc67bd21ab7f03b313ab3fe46714a14b516f931abe1a2d8/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c", size = 148243, upload-time = "2025-05-02T08:33:04.063Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/c0/0f/9abe9bd191629c33e69e47c6ef45ef99773320e9ad8e9cb08b8ab4a8d4cb/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691", size = 150442, upload-time = "2025-05-02T08:33:06.418Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/67/7c/a123bbcedca91d5916c056407f89a7f5e8fdfce12ba825d7d6b9954a1a3c/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0", size = 145147, upload-time = "2025-05-02T08:33:08.183Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/ec/fe/1ac556fa4899d967b83e9893788e86b6af4d83e4726511eaaad035e36595/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b", size = 153057, upload-time = "2025-05-02T08:33:09.986Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/2b/ff/acfc0b0a70b19e3e54febdd5301a98b72fa07635e56f24f60502e954c461/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff", size = 156454, upload-time = "2025-05-02T08:33:11.814Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/92/08/95b458ce9c740d0645feb0e96cea1f5ec946ea9c580a94adfe0b617f3573/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b", size = 154174, upload-time = "2025-05-02T08:33:13.707Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/78/be/8392efc43487ac051eee6c36d5fbd63032d78f7728cb37aebcc98191f1ff/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148", size = 149166, upload-time = "2025-05-02T08:33:15.458Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/44/96/392abd49b094d30b91d9fbda6a69519e95802250b777841cf3bda8fe136c/charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7", size = 98064, upload-time = "2025-05-02T08:33:17.06Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/e9/b0/0200da600134e001d91851ddc797809e2fe0ea72de90e09bec5a2fbdaccb/charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980", size = 105641, upload-time = "2025-05-02T08:33:18.753Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626, upload-time = "2025-05-02T08:34:40.053Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "conan"
|
||||
version = "2.18.1"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama" },
|
||||
{ name = "distro", marker = "platform_system == 'FreeBSD' or sys_platform == 'linux'" },
|
||||
{ name = "fasteners" },
|
||||
{ name = "jinja2" },
|
||||
{ name = "patch-ng" },
|
||||
{ name = "python-dateutil" },
|
||||
{ name = "pyyaml" },
|
||||
{ name = "requests" },
|
||||
{ name = "urllib3" },
|
||||
]
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c7/55/9a10f21dd6dc9137c6e7b51eff7c54ab92400812e6e795d1a991ead00b54/conan-2.18.1.tar.gz", hash = "sha256:5d8e9fac7614de9297933f65de8f17db14851a871cebc962f4856b7c294f43c5", size = 521034, upload-time = "2025-07-04T07:08:07.842Z" }
|
||||
|
||||
[[package]]
|
||||
name = "distro"
|
||||
version = "1.8.0"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4b/89/eaa3a3587ebf8bed93e45aa79be8c2af77d50790d15b53f6dfc85b57f398/distro-1.8.0.tar.gz", hash = "sha256:02e111d1dc6a50abb8eed6bf31c3e48ed8b0830d1ea2a1b78c61765c2513fdd8", size = 59428, upload-time = "2022-10-10T15:30:33.395Z" }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/f4/2c/c90a3adaf0ddb70afe193f5ebfb539612af57cffe677c3126be533df3098/distro-1.8.0-py3-none-any.whl", hash = "sha256:99522ca3e365cac527b44bde033f64c6945d90eb9f769703caaec52b09bbd3ff", size = 20315, upload-time = "2022-10-10T15:30:26.903Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fasteners"
|
||||
version = "0.19"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5f/d4/e834d929be54bfadb1f3e3b931c38e956aaa3b235a46a3c764c26c774902/fasteners-0.19.tar.gz", hash = "sha256:b4f37c3ac52d8a445af3a66bce57b33b5e90b97c696b7b984f530cf8f0ded09c" }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/bf/fd60001b3abc5222d8eaa4a204cd8c0ae78e75adc688f33ce4bf25b7fafa/fasteners-0.19-py3-none-any.whl", hash = "sha256:758819cb5d94cdedf4e836988b74de396ceacb8e2794d21f82d131fd9ee77237" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.10"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jinja2"
|
||||
version = "3.1.6"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
dependencies = [
|
||||
{ name = "markupsafe" },
|
||||
]
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logging"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "conan" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "conan", specifier = ">=2.18.1" }]
|
||||
|
||||
[[package]]
|
||||
name = "markupsafe"
|
||||
version = "3.0.2"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "patch-ng"
|
||||
version = "1.18.1"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ee/c0/53a2f017ac5b5397a7064c2654b73c3334ac8461315707cbede6c12199eb/patch-ng-1.18.1.tar.gz", hash = "sha256:52fd46ee46f6c8667692682c1fd7134edc65a2d2d084ebec1d295a6087fc0291", size = 17913, upload-time = "2024-10-25T12:20:10.591Z" }
|
||||
|
||||
[[package]]
|
||||
name = "python-dateutil"
|
||||
version = "2.9.0.post0"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
dependencies = [
|
||||
{ name = "six" },
|
||||
]
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
version = "6.0.2"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.32.4"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
dependencies = [
|
||||
{ name = "certifi" },
|
||||
{ name = "charset-normalizer" },
|
||||
{ name = "idna" },
|
||||
{ name = "urllib3" },
|
||||
]
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258, upload-time = "2025-06-09T16:43:07.34Z" }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.17.0"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.0.7"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/af/47/b215df9f71b4fdba1025fc05a77db2ad243fa0926755a52c5e71659f4e3c/urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84", size = 282546, upload-time = "2023-10-17T17:46:50.542Z" }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/d2/b2/b157855192a68541a91ba7b2bbcb91f1b4faa51f8bae38d8005c034be524/urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e", size = 124213, upload-time = "2023-10-17T17:46:48.538Z" },
|
||||
]
|
||||
Reference in New Issue
Block a user