public class RequestIdInterceptor : DbCommandInterceptor
{
private readonly string _requestId;
public RequestIdInterceptor()
{
}
public RequestIdInterceptor(IHttpContextAccessor httpContextAccessor)
{
_requestId = httpContextAccessor?.HttpContext?.TraceIdentifier ?? "no http";
}
// 读取数据之前
public override InterceptionResult<DbDataReader> ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result)
{
AddRequestIdToCommand(command);
return base.ReaderExecuting(command, eventData, result);
}
// 读取数据之前(异步)
public override ValueTask<InterceptionResult<DbDataReader>> ReaderExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result, CancellationToken cancellationToken = default)
{
AddRequestIdToCommand(command);
return base.ReaderExecutingAsync(command, eventData, result, cancellationToken);
}
// 读取数据之后
public override DbDataReader ReaderExecuted(DbCommand command, CommandExecutedEventData eventData, DbDataReader result)
{
return base.ReaderExecuted(command, eventData, result);
}
// 读取数据之后(异步)
public override ValueTask<DbDataReader> ReaderExecutedAsync(DbCommand command, CommandExecutedEventData eventData, DbDataReader result, CancellationToken cancellationToken = default)
{
return base.ReaderExecutedAsync(command, eventData, result, cancellationToken);
}
// DataReader 对象释放之前
public override InterceptionResult DataReaderDisposing(DbCommand command, DataReaderDisposingEventData eventData, InterceptionResult result)
{
return base.DataReaderDisposing(command, eventData, result);
}
// 无查询执行 sql 之前
public override InterceptionResult<int> NonQueryExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<int> result)
{
AddRequestIdToCommand(command);
return base.NonQueryExecuting(command, eventData, result);
}
// 无查询执行 sql 之前(异步)
public override ValueTask<InterceptionResult<int>> NonQueryExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<int> result, CancellationToken cancellationToken = default)
{
AddRequestIdToCommand(command);
return base.NonQueryExecutingAsync(command, eventData, result, cancellationToken);
}
// 无查询执行 sql 之后
public override int NonQueryExecuted(DbCommand command, CommandExecutedEventData eventData, int result)
{
AddRequestIdToCommand(command);
return base.NonQueryExecuted(command, eventData, result);
}
// 无查询执行 sql 之后(异步)
public override ValueTask<int> NonQueryExecutedAsync(DbCommand command, CommandExecutedEventData eventData, int result, CancellationToken cancellationToken = default)
{
AddRequestIdToCommand(command);
return base.NonQueryExecutedAsync(command, eventData, result, cancellationToken);
}
// 执行 sql 返回单行单列之前
public override InterceptionResult<object> ScalarExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<object> result)
{
AddRequestIdToCommand(command);
return base.ScalarExecuting(command, eventData, result);
}
// 执行 sql 返回单行单列之前(异步)
public override ValueTask<InterceptionResult<object>> ScalarExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<object> result, CancellationToken cancellationToken = default)
{
AddRequestIdToCommand(command);
return base.ScalarExecutingAsync(command, eventData, result, cancellationToken);
}
// 执行 sql 返回单行单列之后
public override object ScalarExecuted(DbCommand command, CommandExecutedEventData eventData, object result)
{
AddRequestIdToCommand(command);
return base.ScalarExecuted(command, eventData, result);
}
// 执行 sql 返回单行单列之后(异步)
public override ValueTask<object> ScalarExecutedAsync(DbCommand command, CommandExecutedEventData eventData, object result, CancellationToken cancellationToken = default)
{
AddRequestIdToCommand(command);
return base.ScalarExecutedAsync(command, eventData, result, cancellationToken);
}
private void AddRequestIdToCommand(DbCommand command)
{
if (_requestId.IsNullOrEmpty()) return;
//net中如何实现 请求 日志, 请求中间过程EFCore的生成的sql, 三方请求日志 的记录 并使用requestid关联起来,实现日志的链路追踪
// 替换参数占位符为具体的参数值
string fullSql = command.CommandText;
foreach (SqlParameter parameter in command.Parameters)
{
if (int.TryParse(parameter.Value.ToString(), out int topCount))
fullSql = fullSql.Replace(parameter.ParameterName, parameter.Value.ToString());
else
fullSql = fullSql.Replace(parameter.ParameterName, "'" + parameter.Value.ToString() + "'");
}
SqlInfo sqlInfo = new SqlInfo()
{
CommandText = fullSql,
RequestId = _requestId,
};
//插入数据库
//AI et中如何实现 请求id , EFCore, 三方请请求的调用链路追踪日志的记录,并且使用Nlog记录下来详细过程信息
}
}
public class SqlInfo
{
public string CommandText { get; set; }
public string RequestId { get; set; }
public DateTime CreateTime { get; set; } = DateTime.Now;
}
2.注入
IocManager.RegisterIfNot<RequestIdInterceptor>(DependencyLifeStyle.Transient);
3.挂载
builder.AddInterceptors(IocManager.Instance.Resolve<RequestIdInterceptor>());