如何读取Serilog切割的SQLite历史数据库文件?或强制单文件日志
解决方案
一、读取历史日志数据库文件
每个Database-someDate.db都是结构与主库一致的独立SQLite数据库,你可以通过以下两种方式读取:
1. 遍历文件逐个读取
编写辅助方法,传入历史日志文件路径,动态创建EF连接读取日志数据:
public List<LogEntry> ReadLogsFromHistoryFile(string dbFilePath) { var options = new DbContextOptionsBuilder<YourDbContext>() .UseSqlite($"Data Source={dbFilePath}") .Options; using (var context = new YourDbContext(options)) { return context.Logs.ToList(); // 假设Logs是你的日志实体类 } } // 调用示例:遍历目录下所有历史日志文件 var logFiles = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "Database-*.db"); foreach (var file in logFiles) { var logs = ReadLogsFromHistoryFile(file); // 按需处理日志数据 }
2. 跨库联合查询(SQLite原生方式)
如果需要一次性查询主库+所有历史库的日志,可利用SQLite的ATTACH DATABASE命令,将历史库附加到当前连接后做联合查询:
public List<LogEntry> ReadAllLogs() { var mainDbPath = "./Database.db"; var options = new DbContextOptionsBuilder<YourDbContext>() .UseSqlite($"Data Source={mainDbPath}") .Options; using (var context = new YourDbContext(options)) { var logFiles = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "Database-*.db"); foreach (var file in logFiles) { // 为每个历史库生成唯一别名 var alias = $"HistoryDb_{Path.GetFileNameWithoutExtension(file)}"; context.Database.ExecuteSqlRaw($"ATTACH DATABASE '{file}' AS {alias}"); } // 联合查询所有库的Logs表 var unionQueries = logFiles.Select(f => $"SELECT * FROM HistoryDb_{Path.GetFileNameWithoutExtension(f)}.Logs"); var allLogsQuery = $"SELECT * FROM Logs UNION ALL {string.Join(" UNION ALL ", unionQueries)}"; var allLogs = context.Logs.FromSqlRaw(allLogsQuery).ToList(); // 可选:分离附加的数据库 foreach (var file in logFiles) { var alias = $"HistoryDb_{Path.GetFileNameWithoutExtension(file)}"; context.Database.ExecuteSqlRaw($"DETACH DATABASE {alias}"); } return allLogs; } }
二、强制Serilog使用单个数据库文件
Serilog.Sinks.SQLite默认会在文件达到10MB时滚动日志,你可以通过配置参数禁用滚动,或调整文件大小限制:
修改你的appSettings配置,添加以下参数:
<appSettings> <!-- 原有配置保持不变 --> <!-- 禁用日志滚动 --> <add key="sqlite:serilog:write-to:SQLite.rollOnFileSizeLimit" value="false"/> <!-- 可选:调整数据库文件最大允许大小,示例为100MB(单位字节) --> <add key="sqlite:serilog:write-to:SQLite.fileSizeLimitBytes" value="104857600"/> </appSettings>
rollOnFileSizeLimit设为false后,Serilog将不再创建历史文件,所有日志持续写入Database.dbfileSizeLimitBytes用于自定义数据库文件的最大阈值,默认是10MB(10485760字节),可根据业务需求调大
注意:禁用滚动后数据库文件会持续增大,建议定期手动清理或归档旧日志,避免文件过大影响读写性能。
内容的提问来源于stack exchange,提问作者Isaev Semyon
相关产品推荐
相关产品推荐

