
CodeSpirit.Audit组件现在支持使用GreptimeDB作为审计日志的存储后端,提供更好的时序数据处理性能和资源利用率。
目的:



在appsettings.json中配置GreptimeDB:
{
"Audit": {
"Enabled": true,
"StorageProvider": "GreptimeDB",
"LogRequestParams": true,
"LogResponseData": false,
"GreptimeDB": {
"Url": "http://localhost:4000",
"Database": "audit_logs",
"TableName": "audit_logs",
"Username": "",
"Password": "",
"TimeoutSeconds": 30,
"BatchSize": 1000,
"TablePrefix": "codespirit"
},
"RabbitMQ": {
"ExchangeName": "audit.exchange",
"QueueName": "audit.queue",
"RoutingKey": "audit.log"
}
}
}目前CodeSpirit在CodeSpirit.AppHost中已配置GreptimeDB容器及环境变量,如果在本地运行,无需再额外配置。
{
"Audit": {
"StorageProvider": "GreptimeDB",
"GreptimeDB": {
"Url": "http://localhost:4000",
"Database": "audit_logs_dev",
"TablePrefix": "dev"
}
}
}
{
"Audit": {
"StorageProvider": "GreptimeDB",
"GreptimeDB": {
"Url": "https://greptimedb.production.com:4000",
"Database": "audit_logs",
"Username": "audit_user",
"Password": "your_secure_password",
"TablePrefix": "prod",
"TimeoutSeconds": 60,
"BatchSize": 5000
}
}
}
在Program.cs中注册审计服务(无需修改):
// 添加审计服务(会自动根据配置选择存储提供者)
builder.Services.AddAuditServices(builder.Configuration);
var app = builder.Build();
// 使用审计中间件
app.UseRouting();
app.UseAudit();
app.UseAuthorization();
控制器使用方式保持不变:
[Audit]
public class UsersController : ControllerBase
{
[Audit("创建用户", AuditOperationType.Create)]
[HttpPost]
public async Task<IActionResult> CreateUser(CreateUserDto dto)
{
// 业务逻辑
}
}
查询API保持不变:
public class AuditLogController : ControllerBase
{
private readonly IAuditService _auditService;
[HttpGet]
public async Task<IActionResult> GetLogs([FromQuery] AuditLogQueryDto query)
{
var result = await _auditService.SearchAsync(query);
return Ok(result);
}
[HttpGet("stats/operations")]
public async Task<IActionResult> GetOperationStats(
[FromQuery] DateTime startTime,
[FromQuery] DateTime endTime)
{
var stats = await _auditService.GetOperationStatsAsync(startTime, endTime);
return Ok(stats);
}
}
# 使用Docker运行GreptimeDB
docker run -d \
--name greptimedb \
-p 4000:4000 \
-p 4001:4001 \
-p 4002:4002 \
-p 4003:4003 \
-v greptimedb-data:/tmp/greptimedb \
greptime/greptimedb:latest standalone start
-- 连接到GreptimeDB并验证
curl -X POST "http://localhost:4000/v1/sql" \
-H "Content-Type: application/json" \
-d '{"sql": "SELECT 1 as health"}'
GreptimeDB中的审计日志表结构:
CREATE TABLE IF NOT EXISTS codespirit_audit_logs (
id STRING,
user_id STRING,
user_name STRING,
ip_address STRING,
operation_time TIMESTAMP TIME INDEX,
service_name STRING,
controller_name STRING,
action_name STRING,
operation_type STRING,
description STRING,
request_path STRING,
request_method STRING,
request_params TEXT,
entity_name STRING,
entity_id STRING,
execution_duration BIGINT,
is_success BOOLEAN,
error_message TEXT,
status_code INT,
before_data TEXT,
after_data TEXT,
user_agent TEXT,
operation_name STRING,
tenant_id STRING,
PRIMARY KEY (id)
)
-- 查询最近的审计日志
SELECT * FROM codespirit_audit_logs
ORDER BY operation_time DESC
LIMIT 10;
-- 按用户查询
SELECT * FROM codespirit_audit_logs
WHERE user_name = 'admin'
AND operation_time >= '2024-01-01 00:00:00'
ORDER BY operation_time DESC;
-- 操作类型统计
SELECT operation_type, COUNT(*) as count
FROM codespirit_audit_logs
WHERE operation_time >= '2024-01-01 00:00:00'
GROUP BY operation_type
ORDER BY count DESC;
-- 用户活跃度统计
SELECT user_name, COUNT(*) as count
FROM codespirit_audit_logs
WHERE operation_time >= '2024-01-01 00:00:00'
AND user_name IS NOT NULL
GROUP BY user_name
ORDER BY count DESC
LIMIT 10;
-- 按小时统计操作趋势
SELECT
date_trunc('hour', operation_time) as hour,
COUNT(*) as operations
FROM codespirit_audit_logs
WHERE operation_time >= '2024-01-01 00:00:00'
GROUP BY hour
ORDER BY hour;
-- 按天统计操作趋势
SELECT
date_trunc('day', operation_time) as day,
COUNT(*) as operations
FROM codespirit_audit_logs
WHERE operation_time >= '2024-01-01 00:00:00'
GROUP BY day
ORDER BY day;
GreptimeDB支持高效的批量写入,配置较大的批次大小可以提高写入性能:
{
"GreptimeDB": {
"BatchSize": 5000
}
}
GreptimeDB自动为时间字段创建索引,对于频繁查询的字段可以考虑创建额外索引:
-- 为用户ID创建索引(如果需要)
ALTER TABLE codespirit_audit_logs ADD INDEX idx_user_id (user_id);
StorageProvider改为"GreptimeDB"如需回滚,只需将配置改回:
{
"Audit": {
"StorageProvider": "Elasticsearch"
}
}
// 检查GreptimeDB连接健康状态
public async Task<bool> CheckHealthAsync()
{
var healthSql = "SELECT 1 as health";
// 执行查询检查连接状态
}
定期监控GreptimeDB的:
错误信息: fail: CodeSpirit.Audit.Services.Implementation.GreptimeDbAuditStorageService[0] GreptimeDB SQL执行失败: ServiceUnavailable
可能原因及解决方案:
GreptimeDB服务未启动
# 检查容器状态
docker ps | grep greptimedb
# 如果没有运行,启动服务
cd Src/CodeSpirit.AppHost
dotnet run
端口映射问题
配置错误
// 检查 appsettings.json 中的配置
{
"Audit": {
"GreptimeDB": {
"Url": "http://greptimedb:4000", // 容器内部使用服务名
"Database": "audit_logs"
}
}
}
错误信息: fail: CodeSpirit.Audit.Services.Implementation.GreptimeDbAuditStorageService[0] GreptimeDB表创建失败: web_audit_logs
解决步骤:
检查数据库是否存在
# 使用 HTTP API 检查
curl -X POST "http://localhost:4000/v1/sql" \
-H "Content-Type: application/json" \
-d '{"sql": "SHOW DATABASES"}'
手动创建数据库
curl -X POST "http://localhost:4000/v1/sql" \
-H "Content-Type: application/json" \
-d '{"sql": "CREATE DATABASE IF NOT EXISTS audit_logs"}'
检查表结构
curl -X POST "http://localhost:4000/v1/sql?db=audit_logs" \
-H "Content-Type: application/json" \
-d '{"sql": "SHOW TABLES"}'
解决方案:
{
"Audit": {
"GreptimeDB": {
"TimeoutSeconds": 60
}
}
}
我们提供了专门的诊断工具来检查GreptimeDB连接状态:
// 在代码中使用
var diagnosticTool = new GreptimeDbDiagnosticTool(logger, configuration);
var result = await diagnosticTool.RunFullDiagnosticAsync();
if (!result.AllTestsPassed)
{
// 查看具体失败的测试
logger.LogError("连接测试: {Success}", result.ConnectionTest.Success);
logger.LogError("SQL测试: {Success}", result.SqlQueryTest.Success);
}
验证服务状态
# 检查 GreptimeDB 容器
docker logs <greptimedb_container_id>
# 检查端口监听
netstat -an | grep 4000
测试基础连接
# 健康检查
curl http://localhost:4000/health
# 基础查询
curl -X POST "http://localhost:4000/v1/sql" \
-H "Content-Type: application/json" \
-d '{"sql": "SELECT 1"}'
检查日志
批量写入
{
"GreptimeDB": {
"BatchSize": 5000
}
}
连接池配置
{
"GreptimeDB": {
"TimeoutSeconds": 30
}
}
重试机制
GreptimeDB作为审计日志存储提供了: