ABP Vnext 关于使用Serilog时自定义Sink,将日志保存到数据库(Orm为SqlSugar)
1、安装Serilog.AspNetCore(我这里安装的是6.0.0)
2、安装SqlSugarCore
3、定义模型类(自定义,想要哪些字段加哪些字段)
[SugarTable("Logs")]
public class Logs
{
[SugarColumn(IsPrimaryKey = true, OracleSequenceName = "SEQ_ID")]
public int Id { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? CreateTime { get; set; }
[SugarColumn(IsNullable = true)]
public string EventType { get; set; }
[SugarColumn(IsNullable = true)]
public string Message { get; set; }
[SugarColumn(IsNullable = true)]
public string Exception { get; set; }
}
4、定义SqlSugar上下文
public class DbContext : ITransientDependency
{
public IConfiguration _Configuration { get; set; }
public SqlSugarClient _SqlSugarClient { get; set; }
public DbContext (IConfiguration configuration)
{
_Configuration = configuration;
var connStr = _Configuration.GetConnectionString("Default");
// 创建SqlSugarClient
_SqlSugarClient = new SqlSugarClient(
new ConnectionConfig()
{
// 1.1、配置连接地址
ConnectionString = connStr,
DbType = DbType.Oracle, // 选择Oracle数据库
IsAutoCloseConnection = true,
MoreSettings = new ConnMoreSettings() { IsAutoToUpper = false },
}
);
}
}
5、添加一个Sink类
public class DatabaseSink : ILogEventSink,ISingletonDependency
{
private readonly DbContext _DbContext;
public MHWCSDatabaseSink(DbContext DbContext)
{
_DbContext = DbContext;
}
public void Emit(LogEvent logEvent)
{
var data = new Logs()
{
CreateTime = DateTime.Now,
EventType = logEvent.Level.ToString(),
Message = logEvent.MessageTemplate.Text,
Exception = logEvent.Exception?.Message,
};
var db = _DbContext._SqlSugarClient.CopyNew();
var entity = db.Insertable<Logs>(data).ExecuteReturnEntity();
}
}
tips:这里为什么要CopyNew呢,因为我在quartz里也输出了日志,所以为了防止线程问题,根据作者大大的提示,加了这个(赞美作者)
6、在你的program类或者模块类的OnApplicationInitialization方法中配置Serilog
Log.Logger = new LoggerConfiguration()
// 最小的记录的日志级别
.MinimumLevel.Debug()
// 重写quartz的最小的记录的日志的级别
.MinimumLevel.Override("Quartz", LogEventLevel.Information)
// Serilog 中用来将 LogContext 中的上下文信息
//(如自定义的属性或标记)自动附加到每条日志记录中的方法。
.Enrich.FromLogContext()
// 写到txt文件中
.WriteTo.File("Logs/AllLogs/log.txt", rollingInterval: RollingInterval.Day)
// 输出到控制台
.WriteTo.Console()
// 添加自定义的Sink
.WriteTo.Logger(_ =>
// 这里做了过滤,也就是过滤日志消息中包含某个常量(这个常量是自己写在某个类里的,不用可以吧这里的过滤去掉)
_.Filter.ByIncludingOnly(b => b.RenderMessage().Contains(FlagConsts.Flag))
//这里能getRequiredService的原因是在sink类上加了ISingletonDependency,应该能明白吧
.WriteTo.Sink(context.ServiceProvider.GetRequiredService<DatabaseSink>())
)
.CreateLogger();
7、如何使用
serilog好像是个静态类,没细看,直接在需要的地方打印即可
Log.Information("这是一条日志!");