首页 > 其他分享 >core中间件全局日志

core中间件全局日志

时间:2023-11-23 11:13:18浏览次数:34  
标签:core return string HttpContext 中间件 static context 日志 public

参考学习项目zradmin

在Configure中配置请求参数缓存

//使可以多次多去body内容
            app.Use((context, next) =>
            {
                context.Request.EnableBuffering();
                return next();//请求通道走向下一步
            });

在ConfigureServices配置中间件

 services.AddMvc(options =>
            {
                options.Filters.Add(typeof(GlobalActionMonitor));//全局注册
            })

中间件

public class GlobalActionMonitor : ActionFilterAttribute
    {
        static readonly Logger logger = LogManager.GetCurrentClassLogger();
        private ISysOperLogService OperLogService;
        public GlobalActionMonitor(ISysOperLogService operLogService)
        {
            OperLogService = operLogService;
        }

        /// <summary>
        /// Action请求前
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            ApiResult response = new();
            response.Code = (int)ResultCode.PARAM_ERROR;

            var values = context.ModelState.Values;
            foreach (var item in values)
            {
                foreach (var err in item.Errors)
                {
                    if (err.ErrorMessage.Contains("JSON"))
                    {
                        return next();
                    }
                    if (!string.IsNullOrEmpty(response.Msg))
                    {
                        response.Msg += " | ";
                    }

                    response.Msg += err.ErrorMessage;
                }
            }
            if (!string.IsNullOrEmpty(response.Msg))
            {
                logger.Info($"请求参数错误,{response.Msg}");
                context.Result = new JsonResult(response);
            }
            return base.OnActionExecutionAsync(context, next);
        }

        /// <summary>
        /// OnActionExecuted是在Action中的代码执行之后运行的方法。
        /// </summary>
        /// <param name="context"></param>
        public override void OnResultExecuted(ResultExecutedContext context)
        {
            if (context.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor) return;

            //获得注解信息
            LogAttribute logAttribute = GetLogAttribute(controllerActionDescriptor);
            if (logAttribute == null) return;

            try
            {
                string method = context.HttpContext.Request.Method.ToUpper();
                // 获取当前的用户
                string userName = context.HttpContext.GetName();
                string jsonResult = string.Empty;
                if (context.Result is ContentResult result && result.ContentType == "application/json")
                {
                    jsonResult = result.Content.Replace("\r\n", "").Trim();
                }
                if (context.Result is JsonResult result2)
                {
                    jsonResult = result2.Value?.ToString();
                }
                //获取当前执行方法的类名
                //string className =  System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name;
                //获取当前成员的名称
                //string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
                string controller = context.RouteData.Values["Controller"].ToString();
                string action = context.RouteData.Values["Action"].ToString();

                string ip = HttpContextExtension.GetClientUserIp(context.HttpContext);
                var ip_info = IpTool.Search(ip);

                SysOperLog sysOperLog = new()
                {
                    status = 0,
                    operName = userName,
                    operIp = ip,
                    operUrl = HttpContextExtension.GetRequestUrl(context.HttpContext),
                    requestMethod = method,
                    jsonResult = jsonResult,
                    operLocation = ip_info.Province + " " + ip_info.City,
                    method = controller + "." + action + "()",
                    //Elapsed = _stopwatch.ElapsedMilliseconds,
                    operTime = DateTime.Now
                };
                HttpContextExtension.GetRequestValue(context.HttpContext, sysOperLog);

                if (logAttribute != null)
                {
                    sysOperLog.title = logAttribute?.Title;
                    sysOperLog.businessType = (int)logAttribute?.BusinessType;
                    sysOperLog.operParam = logAttribute.IsSaveRequestData ? sysOperLog.operParam : "";
                    sysOperLog.jsonResult = logAttribute.IsSaveResponseData ? sysOperLog.jsonResult : "";
                }

                LogEventInfo ei = new(LogLevel.Info, "GlobalActionMonitor", "");
                
                ei.Properties["jsonResult"] = !HttpMethods.IsGet(method) ? jsonResult : "";
                ei.Properties["requestParam"] = sysOperLog.operParam;
                ei.Properties["user"] = userName;
                logger.Log(ei);

                OperLogService.InsertOperlog(sysOperLog);
            }
            catch (Exception ex)
            {
                logger.Error(ex, $"记录操作日志出错了#{ex.Message}");
            }
        }

        private LogAttribute GetLogAttribute(ControllerActionDescriptor controllerActionDescriptor)
        {
            var attribute = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true)
                .FirstOrDefault(a => a.GetType().Equals(typeof(LogAttribute)));

            return (LogAttribute)attribute;
        }
    }

方法上的日志特性

/// <summary>
    /// 自定义操作日志记录注解
    /// </summary>
    public class LogAttribute : System.Attribute
    {
        public string Title { get; set; }
        public BusinessType BusinessType { get; set; }
        /// <summary>
        /// 是否保存请求数据
        /// </summary>
        public bool IsSaveRequestData { get; set; } = true;
        /// <summary>
        /// 是否保存返回数据
        /// </summary>
        public bool IsSaveResponseData { get; set; } = true;

        public LogAttribute() { }

        public LogAttribute(string name)
        {
            Title = name;
        }
        public LogAttribute(string name, BusinessType businessType, bool saveRequestData = true, bool saveResponseData = true)
        {
            Title = name;
            BusinessType = businessType;
            IsSaveRequestData = saveRequestData;
            IsSaveResponseData = saveResponseData;
        }
    }

使用方式

上下网络获取

 /// <summary>
    /// HttpContext扩展类
    /// </summary>
    public static class HttpContextExtension
    {
        /// <summary>
        /// 是否是ajax请求
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public static bool IsAjaxRequest(this HttpRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            //return request.Headers.ContainsKey("X-Requested-With") &&
            //       request.Headers["X-Requested-With"].Equals("XMLHttpRequest");

            return request.Headers["X-Requested-With"] == "XMLHttpRequest" || (request.Headers != null && request.Headers["X-Requested-With"] == "XMLHttpRequest");
        }

        /// <summary>
        /// 获取客户端IP
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetClientUserIp(this HttpContext context)
        {
            if (context == null) return "";
            var result = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
            if (string.IsNullOrEmpty(result))
            {
                result = context.Connection.RemoteIpAddress.ToString();
            }
            if (string.IsNullOrEmpty(result) || result.Contains("::1"))
                result = "127.0.0.1";

            result = result.Replace("::ffff:", "127.0.0.1");
            result = IsIP(result) ? result : "127.0.0.1";
            return result;
        }

        public static bool IsIP(string ip)
        {
            return Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
        }

        public static long GetUId(this HttpContext context)
        {
            var uid = context.User.FindFirstValue(ClaimTypes.PrimarySid);

            return !string.IsNullOrEmpty(uid) ? long.Parse(uid) : 0;
        }
        public static string GetName(this HttpContext context)
        {
            var uid = context.User?.Identity?.Name;

            return uid;
        }

        public static bool IsAdmin(this HttpContext context)
        {
            long id = GetUId(context);
            return id == 1;
        }

        /// <summary>
        /// ClaimsIdentity
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static IEnumerable<ClaimsIdentity> GetClaims(this HttpContext context)
        {
            return context.User?.Identities;
        }
        //public static int GetRole(this HttpContext context)
        //{
        //    var roleid = context.User.FindFirstValue(ClaimTypes.Role) ?? "0";

        //    return int.Parse(roleid);
        //}

        public static string GetUserAgent(this HttpContext context)
        {
            return context.Request.Headers["User-Agent"];
        }

        /// <summary>
        /// 获取请求令牌
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetToken(this HttpContext context)
        {
            return context.Request.Headers["Authorization"];
        }

        public static ClientInfo GetClientInfo(this HttpContext context)
        {
            var str = GetUserAgent(context);
            var uaParser = Parser.GetDefault();
            ClientInfo c = uaParser.Parse(str);

            return c;
        }

        public static string GetRequestUrl(this HttpContext context)
        {
            return context != null ? context.Request.Path.Value : "";
        }

        /// <summary>
        /// 设置请求参数
        /// </summary>
        /// <param name="operLog"></param>
        /// <param name="context"></param>
        public static void GetRequestValue(this HttpContext context, SysOperLog operLog)
        {
            string reqMethod = operLog.requestMethod;
            string param;

            if (HttpMethods.IsPost(reqMethod) || HttpMethods.IsPut(reqMethod))
            {
                context.Request.Body.Seek(0, SeekOrigin.Begin);
                using var reader = new StreamReader(context.Request.Body, Encoding.UTF8);
                //需要使用异步方式才能获取
                param = reader.ReadToEndAsync().Result;
            }
            else
            {
                param = context.Request.QueryString.Value.ToString();
            }
            operLog.operParam = param;
        }

    }

这样一个全局异常就搞定了

标签:core,return,string,HttpContext,中间件,static,context,日志,public
From: https://www.cnblogs.com/shuaimeng/p/17851104.html

相关文章

  • 【HMS Core】应用内支付问题总结
    ​【问题描述1】集成应用内支付,怎么让微信或者支付宝的选项位于华为支付之前。​ 【解决方案】目前不能调整顺序的。 【问题描述2】用户手机上的价格,是按照什么货币单位显示的?【解决方案】手机客户端根据当前华为帐号所属的服务地(查看方式:“应用市场>我的>设置>......
  • Sqlserver日志传送高可用搭建
    1.原理主数据库定时备份事务日志到共享文件夹,辅助数据库定时从共享文件夹把事务日志备份复制到本地文件夹中,辅助数据库定时将本地文件夹中的事务日志备份还原到数据库上。2.修改服务启动账户2.1.为什么修改如果使用默认的NTSERVICE\MSSQLSERVER用户启动SQLServer,NTSERVICE\S......
  • 在ASP.NET Core 中使用 .NET Aspire 消息传递组件
    前言云原生应用程序通常需要可扩展的消息传递解决方案,以提供消息队列、主题和订阅等功能。.NETAspire组件简化了连接到各种消息传递提供程序(例如Azure服务总线)的过程。在本教程中,小编将为大家介绍如何创建一个ASP.NETCore应用并将提交的消息将发送到服务总线主题以供订阅......
  • Nginx loki监控日志的学习
    Nginxloki监控日志的学习背景学习自:https://mp.weixin.qq.com/s/Qt1r7vzWvCcJpNDilWHuxQ增加了一些自己的理解第一部分nginx日志的完善在logformat的后面增加一个:log_formatjson_analyticsescape=json'{''"msec":"$msec",'......
  • asp.net core 8 目录索引
    netcorenetcore3.1知识累积HttpClientFactory是HttpClient的正确使用方式linux与windows路径字符串中分隔目录级别知识重点asp.netcore3.1CreateDefaultBuilder默认启动解析asp.netcore2.1中间件应用asp.netcore3.1日志记录Loggingasp,netcore3.1的过......
  • core-dns的pod运行失败
    经查询,该问题是由于系统内核版本过高导致的,把系统的内核版本降下来后,coredns运行正常。  ......
  • 对linux下日志文件error监控
    对日志文件中的error进行监控,当日志文件中出现error关键字时,就截取日志(grep-ierror不区分大小写进行搜索"error"关键字,但是会将包含error大小写字符的单词搜索出来),大家可以去看这编文章   1)第一类日志在每天的日志目录下生产的error日志,此日志文件每天都会自动生成,里面有......
  • 通用 log4j2 日志模板
    通用log4j2日志模板 <?xmlversion="1.0"encoding="UTF-8"?><!--配置项集属性status指明全局的最低日志级别。属性monitorInterval指明监控日志变化的时间间隔。这里指明了日志级别为debug,监控日志文件变化的周期是30毫秒格式:%m输出的......
  • 通用的 logback.xml 日志模版
    通用的logback.xml日志模版 <?xmlversion="1.0"encoding="UTF-8"?><configuration> <!--定义日志输出目录--> <substitutionPropertyname="log.base"value="/log/joyupx/trade/"/> <!--<jmxConfig......
  • 在Linux平台下使用.NET Core访问Access数据库读取mdb文件数据
    今天有群友在群里问C#能不能在Linux下访问Access数据库?我觉得这很有趣,因此研究折腾了一下,也因为很久没有写博文了,所以特意上来写博文分享经验。运行环境操作系统:Ubuntu22.04.3LTS(Jammy)开发工具:VisualStudio2022(17.8.0)运行时版本:.NETRuntime8.0依赖库:unixo......