0

目前有 Elastic Apm 设置:app.UseAllElasticApm(Configuration);它工作正常。我一直在尝试找到一种方法来准确记录通过实体框架为每个事务运行的 SQL 查询数量。

理想情况下,在 Kibana 中查看 Apm 数据时,元数据选项卡可以只包含一个EntityFramework.ExecutedSqlQueriesCount.

目前在.Net Core 2.2.3

4

1 回答 1

1

您可以使用的一件事是过滤器 API

这样,您就可以在将它们发送到 APM 服务器之前访问所有事务和跨度。

您无法遍历给定事务的所有跨度,因此您需要进行一些调整 - 为此我Dictionary在示例中使用 a 。

var numberOfSqlQueries = new Dictionary<string, int>();

Elastic.Apm.Agent.AddFilter((ITransaction transaction) =>
{
    if (numberOfSqlQueries.ContainsKey(transaction.Id))
    {
        // We make an assumption here: we assume that all SQL requests on a given transaction end before the transaction ends
        // this in practice means that you don't do any "fire and forget" type of query. If you do, you need to make sure
        // that the numberOfSqlQueries does not leak.
        transaction.Labels["NumberOfSqlQueries"] = numberOfSqlQueries[transaction.Id].ToString();
        numberOfSqlQueries.Remove(transaction.Id);
    }

    return transaction;
});

Elastic.Apm.Agent.AddFilter((ISpan span) =>
{
    // you can't relly filter whether if it's done by EF Core, or another database library
    // but you have all sorts of other info like db instance, also span.subtype and span.action could be helpful to filter properly
    if (span.Context.Db != null && span.Context.Db.Instance == "MyDbInstance")
    {
        if (numberOfSqlQueries.ContainsKey(span.TransactionId))
            numberOfSqlQueries[span.TransactionId]++;
        else
            numberOfSqlQueries[span.TransactionId] = 1;
    }

    return span;
});

这里有几件事:

  • 我假设你不做“一劳永逸”类型的查询,如果你这样做,你需要处理那些额外的
  • 计数并不是真正特定于 EF Core 查询,但您有数据库名称、数据库类型(mssql 等)之类的信息 - 希望您能够根据这些信息过滤您想要的查询。
  • 通过transaction.Labels["NumberOfSqlQueries"]我们为给定的交易添加标签,您将能够在 Kibana 中看到有关交易的这些数据。
于 2020-09-17T08:40:33.550 回答