netmash/NDB.Logging.Api/RequestLoggingAttribute.cs

66 lines
2.2 KiB
C#

using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Threading.Tasks;
namespace NDB.Logging.Api
{
public class RequestLoggingAttribute : ActionFilterAttribute
{
private readonly ILogger<RequestLoggingAttribute> _logger;
public RequestLoggingAttribute(ILogger<RequestLoggingAttribute> logger)
{
_logger = logger;
}
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var stopWatch = new Stopwatch();
stopWatch.Start();
var uid = Guid.NewGuid();
var request = ((DefaultHttpRequest)((ControllerBase)context.Controller).Request);
var requestUrl = request.Path;
if (request.QueryString != null && request.QueryString.HasValue)
requestUrl += request.QueryString.ToString();
var logContent = $"Start request {uid} for method {requestUrl}";
if (request.Method == WebRequestMethods.Http.Post)
{
var requestBody = await GetRequestBody(request);
logContent += $" with body {requestBody}";
}
_logger.LogInformation(logContent);
var resultContext = await next();
stopWatch.Stop();
if (resultContext.Exception != null)
_logger.LogError(resultContext.Exception, $"Request {uid} for method {requestUrl} failed - {resultContext.Exception.Message}");
_logger.LogInformation($"End request {uid} for method {requestUrl}");
_logger.LogDebug($"Request {uid} duration: {stopWatch.ElapsedMilliseconds:N0} ms");
}
private async Task<string> GetRequestBody(DefaultHttpRequest request)
{
if (request.ContentLength == 0)
return "-";
var body = new StreamReader(request.Body);
body.BaseStream.Seek(0, SeekOrigin.Begin);
var bodyStr = await body.ReadToEndAsync();
return bodyStr;
}
}
}