dotnet add package log4net
<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=""UtilLogs_"yyyyMMdd".log"" />
<staticLogFileName value="false" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="【异常时间】:%date %newline%message%newline--------------------------------------------------------------------%newline" />
layout>
appender>
<root>
<level value="ALL" />
<appender-ref ref="RollingFileAppenderNameByDate" />
root>
log4net>
configuration>
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;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Common.API.Log
{
public interface ILoggerHelper
{
///
/// 调试信息
///
/// source
/// message
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);
}
}
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>();
///
/// 获取记录器
///
/// 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;
}
}
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);
}
}
}
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));
}
///
/// 自定义返回格式
///
///
///
///
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; }
}
}
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
{
///
/// log4net 仓储库
///
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();
});
}
}
}
异常记录
【异常时间】: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