Пользовательское форматирование Serilog HTTP Sink для Logstash - PullRequest
0 голосов
/ 19 октября 2018

Я использую Приемник Serilog HTTP для входа в Logstash в моем .Net Core Project.В файле startup.cs у меня есть следующий код для включения serilog.

 Log.Logger = new LoggerConfiguration()
        .Enrich.FromLogContext()
        .WriteTo.Http("http://mylogstashhost.com:5000").Enrich.WithProperty("user", "xxx").Enrich.WithProperty("serviceName", "yyy")
        .MinimumLevel.Warning()
        .CreateLogger();

И этот код отправляет журналы на указанный http-адрес.На фиддлере я вижу, что следующий json публикуется в logstash, и logstash возвращает сообщение "ok".

{"events":[{"Timestamp":"2018-10-19T18:16:27.6561159+01:00","Level":"Warning","MessageTemplate":"abc","RenderedMessage":"abc","user":"xxx","serviceName":"yyy","Properties":{"ActionId":"b313b8ed-0baf-4d75-a6e2-f0dbcb941f67","ActionName":"MyProject.Controllers.HomeController.Index","RequestId":"0HLHLQMV1EBCJ:00000003","RequestPath":"/"}}]}

Но когда я проверял Кибану, я не вижу этот журнал.Я попытался выяснить, чем это вызвано, и я понял, что если я отправлю json в следующем формате, я смогу увидеть журнал.

{"Timestamp":"2018-10-19T18:16:27.6561159+01:00","Level":"Warning","MessageTemplate":"abc","RenderedMessage":"abc","user":"xxx","serviceName":"yyy","Properties":{"ActionId":"b313b8ed-0baf-4d75-a6e2-f0dbcb941f67","ActionName":"MyProject.Controllers.HomeController.Index" ,"RequestId":"0HLHLQMV1EBCJ:00000003","RequestPath":"/"}}

Так что Logstash не нравится, чтобы событие было в Events {}, а также онохочет, чтобы теги "user" и "ServiceName" были удалены из "Properties".Есть ли способ отформатировать мой Json, как это?

1 Ответ

0 голосов
/ 20 октября 2018

Хорошо, после некоторых исследований и помощи, в основном для создания пользовательских форматов, нужно реализовать такие интерфейсы, как ITextFormatter, BatchFormatter и т. Д.

Я мог бы добиться нужного мне формата, немного изменив ArrayBatchFormatter:

public class MyFormat : BatchFormatter
{
    /// <summary>
    /// Initializes a new instance of the <see cref="ArrayBatchFormatter"/> class.
    /// </summary>
    /// <param name="eventBodyLimitBytes">
    /// The maximum size, in bytes, that the JSON representation of an event may take before it
    /// is dropped rather than being sent to the server. Specify null for no limit. Default
    /// value is 256 KB.
    /// </param>
    public MyFormat(long? eventBodyLimitBytes = 256 * 1024): base(eventBodyLimitBytes)
    {

    }

    /// <summary>
    /// Format the log events into a payload.
    /// </summary>
    /// <param name="logEvents">
    /// The events to format.
    /// </param>
    /// <param name="output">
    /// The payload to send over the network.
    /// </param>
    public override void Format(IEnumerable<string> logEvents, TextWriter output)
    {
        if (logEvents == null) throw new ArgumentNullException(nameof(logEvents));
        if (output == null) throw new ArgumentNullException(nameof(output));

        // Abort if sequence of log events is empty
        if (!logEvents.Any())
        {
            return;
        }

        output.Write("[");

        var delimStart = string.Empty;

        foreach (var logEvent in logEvents)
        {
            if (string.IsNullOrWhiteSpace(logEvent))
            {
                continue;
            }
            int index = logEvent.IndexOf("{");

            string adjustedString = "{\"user\":\"xxx\",\"serviceName\" : \"yyy\"," + logEvent.Substring(1);
            if (CheckEventBodySize(adjustedString))
            {
                output.Write(delimStart);
                output.Write(adjustedString);
                delimStart = ",";
            }
        }

        output.Write("]");
    }
}
...