使用 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>>();
我无法对最有效的方法发表评论,因为我不确定您的任务是什么。在某些情况下,最高效的方法是根本不反序列化整个负载。
我们使用客户端 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.
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>>();
我无法对最有效的方法发表评论,因为我不确定您的任务是什么。在某些情况下,最高效的方法是根本不反序列化整个负载。