使用 MS Bond 反序列化 Application Insights JSON 流

Deserializing Application Insights JSON stream using MS Bond

我们使用客户端 SDK 中的标准接收器扩展性,将 Application Insights 生成的数据副本发送到事件中心。我们遵循与默认接收器相同的批处理和压缩逻辑——而不是简单地将数据发送到事件中心端点。

在接收数据的函数应用程序中,单个 EventHub 消息因此将包含一个 JSON 流和多个遥测点,使用 gzip 压缩。

我们需要反序列化流并根据遥测类型采取一些操作。我们每秒将接收大约 50k,因此性能很重要。

我注意到 SDK 正在使用 Bond and has defined the public schema - https://github.com/Microsoft/ApplicationInsights-aspnetcore/tree/develop/Schema/PublicSchema

我目前正在做类似的事情,

foreach (var eventHubMessage in messages)
{
    // decompress the entire gzipped payload
    var decompressedData = DeserializeCompressedStream(eventHubMessage.Body.Array);

    // deframe the JSON stream into individual items, (e.g. data.Split(new[] { Environment.NewLine })
    var payloadItems = decompressedData.Deframe();

    foreach (var item in payloadItems){

        // A  standard JSON.NET conversion to get the item
        Envelope telemetryItem = ItemConverter.CreateTelemetryFromPayloadItem(item);

        // etc etc
    }
}

这行得通,但是使用 JSON.Net 在项目级别进行的转换在这种规模下是一项昂贵的操作,并且会超出 CPU。

假设执行反序列化的应用程序可以访问类型,例如 https://github.com/Microsoft/ApplicationInsights-aspnetcore/tree/develop/test/ApplicationInsightsTypes,使用 Bond 定义反序列化 JSON 流的推荐且最有效的方法是什么?

很遗憾,由于延迟反序列化中的一个问题,您无法反序列化整个信封:https://github.com/Microsoft/bond/issues/96

因此您需要以其他方式解析出 baseData,然后将其传递给绑定反序列化程序。或者像我们在 unit tests.

中所做的那样,使用一些 JSON 解析器将其解析为 JSON
JsonReader reader = new JsonTextReader(new StringReader(Encoding.UTF8.GetString(b, 0, b.Length)));
reader.DateParseHandling = DateParseHandling.None;
JObject obj = JObject.Load(reader);
return obj.ToObject<AI.TelemetryItem<TelemetryDataType>>();

我无法对最有效的方法发表评论,因为我不确定您的任务是什么。在某些情况下,最高效的方法是根本不反序列化整个负载。