123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- using Microsoft.AspNetCore.Connections;
- using Microsoft.AspNetCore.Http;
- using Microsoft.Extensions.Logging;
- using System;
- using System.Diagnostics;
- using System.Text;
- using System.Threading.Tasks;
- namespace FastGithub.HttpServer.HttpMiddlewares
- {
- /// <summary>
- /// 请求日志中间件
- /// </summary>
- sealed class RequestLoggingMiddleware
- {
- private readonly ILogger<RequestLoggingMiddleware> logger;
- /// <summary>
- /// 请求日志中间件
- /// </summary>
- /// <param name="logger"></param>
- public RequestLoggingMiddleware(ILogger<RequestLoggingMiddleware> logger)
- {
- this.logger = logger;
- }
- /// <summary>
- /// 执行请求
- /// </summary>
- /// <param name="context"></param>
- /// <param name="next"></param>
- /// <returns></returns>
- public async Task InvokeAsync(HttpContext context, RequestDelegate next)
- {
- var feature = new RequestLoggingFeature();
- context.Features.Set<IRequestLoggingFeature>(feature);
- var stopwatch = Stopwatch.StartNew();
- try
- {
- await next(context);
- }
- finally
- {
- stopwatch.Stop();
- }
- if (feature.Enable == false)
- {
- return;
- }
- var request = context.Request;
- var response = context.Response;
- var exception = context.GetForwarderErrorFeature()?.Exception;
- if (exception == null)
- {
- logger.LogInformation($"{request.Method} {request.Scheme}://{request.Host}{request.Path} responded {response.StatusCode} in {stopwatch.Elapsed.TotalMilliseconds} ms");
- }
- else if (IsError(exception))
- {
- logger.LogError($"{request.Method} {request.Scheme}://{request.Host}{request.Path} responded {response.StatusCode} in {stopwatch.Elapsed.TotalMilliseconds} ms{Environment.NewLine}{exception}");
- }
- else
- {
- logger.LogWarning($"{request.Method} {request.Scheme}://{request.Host}{request.Path} responded {response.StatusCode} in {stopwatch.Elapsed.TotalMilliseconds} ms{Environment.NewLine}{GetMessage(exception)}");
- }
- }
- /// <summary>
- /// 是否为错误
- /// </summary>
- /// <param name="exception"></param>
- /// <returns></returns>
- private static bool IsError(Exception exception)
- {
- if (exception is OperationCanceledException)
- {
- return false;
- }
- if (HasInnerException<ConnectionAbortedException>(exception))
- {
- return false;
- }
- return true;
- }
- /// <summary>
- /// 是否有内部异常异常
- /// </summary>
- /// <typeparam name="TInnerException"></typeparam>
- /// <param name="exception"></param>
- /// <returns></returns>
- private static bool HasInnerException<TInnerException>(Exception exception) where TInnerException : Exception
- {
- var inner = exception.InnerException;
- while (inner != null)
- {
- if (inner is TInnerException)
- {
- return true;
- }
- inner = inner.InnerException;
- }
- return false;
- }
- /// <summary>
- /// 获取异常信息
- /// </summary>
- /// <param name="exception"></param>
- /// <returns></returns>
- private static string GetMessage(Exception exception)
- {
- var ex = exception;
- var builder = new StringBuilder();
- while (ex != null)
- {
- var type = ex.GetType();
- builder.Append(type.Namespace).Append('.').Append(type.Name).Append(": ").AppendLine(ex.Message);
- ex = ex.InnerException;
- }
- return builder.ToString();
- }
- private class RequestLoggingFeature : IRequestLoggingFeature
- {
- public bool Enable { get; set; } = true;
- }
- }
- }
|