EF 拦截sql,并还原+requestid形成链路追踪

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>());
           

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值