You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何读取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.db
  • fileSizeLimitBytes用于自定义数据库文件的最大阈值,默认是10MB(10485760字节),可根据业务需求调大

注意:禁用滚动后数据库文件会持续增大,建议定期手动清理或归档旧日志,避免文件过大影响读写性能。


内容的提问来源于stack exchange,提问作者Isaev Semyon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 08:11:24