mattwcole / gelf-extensions-logging

GELF provider for Microsoft.Extensions.Logging
MIT License
109 stars 42 forks source link

I can't write additional information into graylog. #30

Closed CwjXFH closed 5 years ago

CwjXFH commented 5 years ago

Hi, I use this package like this:

// config graylog
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    var gelfLoggerOptions = new GelfLoggerOptions()
    {
        Host = ConfigurationManager.AppSettings["grayLogHost"],
        Port = Convert.ToInt32(ConfigurationManager.AppSettings["grayLogPort"]),
        LogSource = ConfigurationManager.AppSettings["grayLogSource"],
        Protocol = GelfProtocol.Udp
    };
    loggerFactory.AddGelf(gelfLoggerOptions);

    app.UseMvc();
}
// write request info into graylog
public class GrayLogFilter : IActionFilter
{
    private readonly ILogger _logger;
    private const string REQUEST_START_TIME = "REQUEST_START_TIME";
    public GrayLogFilter(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger("grayLog");
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        try
        {
            var request = context.HttpContext.Request;
            var method = request.Method;
            var url = request.GetEncodedUrl();
            var statusCode = context.HttpContext.Response.StatusCode;
            var requestData = context.ActionDescriptor.Parameters;

            var requestStartTime = (DateTime)context.HttpContext.Items[REQUEST_START_TIME];
            var elapsed = (DateTime.Now - requestStartTime).Milliseconds;

            _logger.LogInformation($"{method} {url} {statusCode}", new { Request = requestData, Elapsed = elapsed });
        }
        catch
        {
            // ignore
        }
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        context.HttpContext.Items[REQUEST_START_TIME] = DateTime.Now;
    }

}

But, the info write into graylog like this: image Where's the new { Request = requestData, Elapsed = elapsed }?


I try solve this problem in this way:

// GrayLogEntity is my custom type
var grayLogEntity = new GrayLogEntity()
{
    RequestHeader = $"{method} {url} {statusCode}",
    RequestData = requestData,
    Elapsed = elapsed
};

_logger.Log(LogLevel.Information, eventId: default, state: grayLogEntity, exception: null, formatter:
                    (entity, ex) => { return entity.RequestHeader; });

But,it annot write grayLogEntity into Graylog.

Finally,i try this way:

var gelfLoggerOptions = new GelfLoggerOptions()
{
    Host = ConfigurationManager.AppSettings["grayLogHost"],
    Port = Convert.ToInt32(ConfigurationManager.AppSettings["grayLogPort"]),
    LogSource = ConfigurationManager.AppSettings["grayLogSource"],
    Protocol = GelfProtocol.Udp
};
var messageProcesser = new GelfMessageProcessor(new UdpGelfClient(gelfLoggerOptions));
var message = new GelfMessage()
{
    Level = SyslogSeverity.Informational,
    Host = request.Host.Value,
    Timestamp = Math.Round((double)DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() / 1000.0, 2),
    ShortMessage = $"{method} {url} {statusCode}",
    Logger = "graylog",
    AdditionalFields = new Dictionary<string, object>()
    {
        ["Elapsed"] = elapsed,
        ["RequestData"] = requestData
    }
};
messageProcesser.SendMessage(message);

But,nothing write into graylog,:joy:

Please help me,thanks!

mattwcole commented 5 years ago

The readme explains how to add additional fields to your logs, and there are also some samples that might help. The reason your first attempt isn't working is because your parameters don't match your message template. You might be better off with a log scope. You could use a middleware, similar to this one to attach additional fields to all of the logs made during the request.

using (_logger.BeginScope(new Dictionary<string, object>
{
    ["method"] = "...",
    ["url"] = "..."
}))
{
    await _next.Invoke(context);
}
CwjXFH commented 5 years ago

@mattwcole I got it,Thanks!