原文作者:老张的哲学
在 Blog.core 下的 Log 文件夹内,新建 ILoggerHelper.cs
更新:这个接口其实也没必要,你可以直接参考官方提供的ILogger,然后注入就行,当然看个人习惯吧,如果一定要自己设计,可按照我的方法设计接口
using System;
namespace Blog.Core.API.Log
{
///
/// 日志接口
///
public interface ILoggerHelper
{
///
/// 调试信息
///
///
///
void Debug(object source, string message);
///
/// 调试信息
///
/// source
/// message
/// ps
void Debug(object source, string message, params object[] ps);
///
/// 调试信息
///
/// source
/// message
void Debug(Type source, string message);
///
/// 关键信息
///
/// source
/// message
void Info(object source, object message);
///
/// 关键信息
///
/// source
/// message
void Info(Type source, object message);
///
/// 警告信息
///
/// source
/// message
void Warn(object source, object message);
///
/// 警告信息
///
/// source
/// message
void Warn(Type source, object message);
///
/// 错误信息
///
/// source
/// message
void Error(object source, object message);
///
/// 错误信息
///
/// source
/// message
void Error(Type source, object message);
///
/// 失败信息
///
/// source
/// message
void Fatal(object source, object message);
///
/// 失败信息
///
/// source
/// message
void Fatal(Type source, object message);
/* Log a message object and exception */
///
/// 调试信息
///
/// source
/// message
/// ex
void Debug(object source, object message, Exception exception);
///
/// 调试信息
///
/// source
/// message
/// ex
void Debug(Type source, object message, Exception exception);
///
/// 关键信息
///
/// source
/// message
/// ex
void Info(object source, object message, Exception exception);
///
/// 关键信息
///
/// source
/// message
/// ex
void Info(Type source, object message, Exception exception);
///
/// 警告信息
///
/// source
/// message
/// ex
void Warn(object source, object message, Exception exception);
///
/// 警告信息
///
/// source
/// message
/// ex
void Warn(Type source, object message, Exception exception);
///
/// 错误信息
///
/// source
/// message
/// ex
void Error(object source, object message, Exception exception);
///
/// 错误信息
///
/// source
/// message
/// ex
void Error(Type source, object message, Exception exception);
///
/// 失败信息
///
/// source
/// message
/// ex
void Fatal(object source, object message, Exception exception);
///
/// 失败信息
///
/// source
/// message
/// ex
void Fatal(Type source, object message, Exception exception);
}
}
1、在 Log 文件夹下新建 LogHelper.cs
using log4net;
using System;
using System.Collections.Concurrent;
namespace Blog.Core.API.Log
{
public class LogHelper : ILoggerHelper
{
private readonly ConcurrentDictionary Loggers = new ConcurrentDictionary();
///
/// 获取记录器
///
/// soruce
///
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;
}
}
/* Log a message object */
///
/// 调试信息
///
/// source
/// message
public void Debug(object source, string message)
{
Debug(source.GetType(), message);
}
///
/// 调试信息
///
/// source
/// message
/// ps
public void Debug(object source, string message, params object[] ps)
{
Debug(source.GetType(), string.Format(message, ps));
}
///
/// 调试信息
///
/// source
/// message
public void Debug(Type source, string message)
{
ILog logger = GetLogger(source);
if (logger.IsDebugEnabled)
{
logger.Debug(message);
}
}
///
/// 关键信息
///
/// source
/// message
public void Info(object source, object message)
{
Info(source.GetType(), message);
}
///
/// 关键信息
///
/// source
/// message
public void Info(Type source, object message)
{
ILog logger = GetLogger(source);
if (logger.IsInfoEnabled)
{
logger.Info(message);
}
}
///
/// 警告信息
///
/// source
/// message
public void Warn(object source, object message)
{
Warn(source.GetType(), message);
}
///
/// 警告信息
///
/// source
/// message
public void Warn(Type source, object message)
{
ILog logger = GetLogger(source);
if (logger.IsWarnEnabled)
{
logger.Warn(message);
}
}
///
/// 错误信息
///
/// source
/// message
public void Error(object source, object message)
{
Error(source.GetType(), message);
}
///
/// 错误信息
///
/// source
/// message
public void Error(Type source, object message)
{
ILog logger = GetLogger(source);
if (logger.IsErrorEnabled)
{
logger.Error(message);
}
}
///
/// 失败信息
///
/// source
/// message
public void Fatal(object source, object message)
{
Fatal(source.GetType(), message);
}
///
/// 失败信息
///
/// source
/// message
public void Fatal(Type source, object message)
{
ILog logger = GetLogger(source);
if (logger.IsFatalEnabled)
{
logger.Fatal(message);
}
}
/* Log a message object and exception */
///
/// 调试信息
///
/// source
/// message
/// ex
public void Debug(object source, object message, Exception exception)
{
Debug(source.GetType(), message, exception);
}
///
/// 调试信息
///
/// source
/// message
/// ex
public void Debug(Type source, object message, Exception exception)
{
GetLogger(source).Debug(message, exception);
}
///
/// 关键信息
///
/// source
/// message
/// ex
public void Info(object source, object message, Exception exception)
{
Info(source.GetType(), message, exception);
}
///
/// 关键信息
///
/// source
/// message
/// ex
public void Info(Type source, object message, Exception exception)
{
GetLogger(source).Info(message, exception);
}
///
/// 警告信息
///
/// source
/// message
/// ex
public void Warn(object source, object message, Exception exception)
{
Warn(source.GetType(), message, exception);
}
///
/// 警告信息
///
/// source
/// message
/// ex
public void Warn(Type source, object message, Exception exception)
{
GetLogger(source).Warn(message, exception);
}
///
/// 错误信息
///
/// source
/// message
/// ex
public void Error(object source, object message, Exception exception)
{
Error(source.GetType(), message, exception);
}
///
/// 错误信息
///
/// source
/// message
/// ex
public void Error(Type source, object message, Exception exception)
{
GetLogger(source).Error(message, exception);
}
///
/// 失败信息
///
/// source
/// message
/// ex
public void Fatal(object source, object message, Exception exception)
{
Fatal(source.GetType(), message, exception);
}
///
/// 失败信息
///
/// source
/// message
/// ex
public void Fatal(Type source, object message, Exception exception)
{
GetLogger(source).Fatal(message, exception);
}
}
}
image
这个时候,你会发现还有一个错误 , 不过别慌,请往下看。
image
1、在启动文件中添加 Loger 日志仓库
这个具体深入的概念,我还在研究中,有时间补充下,这里大概了解用法以及概念,留一个坑
///
/// log4net 仓储库
///
public static ILoggerRepository repository { get; set; }
Repository可以说成基于一个log4net配置节创建的log4net容器,它根据log4net配置节的指示创建其他所有对象(Logger/Appender/Filter/Layout等等)并保有他们的实例,随时为你所用。
每个Repository都有自己唯一的名字,如 root。
一般而言一个AppDomain(或者说一个进程)有一个Repository,该AppDomain下所有程序集Assembly都可以使用这个Repository。Repository需要实现ILoggerRepository,log4net中log4net.Repository.Hierarchy.Hierarchy就通过继承LoggerRepositorySkeleton实现了ILoggerRepository,它也是log4net中唯一实现ILoggerRepository的类。
//log4net
repository = LogManager.CreateRepository("");//需要获取日志的仓库名,也就是你的当然项目名
//指定配置文件,如果这里你遇到问题,应该是使用了InProcess模式,请查看Blog.Core.csproj,并删之
XmlConfigurator.Configure(repository, new FileInfo("log4net.config"));//配置文件
image.png
在 Blog.core 根目录下,添加 Log4net.config
最终的结构是
image
这个时候,我们已经把日志添加好了,可以在任何需用用的地方去使用了,你会问了,不是全局么,总不能每个方法都写 try catch 吧,有想法,请往下看。
1、日志接口进行注入
在 启动文件的 ConfigureServices方法中,添加服务注入
//log日志注入
services.AddSingleton();
2、Blog.core 新建Filter 文件夹,添加 GlobalExceptionFilter.cs
using Blog.Core.API.Log;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
namespace Blog.Core.API.Filter
{
///
/// 全局异常错误日志
///
public class GlobalExceptionFilter
{
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));
}
///
/// 自定义返回格式
///
///
///
///
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
{
///
/// 生产环境的消息
///
public string Message { get; set; }
///
/// 开发环境的消息
///
public string DevelopmentMessage { get; set; }
}
}
}
3、在启动服务中,注入全局异常
//注入全局异常捕获
services.AddMvc(o =>
{
o.Filters.Add(typeof(GlobalExceptionsFilter));
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
结构是这样的
image
我故意写错数据库连接字符串,看看 swagger 如何报错
image
看看日志是如何记录的
image
今天是不定期更新系列,也是群里小伙伴提出来的想法,我自己简单搞搞,这里希望大家可以积极提意见哟,如果技术不错,我会把你的个人主页和Git放到文章中,也算是鼓励大家的一个方式了。