.NET CORE 3 - 5 全局日志的书写

NET CORE 5.0 全局日志的书写

第一步 创建.NET CORE项目

第二步 项目依赖项下安装neget包 log4net

dotnet add package log4net

第三步 创建log4net.config文件

<?xml version="1.0" encoding="utf-8"?>
<configuration>
	<configSections>
		<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
	</configSections>

	<log4net>
		<!-- 将日志以回滚文件的形式写到文件中 -->
		<!-- 按日期切分日志文件,并将日期作为日志文件的名字 -->
		<appender name="RollingFileAppenderNameByDate" type="log4net.Appender.RollingFileAppender">
			<!-- 日志文件存放位置,可以为绝对路径也可以为相对路径 -->
			<file value="D:\Common.API\Logs\" />
			<!-- 将日志信息追加到已有的日志文件中-->
			<appendToFile value="true" />
			<!-- 最小锁定模式,以允许多个进程可以写入同一个文件 -->
			<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
			<!-- 指定按日期切分日志文件 -->
			<rollingStyle value="Date" />
			<!-- 日志文件的命名规则 -->
			<datePattern value="&quot;UtilLogs_&quot;yyyyMMdd&quot;.log&quot;" />
			<!-- 当将日期作为日志文件的名字时,必须将staticLogFileName的值设置为false -->
			<staticLogFileName value="false" />
			<!-- 日志显示模板 -->
			<layout type="log4net.Layout.PatternLayout">
				<conversionPattern value="【异常时间】:%date %newline%message%newline--------------------------------------------------------------------%newline" />
			</layout>
		</appender>

		<root>
			<!-- 控制级别,由低到高:ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF -->
			<!-- 比如定义级别为INFO,则INFO级别向下的级别,比如DEBUG日志将不会被记录 -->
			<!-- 如果没有定义LEVEL的值,则缺省为DEBUG -->
			<level value="ALL" />
			<!-- 按日期切分日志文件,并将日期作为日志文件的名字 -->
			<appender-ref ref="RollingFileAppenderNameByDate" />
		</root>
	</log4net>
</configuration>

第四步 创建AppSetting.cs类

using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace Common.API
{
    public class AppSetting
    {
        private static readonly object objLock = new object();
        private static AppSetting instance = null;
        private IConfigurationRoot Config { get; }

        private AppSetting()
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
            Config = builder.Build();
        }
        public static AppSetting GetInstance()
        {
            if (instance == null)
            {
                lock (objLock)
                {
                    if (instance == null)
                    {
                        instance = new AppSetting();
                    }
                }
            }
            return instance;
        }

        public static string GetConfig(string name)
        {
            return GetInstance().Config.GetSection(name).Value;
        }
    }
}

第五步 创建ILoggerHelper.cs接口类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Common.API.Log
{
    public interface ILoggerHelper
    {
        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Debug(object source, string message);
        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="ps">ps</param>
        void Debug(object source, string message, params object[] ps);
        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Debug(Type source, string message);
        /// <summary>
        /// 关键信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Info(object source, object message);
        /// <summary>
        /// 关键信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Info(Type source, object message);
        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Warn(object source, object message);
        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Warn(Type source, object message);
        /// <summary>
        /// 错误信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Error(object source, object message);
        /// <summary>
        /// 错误信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Error(Type source, object message);
        /// <summary>
        /// 失败信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Fatal(object source, object message);
        /// <summary>
        /// 失败信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        void Fatal(Type source, object message);

        /* Log a message object and exception */

        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Debug(object source, object message, Exception exception);
        /// <summary>
        /// 调试信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Debug(Type source, object message, Exception exception);
        /// <summary>
        /// 关键信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Info(object source, object message, Exception exception);
        /// <summary>
        /// 关键信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Info(Type source, object message, Exception exception);
        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Warn(object source, object message, Exception exception);
        /// <summary>
        /// 警告信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Warn(Type source, object message, Exception exception);
        /// <summary>
        /// 错误信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Error(object source, object message, Exception exception);
        /// <summary>
        /// 错误信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Error(Type source, object message, Exception exception);
        /// <summary>
        /// 失败信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Fatal(object source, object message, Exception exception);
        /// <summary>
        /// 失败信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="message">message</param>
        /// <param name="exception">ex</param>
        void Fatal(Type source, object message, Exception exception);
    }
}

第六步 创建 ILoggerHelper.cs接口实现类LogerHelper.cs 并实现接口方法继承

using Common.API.Log;
using log4net;
using log4net.Config;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace Common.API
{
    public class LogHelper : ILoggerHelper
    {
        private readonly ConcurrentDictionary<Type, ILog> Loggers = new ConcurrentDictionary<Type, ILog>();
        /// <summary>
        /// 获取记录器
        /// </summary>
        /// <param name="source">soruce</param>
        /// <returns></returns>
        private ILog GetLogger(Type source)
        {
            if (Loggers.ContainsKey(source))
            {
                return Loggers[source];
            }
            else
            {
                ILog logger = LogManager.GetLogger(Startup.repository.Name, source);
                Loggers.TryAdd(source, logger);
                return logger;
            }
        }

        public void Debug(object source, string message)
        {
            Debug(source.GetType(), message);
        }

        public void Debug(object source, string message, params object[] ps)
        {
            Debug(source.GetType(), string.Format(message, ps));
        }

        public void Debug(Type source, string message)
        {
            ILog logger = GetLogger(source);
            if (logger.IsDebugEnabled)
            {
                logger.Debug(message);
            }
        }

        public void Debug(object source, object message, Exception exception)
        {
            Debug(source.GetType(), message, exception);
        }

        public void Debug(Type source, object message, Exception exception)
        {
            GetLogger(source).Debug(message, exception);
        }

        public void Error(object source, object message)
        {
            Error(source.GetType(), message);
        }

        public void Error(Type source, object message)
        {
            ILog logger = GetLogger(source);
            if (logger.IsErrorEnabled)
            {
                logger.Error(message);
            }
        }

        public void Error(object source, object message, Exception exception)
        {
            Error(source.GetType(), message, exception);
        }

        public void Error(Type source, object message, Exception exception)
        {
            GetLogger(source).Error(message, exception);
        }

        public void Fatal(object source, object message)
        {
            Fatal(source.GetType(), message);
        }

        public void Fatal(Type source, object message)
        {
            ILog logger = GetLogger(source);
            if (logger.IsFatalEnabled)
            {
                logger.Fatal(message);
            }
        }

        public void Fatal(object source, object message, Exception exception)
        {
            Fatal(source.GetType(), message, exception);
        }

        public void Fatal(Type source, object message, Exception exception)
        {
            GetLogger(source).Fatal(message, exception);
        }

        public void Info(object source, object message)
        {
            Info(source.GetType(), message);
        }

        public void Info(Type source, object message)
        {
            ILog logger = GetLogger(source);
            if (logger.IsInfoEnabled)
            {
                logger.Info(message);
            }
        }

        public void Info(object source, object message, Exception exception)
        {
            Info(source.GetType(), message, exception);
        }

        public void Info(Type source, object message, Exception exception)
        {
            GetLogger(source).Info(message, exception);
        }

        public void Warn(object source, object message)
        {
            Warn(source.GetType(), message);
        }

        public void Warn(Type source, object message)
        {
            ILog logger = GetLogger(source);
            if (logger.IsWarnEnabled)
            {
                logger.Warn(message);
            }
        }

        public void Warn(object source, object message, Exception exception)
        {
            Warn(source.GetType(), message, exception);
        }

        public void Warn(Type source, object message, Exception exception)
        {
            GetLogger(source).Warn(message, exception);
        }
    }
}


第七步 创建全局异常类 GlobalExceptionFilter.cs

using Common.API.Log;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Common.API.Filte
{
    public class GlobalExceptionFilter : IExceptionFilter
    {
        private readonly IHostingEnvironment _env;
        private readonly ILoggerHelper _loggerHelper;
        public GlobalExceptionFilter(IHostingEnvironment env, ILoggerHelper loggerHelper)
        {
            _env = env;
            _loggerHelper = loggerHelper;
        }
        public void OnException(ExceptionContext context)
        {
            var json = new JsonErrorResponse();
            json.Message = context.Exception.Message;//错误信息
            if (_env.IsDevelopment())
            {
                json.DevelopmentMessage = context.Exception.StackTrace;//堆栈信息
            }
            context.Result = new InternalServerErrorObjectResult(json);

            //采用log4net 进行错误日志记录
            _loggerHelper.Error(json.Message, WriteLog(json.Message, context.Exception));
        }
        /// <summary>
        /// 自定义返回格式
        /// </summary>
        /// <param name="throwMsg"></param>
        /// <param name="ex"></param>
        /// <returns></returns>
        public string WriteLog(string throwMsg, Exception ex)
        {
            return string.Format("【自定义错误】:{0} \r\n【异常类型】:{1} \r\n【异常信息】:{2} \r\n【堆栈调用】:{3}", new object[] { throwMsg,
                ex.GetType().Name, ex.Message, ex.StackTrace });
        } 
    }
    public class InternalServerErrorObjectResult : ObjectResult
    {
        public InternalServerErrorObjectResult(object value) : base(value)
        {
            StatusCode = StatusCodes.Status500InternalServerError;
        }
    }
    //返回错误信息
    public class JsonErrorResponse
    {
        /// <summary>
        /// 生产环境的消息
        /// </summary>
        public string Message { get; set; }
        /// <summary>
        /// 开发环境的消息
        /// </summary>
        public string DevelopmentMessage { get; set; }
    }


}

第八步 路由注册 StarUp.cs

using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace Common.API
{
    public class Startup
    {  
	
	   /// <summary>
       /// log4net 仓储库
       /// </summary>
        public static ILoggerRepository repository { get; set; }
        public Startup(IConfiguration configuration)
        {
            //log4net
            repository = LogManager.CreateRepository("Common.API");//Common.API 为需要获取日志的仓库名,也就是你的当然项目名

            //指定配置文件,如果这里你遇到问题,应该是使用了InProcess模式,请查看Blog.Core.csproj,并删之 
            XmlConfigurator.Configure(repository, new FileInfo("log4net.config"));//配置文件
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
			
            //注入日志的全局异常捕获
            services.AddMvc(x =>
            {
                x.Filters.Add(typeof(GlobalExceptionFilter));
            }).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

            //log日志依赖注入
            services.AddSingleton<ILoggerHelper, LogHelper>();
			
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "Common.API", Version = "v1" });
            });

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Common.API v1"));
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}


第九步 判断结果 可在appsettings.json 内配置数据库连接字符串查看其异常结果 ,第三步内的 log4net.config文件可以修改日志的存放路径

异常记录
【异常时间】:2021-12-29 13:32:47,754
【自定义错误】:The ConnectionString property has not been initialized.
【异常类型】:InvalidOperationException
【异常信息】:The ConnectionString property has not been initialized.
【堆栈调用】: at System.Data.SqlClient.SqlConnection.PermissionDemand()
at System.Data.SqlClient.SqlConnectionFactory.PermissionDemand(DbConnection outerConnection)
at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource1 retry, DbConnectionOptions userOptions) at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource1 retry, DbConnectionOptions userOptions)
at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.Open()
at Common.API.SqlServer.SqlServerDBHelper.ExecuteNonQuery(String sql, String StringName) in D:\ComPany\ProjectFile\Exercise_Project\Common\Common.API\SqlServer\SqlServerDBHelper.cs:line 17
at Common.API.Controllers.WeatherForecastController.Sum(Int32 a, Int32 b) in D:\ComPany\ProjectFile\Exercise_Project\Common\Common.API\Controllers\WeatherForecastController.cs:line 46
at lambda_method3(Closure , Object , Object[] )
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Logged|12_1(ControllerActionInvoker invoker)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
— End of stack trace from previous location —
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)

转载于:

https://blog.csdn.net/Laity07/article/details/122327794

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值