第6章 初识SqlSugarCore之内置日志中间件与自定义日志

.NetCore框架集成了内置日志中间件,且该中间件在默认状态下处于启用状态

1 内置日志中间件

1.1 重构Web.Controllers.HomeController.HomeController方法

  public HomeController(SqlSugarContext context, ILogger<HomeController> logger)

        {

            _context = context;

            _logger = logger;

        }

1.2 重构Web.Controllers.HomeController.Index方法

    在该方法中定义以下代码:

   //调用.NetCore框架内置日志中间件。

            _logger.LogTrace("这是内置【跟踪】日志方法!");

            _logger.LogDebug("这是内置【调用】日志方法!");

            _logger.LogInformation("这是内置【信息】日志方法!");

            _logger.LogWarning("这是内置【警告】日志方法!");

            _logger.LogError("这是内置【错误】日志方法!");

            _logger.LogCritical("这是内置【严重】日志方法!");

     按F5执行结果如下:

       从上图上可以看出,内置日志中间件中的方法“LogTrace”和“LogDebug”并不在控件台中输出日志信息。

2 自定义日志

    在当前实际开发中日志的主要作用是:

  1. 安全追踪,即当前网站受到攻击时,能够通用日志纪录信息查找出攻击方,及其通过那个类的进行攻击,以便开发者针对该方法进行打补丁。
  2. 商业网站中,也有利用日志数据,进行数据分析后,向终端用户进行精确推送。

不管上面的那功能都不是内置日志中间件所能达到的,首先内置日志中间件中的数据不能被持久化就是硬伤,所以开发者一半情况下会根据内置日志中间件的实现逻辑,自定义能够持久化的日志实体。

2.1 LogLevel

/// <summary>

    /// 【日志级别--枚举】

    /// <remarks>

    /// 摘要:

    ///    该枚举定义了5种日志级别,日志级别的严格成度从上往下递增,通过枚举实例选定其中的1种,可以过滤掉低级别的日志信息。

    /// </remarks>

    /// </summary>

    public enum LogLevel

    {

        /// <summary>

        /// 【调试】

        /// <remarks>

        /// 摘要:

        ///     设置处于“调试”级别的“日志级别--枚举”实例。

        /// </remarks>

        /// </summary>

        Debug = 10,

        /// <summary>

        /// 【信息】

        /// <remarks>

        /// 摘要:

        ///     设置处于“信息”级别的“日志级别--枚举”实例。

        /// </remarks>

        /// </summary>

        Information = 20,

        /// <summary>

        /// 【警告】

        /// <remarks>

        /// 摘要:

        ///     设置处于“警告”级别的“日志级别--枚举”实例。

        /// </remarks>

        /// </summary>

        Warning = 30,

        /// <summary>

        /// 【错误】

        /// <remarks>

        /// 摘要:

        ///     设置处于“错误”级别的“日志级别--枚举”实例。

        /// </remarks>

        /// </summary>

        Error = 40,

        /// <summary>

        /// 【灾难】

        /// <remarks>

        /// 摘要:

        ///     设置处于“灾难”级别的“日志级别--枚举”实例。

        /// </remarks>

        /// </summary>

        Fatal = 50

    }

2.2 Log

    /// <summary>

    /// 【日志--类】

    /// </summary>

    /// <remarks>

    /// 摘要:

    ///     通过该实体类及其属性成员,用于实现当前程序【Data】.【领域】.【日志集】.【日志】实体与“[SqlSugarAcquaintance].[Log]”表之间的CURD的交互操作,

    /// 并把这些数据存储到数据库设置实例中(内存)。

    /// </remarks>

    public class Log

    {

        /// <summary>

        /// 【编号】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定“日志”实例的整型编号值。

        /// </remarks>

        /// </summary>

        [SugarColumn(IsIdentity = true, IsPrimaryKey = true)]

        public int Id { get; set; }

        /// <summary>

        /// 【日志级别编号】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定“日志级别--枚举”实例的整型值。

        /// </remarks>

        /// </summary>

        public int LogLevelId { get; set; }

        /// <summary>

        /// 【实体名称】

        /// <remarks>

        /// 摘要:

        ///     获取/设置调用1个指定“日志”实例方法及其该方法所在类的全名。

        /// </remarks>

        /// </summary>

        [SugarColumn(ColumnDataType = "nvarchar", Length = int.MaxValue)]

        public string EntityName { get; set; }

        /// <summary>

        /// 【IP地址】

        /// <remarks>

        /// 摘要:

        ///     获取/设置触发1个指定“日志”实例的客户端的IP地址。

        /// </remarks>

        /// </summary>

        [SugarColumn(ColumnDataType = "nvarchar", Length = 255)]

        public string IpAddress { get; set; }

        /// <summary>

        /// 【短信息】

        /// <remarks>

        /// 摘要:

        ///     获取/设置对1个指定“日志”实例进行描述的简短信息。

        /// </remarks>

        /// </summary>

        [SugarColumn(ColumnDataType = "nvarchar", Length = 255)]

        public string ShortMessage { get; set; }

        /// <summary>

        /// 【完整信息】

        /// <remarks>

        /// 摘要:

        ///     获取/设置对1个指定“日志”实例进行描述的完整信息。

        /// </remarks>

        /// </summary>

        [SugarColumn(ColumnDataType = "nvarchar", Length = int.MaxValue)]

        public string FullMessage { get; set; }

        /// <summary>

        /// 【新建日期时间】

        /// <remarks>

        /// 摘要:

        ///    获取/设置“日志”实体的1个指定实例,第1次被持久化存储到数据库对应表中的(本地)时间。

        /// </remarks>

        /// </summary>

        public DateTime CreatedDataTime { get; set; }

    }

2.3 重构Data.SqlSugarContext.CreateTable方法

//通过过滤操作,获取领域文件夹中的所有实体的类型实例。

            //注意:“Where”过滤操作中“ c.Namespace”最好使用“Contains”,而不要使用“==”。

            Type[] _typeArray = assembly.GetTypes()

                .Where(c => c.Namespace.Contains("Data.Domain")&& c.IsClass)//过滤操作。

                .ToArray();

注意:

    在Code-Frist模式下SqlSugarCore中间件通过标记来定义实体与表之间的约束关系,使实体与约束定义产生了极强的耦合,并且当前本人没有在SqlSugarCore中间件找到关于忽略实体与表之间约束关系的标记即“[SugarTable]”标记不存在“IsIgnore = true”,所以实体的支持类最好不要定义在“Domain”文件夹中。

2.4 IpAddressExtension

/// <summary>

    /// 【IP地址扩展】

    /// </summary>

    /// <remarks>

    /// 摘要:

    ///     通过该类中的方法获取字符串类型的客户端IP地址。

    /// </remarks>

    public static class IpAddressExtension

    {

        ///<param name="context">HTTP下文实例。</param>

        /// <summary>

        /// 【获取客户端IP地址】

        /// <remarks>

        /// 摘要:

        ///    该方法用于获取客户端IP地址字符串。

        /// </remarks>

        /// </summary>

        public static string GetClientUserIp(this HttpContext context)

        {

            var userHostAddress = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();

            if (string.IsNullOrEmpty(userHostAddress))

            {

                userHostAddress = context.Connection.RemoteIpAddress.ToString();

            }

            //最后判断获取是否成功,并检查IP地址的格式(检查其格式非常重要)

            if (!string.IsNullOrEmpty(userHostAddress) && IsIP(userHostAddress))

            {

                return userHostAddress;

            }

            return "127.0.0.1";

        }

        ///<param name="ip">1个指定的字符串。</param>

        /// <summary>

        /// 【IP地址?】

        /// <remarks>

        /// 摘要:

        ///     通过相应的参数实例,验证1个指定的字符串是否与IP地址格式相匹配。

        /// </remarks>

        /// </summary>

        /// <returns>

        /// 返回:

        ///     1个值false(不匹配)/true(匹配)。

        /// </returns>

        public static bool IsIP(string ip)

        {

            return System.Text.RegularExpressions.Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");

        }

}

2.5 重构Program.cs

//解决Ubuntu Nginx 代理不能获取IP问题。

app.UseForwardedHeaders(new ForwardedHeadersOptions

{

    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto

});

2.6重构Web.Controllers.HomeController.Index方法

    在该方法中定义以下代码:

  //实例化自定义日志实体的1个指定实例,并把该实例持久化到日志表中。

            Log _model = new Log

            {

                LogLevelId = (int)LogLevel.Information,

                EntityName = typeof(HomeController).FullName +".Index",

                IpAddress= HttpContext.Request.HttpContext.GetClientUserIp(),

                ShortMessage = "获取与考试相关的所有数据,为页面的渲染显示提供支撑。",

                FullMessage = "获取与考试相关的所有数据,为页面的渲染显示提供支撑。",

                CreatedDataTime = DateTime.Now,

            };

            await _context.SugarScope.Insertable(_model).ExecuteReturnEntityAsync();

按F5执行结果如下:

对以上功能更为具体实现和注释见:22-10-08-06_SqlSugarAcquaintance(初识SqlSugarCore之内置与自定义日志)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值