Десериализация потока JSON приложения Insights с использованием MS Bond - PullRequest
0 голосов
/ 16 января 2019

Мы отправляем копию данных, сгенерированных Application Insights, в концентратор событий, используя стандартную расширяемость Sinks в клиентском SDK. Мы придерживаемся той же логики пакетной обработки и сжатия, что и для приемника по умолчанию, вместо этого просто отправляем данные в конечную точку концентратора событий.

В приложении-функции, которое получает данные, одно сообщение EventHub, следовательно, будет содержать поток JSON с несколькими точками телеметрии, сжатыми с помощью gzip.

Нам необходимо десериализовать поток и предпринять ряд действий в зависимости от типа телеметрии. Мы будем получать около 50 Кбит / с, поэтому производительность важна.

Я заметил, что SDK использует Bond и определил общедоступную схему - 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 является дорогостоящей операцией с таким масштабом и максимальной загрузкой ЦП.

Предполагая, что приложение, выполняющее десериализацию, имеет доступ к типам, например, https://github.com/Microsoft/ApplicationInsights-aspnetcore/tree/develop/test/ApplicationInsightsTypes, каков был бы рекомендуемый и наиболее эффективный способ десериализации потока JSON с использованием определений Bond?

1 Ответ

0 голосов
/ 16 января 2019

К сожалению, вы не можете десериализовать весь конверт из-за проблемы в Lazy Deserialization: https://github.com/Microsoft/bond/issues/96.

Так что вам нужно каким-то образом разобрать baseData, а затем передать его в десериализатор облигаций.,Или, возможно, просто проанализируйте его как 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>>();

Я не могу комментировать наиболее эффективный способ сделать это, так как не уверенкакова твоя задачаВ некоторых случаях наиболее эффективный способ - вообще не десериализовать всю полезную нагрузку.

...