Readme
🎯 基于 Tokio 构建的高性能、安全、功能丰富的日志基础设施
Inklog 为企业级应用提供全面 的日志解决方案:
⚡ 高性能
🔒 安全优先
🌐 多目标输出
📊 可观测性
Tokio 异步 I/O
AES-256-GCM 加密
控制台、文件、数据库
健康监控
批量写入与压缩
密钥内存安全清除
自动轮转
指标与追踪
use inklog:: { InklogConfig, LoggerManager} ;
use std:: path:: PathBuf;
# [ tokio ::main ]
async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error> > {
let config = InklogConfig {
file_sink: Some ( inklog:: FileSinkConfig {
enabled: true ,
path: " logs/app.log" . into ( ) ,
max_size: " 100MB" . into ( ) ,
compress: true ,
.. Default :: default( )
} ) ,
.. Default :: default( )
} ;
let _logger = LoggerManager:: with_config( config) . await? ;
log:: info! ( " 应用启动成功" ) ;
log:: error! ( " 发生错误,详情如下" ) ;
Ok ( ( ) )
}
📋 目录
📑 目录 (点击展开)
✨ 核心特性
🎯 核心功能 (始终可用)
状态
功能
描述
✅
异步 I/O
基于 Tokio 的非阻塞日志记录
✅
多目标输出
控制台、文件、数据库、自定义 Sink
✅
结构化日志
tracing 生态系统集成
✅
自定义格式
基于模板的日志格式
✅
文件轮转
基于大小和时间的轮转
✅
数据脱敏
基于正则的 PII 数据脱敏
✅
健康监控
Sink 状态和指标追踪
✅
命令行工具
decrypt、generate、validate 命令(需 cli feature)
⚡ 企业功能
状态
功能
描述
🔍
压缩
ZSTD、GZIP 支持
🔒
加密
AES-256-GCM 文件加密
🗄️
数据库 Sink
PostgreSQL、MySQL、SQLite、DuckDB (dbnexus)
📊
Parquet 导出
分析就绪的日志格式
🌐
HTTP 端点
Axum 健康检查服务器
🔧
命令行工具
日志管理实用命令
📦 功能预设
预设
功能
适用场景
minimal
无可选特性
仅核心日志功能
standard
http , cli
标准开发环境
full
所有默认功能
生产环境日志
🚀 快速开始
📦 安装
在 Cargo.toml 中添加依赖:
[ dependencies ]
inklog = " 0.2"
完整功能集(显式启用):
[ dependencies ]
inklog = { version = "0.2", default-features = false, features = [ " http" , " cli" , " sqlite" ] }
💡 基础使用
第一步:初始化日志系统
use inklog:: LoggerManager;
# [ tokio ::main ]
async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error> > {
let _logger = LoggerManager:: new( ) . await? ;
log:: info! ( " 日志系统已初始化" ) ;
Ok ( ( ) )
}
第二步:记录日志消息
use inklog:: LoggerManager;
# [ tokio ::main ]
async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error> > {
let _logger = LoggerManager:: new( ) . await? ;
log:: trace! ( " 追踪消息" ) ;
log:: debug! ( " 调试消息" ) ;
log:: info! ( " 信息消息" ) ;
log:: warn! ( " 警告消息" ) ;
log:: error! ( " 错误消息" ) ;
Ok ( ( ) )
}
第三步:文件日志
use inklog:: { FileSinkConfig, InklogConfig, LoggerManager} ;
let config = InklogConfig {
file_sink: Some ( FileSinkConfig {
enabled: true ,
path: " logs/app.log" . into ( ) ,
max_size: " 10MB" . into ( ) ,
rotation_time: " daily" . into ( ) ,
keep_files: 7 ,
compress: true ,
.. Default :: default( )
} ) ,
.. Default :: default( )
} ;
let _logger = LoggerManager:: with_config( config) . await? ;
第四步:数据库日志
use inklog:: { DatabaseSinkConfig, InklogConfig} ;
let config = InklogConfig {
database_sink: Some ( DatabaseSinkConfig {
enabled: true ,
url: " sqlite://logs/app.db" . to_string ( ) ,
pool_size: 5 ,
batch_size: 100 ,
flush_interval_ms: 1000 ,
.. Default :: default( )
} ) ,
.. Default :: default( )
} ;
let _logger = LoggerManager:: with_config( config) . await? ;
🔧 高级配置
加密文件日志
use inklog:: { FileSinkConfig, InklogConfig} ;
// 从环境变量设置加密密钥
std:: env:: set_var( " INKLOG_ENCRYPTION_KEY" , " base64-encoded-32-byte-key" ) ;
let config = InklogConfig {
file_sink: Some ( FileSinkConfig {
enabled: true ,
path: " logs/encrypted.log.enc" . into ( ) ,
max_size: " 10MB" . into ( ) ,
encrypt: true ,
encryption_key_env: Some ( " INKLOG_ENCRYPTION_KEY" . into ( ) ) ,
compress: false , // 加密日志不压缩
.. Default :: default( )
} ) ,
.. Default :: default( )
} ;
let _logger = LoggerManager:: with_config( config) . await? ;
自定义日志格式
use inklog:: { InklogConfig, config:: GlobalConfig} ;
let format_string = " [{timestamp}] [{level:>5}] {target} - {message} | {file}:{line}" ;
let config = InklogConfig {
global: GlobalConfig {
level: " debug" . into ( ) ,
format: format_string. to_string ( ) ,
masking_enabled: true ,
.. Default :: default( )
} ,
.. Default :: default( )
} ;
let _logger = LoggerManager:: with_config( config) . await? ;
🎨 功能标志
默认功能
inklog = "0.2" # 默认不包含可选 feature (default = [])
可选功能
# HTTP 服务器
inklog = { version = "0.2", features = [
"http", # Axum HTTP 健康端点
] }
# 命令行工具
inklog = { version = "0.2", features = [
"cli", # decrypt, generate, validate 命令
] }
# 数据库 Sink (可选一个或多个)
inklog = { version = "0.2", features = [
"sqlite", # SQLite 数据库 Sink
"postgres", # PostgreSQL 数据库 Sink
"mysql", # MySQL 数据库 Sink
] }
# 压缩与性能
inklog = { version = "0.2", features = [
"compression", # ZSTD 压缩支持
"parquet", # Parquet 导出支持
"fast-masking", # Aho-Corasick 多模式加速脱敏
] }
功能详情
功能
依赖
描述
http
axum
HTTP 健康检查端点
cli
clap, glob, toml
命令行工具
sqlite
dbnexus, sea-orm
SQLite 数据库 Sink
postgres
dbnexus, sea-orm
PostgreSQL 数据库 Sink
mysql
dbnexus, sea-orm
MySQL 数据库 Sink
duckdb
dbnexus
DuckDB 数据库 Sink
compression
zstd
ZSTD 压缩支持(轮转日志文件)
parquet
parquet, arrow-array, arrow-schema
Parquet 导出支持(分析场景)
fast-masking
aho-corasick
Aho-Corasick 多模式加速脱敏
kit
trait-kit, dbnexus, oxcache
trait-kit AsyncKit 集成 (InklogModule)
📚 文档
📖 附加资源
资源
描述
📘 API 参考
docs.rs 上的完整 API 文档
🏗️ 架构文档
系统架构和设计决策
🔒 安全文档
安全最佳实践和特性
📦 示例
所有功能的可运行示例
💻 示例
📝 基础日志
use inklog:: LoggerManager;
# [ tokio ::main ]
async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error> > {
let _logger = LoggerManager:: new( ) . await? ;
log:: info! ( " 应用已启动" ) ;
log:: error! ( " 发生错误: {}" , err) ;
Ok ( ( ) )
}
📁 带轮转的文件日志
use inklog:: { FileSinkConfig, InklogConfig, LoggerManager} ;
let config = InklogConfig {
file_sink: Some ( FileSinkConfig {
enabled: true ,
path: " logs/app.log" . into ( ) ,
max_size: " 10MB" . into ( ) ,
rotation_time: " daily" . into ( ) ,
keep_files: 7 ,
compress: true ,
.. Default :: default( )
} ) ,
.. Default :: default( )
} ;
let _logger = LoggerManager:: with_config( config) . await? ;
🔒 加密日志
use inklog:: { FileSinkConfig, InklogConfig} ;
std:: env:: set_var( " INKLOG_ENCRYPTION_KEY" , " base64-encoded-key" ) ;
let config = InklogConfig {
file_sink: Some ( FileSinkConfig {
enabled: true ,
path: " logs/encrypted.log" . into ( ) ,
encrypt: true ,
encryption_key_env: Some ( " INKLOG_ENCRYPTION_KEY" . into ( ) ) ,
.. Default :: default( )
} ) ,
.. Default :: default( )
} ;
let _logger = LoggerManager:: with_config( config) . await? ;
🗄️ 数据库日志
use inklog:: { DatabaseSinkConfig, InklogConfig} ;
let config = InklogConfig {
database_sink: Some ( DatabaseSinkConfig {
enabled: true ,
url: " postgresql://localhost/logs" . to_string ( ) ,
pool_size: 10 ,
batch_size: 100 ,
flush_interval_ms: 1000 ,
.. Default :: default( )
} ) ,
.. Default :: default( )
} ;
let _logger = LoggerManager:: with_config( config) . await? ;
🏥 HTTP 健康端点
use axum:: { routing:: get, Json, Router} ;
use inklog:: LoggerManager;
use std:: sync:: Arc;
let logger = Arc:: new( LoggerManager:: new( ) . await? ) ;
let app = Router:: new( ) . route (
" /health" ,
get ( {
let logger = logger. clone ( ) ;
| | async move { Json( logger. get_health_status ( ) ) }
} ) ,
) ;
// 启动 HTTP 服务器...
🎨 自定义格式
use inklog:: { InklogConfig, config:: GlobalConfig} ;
let format_string = " [{timestamp}] [{level:>5}] {target} - {message}" ;
let config = InklogConfig {
global: GlobalConfig {
level: " debug" . into ( ) ,
format: format_string. to_string ( ) ,
masking_enabled: true ,
.. Default :: default( )
} ,
.. Default :: default( )
} ;
let _logger = LoggerManager:: with_config( config) . await? ;
🔍 数据脱敏
use inklog:: { InklogConfig, config:: GlobalConfig} ;
let config = InklogConfig {
global: GlobalConfig {
level: " info" . into ( ) ,
format: " {timestamp} {level} {message}" . to_string ( ) ,
masking_enabled: true , // 启用 PII 脱敏
.. Default :: default( )
} ,
.. Default :: default( )
} ;
let _logger = LoggerManager:: with_config( config) . await? ;
// 敏感数据将自动脱敏
log:: info! ( " 用户邮箱: user@example.com" ) ;
// 输出: 用户邮箱: ***@***.***
📦 可运行示例
examples/ crate 提供了 10 个专用示例,演示特定功能。使用 cargo run -- example < 名称> 运行(在 examples/ 目录下或使用 --package inklog-examples )。
示例
描述
运行命令
object_pool
对象池复用,优化高频分配路径
cargo run -- example object_pool
path_validator
路径校验,确保文件 Sink 目标安全
cargo run -- example path_validator
log_sanitizer
日志输入净化,防止日志注入攻击
cargo run -- example log_sanitizer
log_adapter
log 与 tracing 生态桥接适配器
cargo run -- example log_adapter
compression
文件 Sink 压缩(ZSTD/GZIP)
cargo run -- example compression
rotation
基于大小和时间的文件轮转
cargo run -- example rotation
ring_buffered_file
环形缓冲文件 Sink,适用于高吞吐场景
cargo run -- example ring_buffered_file
config_file
TOML 配置文件加载
cargo run -- example config_file
metrics
健康指标与 Prometheus 导出
cargo run -- example metrics
circuit_breaker
Sink 断路器与故障恢复
cargo run -- example circuit_breaker
🏗️ 架构
flowchart TD
App[ " 应用层<br/>(使用 log! 宏的代码)" ]
API [ " Inklog API 层<br/>- LoggerManager, LoggerBuilder<br/>- 配置管理<br/>- 健康监控" ]
Sink[ " Sink 抽象层<br/>- ConsoleSink<br/>- FileSink (轮转、压缩)<br/>- DatabaseSink (批量写入)<br/>- AsyncFileSink<br/>- RingBufferedFileSink" ]
Core[ " 核心处理层<br/>- 日志格式化和模板<br/>- 数据脱敏 (PII)<br/>- 加密 (AES-256-GCM)<br/>- 压缩 (ZSTD, GZIP)" ]
IO [ " 并发与 I/O<br/>- Tokio 异步运行时<br/>- Crossbeam 通道<br/>- Rayon 并行处理" ]
Store[ " 存储与外部服务<br/>- 文件系统<br/>- 数据库 (PostgreSQL, MySQL, SQLite, DuckDB)<br/>- Parquet (分析)" ]
App - -> API - -> Sink - -> Core - -> IO - -> Store
分层说明
应用层
应用代码使用 log crate 的标准 log! 宏
与现有 Rust 日志模式兼容
Inklog API 层
LoggerManager : 所有日志操作的主要协调器
LoggerBuilder : 流式构建器模式配置
健康状态跟踪和指标收集
Sink 抽象层
多种 Sink 实现对应不同的输出目标
开发环境的控制台输出
带轮转、压缩和加密的文件输出
批量写入的数据库输出 (PostgreSQL, MySQL, SQLite, DuckDB)
高吞吐量场景的异步和缓冲文件 Sink
核心处理层
基于模板的日志格式化
基于正则的 PII 数据脱敏 (邮箱、身份证、信用卡等)
敏感日志的 AES-256-GCM 加密
多种压缩算法 (ZSTD, GZIP)
并发与 I/O 层
Tokio 异步运行时用于非阻塞 I/O
Crossbeam 通道用于任务间通信
Rayon 用于 CPU 密集型并行处理
存储与外部服务层
本地文件系统访问
通过 Sea-ORM 的数据库连接
分析工作流的 Parquet 格式
🔒 安全
Inklog 以安全为首要优先级构建:
🔒 加密
AES-256-GCM : 军用级日志文件加密
密钥管理 : 基于环境变量的密钥注入
内存安全清除 : 通过 zeroize crate 安全清除密钥
SHA-256 哈希 : 加密日志的完整性验证
🎭 数据脱敏
基于正则的模式 : 自动 PII 检测和脱敏
邮箱脱敏 : user@ example. com → * * * @ * * * . * * *
身份证脱敏 : 信用卡和社会安全号脱敏
自定义模式 : 可配置的正则表达式模式
🔐 密钥安全处理
// 从环境变量安全设置加密密钥
std:: env:: set_var( " INKLOG_ENCRYPTION_KEY" , " base64-encoded-32-byte-key" ) ;
// 密钥使用后自动清除
// 切勿在代码中硬编码密钥
🛡️ 安全最佳实践
无硬编码密钥 : 密钥从环境变量加载
最小权限操作 : 仅必要的文件/数据库访问
审计日志 : 调试功能用于安全审计追踪
合规就绪 : 支持 GDPR、HIPAA、PCI-DSS 日志要求
🧪 测试
# 使用默认功能运行所有测试
cargo test --all-features
# 使用特定功能运行测试
cargo test --features "http,cli"
# 在发布模式下运行测试
cargo test --release
# 运行基准测试
cargo bench
测试覆盖率
Inklog 目标是 95%+ 代码覆盖率 :
# 生成覆盖率报告
cargo tarpaulin --out Html --all-features
代码检查和格式化
# 格式化代码
cargo fmt --all
# 检查格式而不修改
cargo fmt --all -- --check
# 运行 Clippy (警告视为错误)
cargo clippy --all-targets --all-features -- -D warnings
安全审计
# 运行 cargo deny 安全检查
cargo deny check
# 检查安全公告
cargo deny check advisories
# 检查禁止的许可证
cargo deny check bans
依赖注入测试
Inklog 提供 Mock 实现,支持无外部依赖的单元测试:
use inklog:: { LoggerManager, LoggerDependencies} ;
use inklog:: { MockCache, MockConfig, MockDatabaseAdapter} ;
use std:: sync:: Arc;
# [ tokio ::test ]
async fn test_with_mocks ( ) -> Result < ( ) , Box < dyn std:: error:: Error> > {
// 创建 Mock 依赖
let deps = LoggerDependencies {
cache: Some ( Arc:: new( MockCache:: new( ) ) ) ,
config: Some ( Arc:: new( MockConfig:: new( ) ) ) ,
# [ cfg ( any ( feature = " sqlite" , feature = " postgres" , feature = " mysql" ) ) ]
database: Some ( Arc:: new( MockDatabaseAdapter:: new( ) ) ) ,
.. Default :: default( )
} ;
// 注入依赖创建 logger
let logger = LoggerManager:: with_dependencies( deps) . await? ;
// 测试日志记录...
log:: info! ( " Test message" ) ;
Ok ( ( ) )
}
Mock 实现特性 :
MockCache : 内存 HashMap,支持延迟模拟
MockConfig : 运行时可修改的配置
MockDatabaseAdapter : 内存日志存储,支持健康状态控制
详细使用方法请参考 用户指南 。
集成测试
# 运行集成测试
cargo test --test '*'
# 使用 Docker 服务运行 (PostgreSQL, MySQL)
docker-compose up -d
cargo test --all-features
docker-compose down
🤝 贡献
开发环境设置
# 克隆仓库
git clone https://github.com/Kirky-X/inklog.git
cd inklog
# 安装 pre-commit 钩子 (如果可用)
./scripts/install-pre-commit.sh
# 运行测试
cargo test --all-features
# 运行 linter
cargo clippy --all-features
# 格式化代码
cargo fmt --all
Pull Request 流程
Fork 仓库
创建功能分支 (git checkout - b feature/amazing-feature )
进行修改
运行测试确保全部通过 (cargo test -- all-features )
运行 clippy 并修复警告 (cargo clippy -- all-features )
提交修改 (git commit - m ' Add amazing feature' )
推送到分支 (git push origin feature/amazing-feature )
打开 Pull Request
代码风格
遵循 Rust 命名约定 (变量 snake_case,类型 PascalCase)
使用 thiserror 定义错误类型
使用 anyhow 提供错误上下文
为所有公共 API 添加文档注释
提交前运行 cargo fmt
📄 许可证
本项目采用 MIT 许可证:
🙏 致谢
Inklog 的实现离不开这些优秀的项目:
📞 支持
⭐ Star 历史
💝 支持本项目
如果您发现本项目有用,请考虑给一个 ⭐️!
由 ❤️ Inklog 团队构建
⬆ 返回顶部
© 2026 Inklog Project. 版权所有。