首页 技术 正文
技术 2022年11月9日
0 收藏 864 点赞 3,187 浏览 6397 个字

下面直接贴出实现代码

FileLoggerProvider

/// <summary>
/// 文件记录器提供商
/// </summary>
public class FileLoggerProvider : ILoggerProvider
{ /// <summary>
/// 配置
/// </summary>
private readonly IConfiguration configuration; /// <summary>
/// 构造方法
/// </summary>
/// <param name="configuration">配置</param>
public FileLoggerProvider(IConfiguration configuration)
{
this.configuration = configuration;
} /// <summary>
/// 创建记录器
/// </summary>
/// <param name="categoryName">类别名称</param>
/// <returns></returns>
public ILogger CreateLogger(string categoryName)
{
return new FileLogger(configuration, categoryName);
} /// <summary>
/// 释放方法
/// </summary>
public void Dispose()
{
}
}
  Lock
/// <summary>
/// IO锁
/// </summary>
public static class Lock
{ /// <summary>
/// 文件读写锁
/// </summary>
public static readonly ReaderWriterLockSlim fileLockSlim = null; ///// <summary>
///// 数据库读写锁
///// </summary>
//public static readonly ReaderWriterLockSlim dbLockSlim = null; /// <summary>
/// 构造方法
/// </summary>
static Lock()
{
fileLockSlim = new ReaderWriterLockSlim();
//dbLockSlim = new ReaderWriterLockSlim();
}
}

  FileLogger

/// <summary>
/// 文件记录器
/// </summary>
public class FileLogger : ILogger
{ /// <summary>
/// 配置
/// </summary>
private readonly IConfiguration configuration; /// <summary>
/// 类别名称
/// </summary>
private readonly string categoryName; /// <summary>
/// 构造方法
/// </summary>
/// <param name="configuration">配置</param>
/// <param name="categoryName">类别名称</param>
public FileLogger(IConfiguration configuration, string categoryName)
{
this.configuration = configuration;
this.categoryName = categoryName;
} /// <summary>
/// 开始范围
/// </summary>
/// <typeparam name="TState">状态类型</typeparam>
/// <param name="state">状态</param>
/// <returns></returns>
public IDisposable BeginScope<TState>(TState state)
{
return null;
} /// <summary>
/// 是否使用
/// </summary>
/// <param name="logLevel">日志级别</param>
/// <returns></returns>
public bool IsEnabled(LogLevel logLevel)
{
var list = new List<IConfigurationSection>();
list.AddRange(configuration.GetSection("Logging:LogLevel").GetChildren());
list.AddRange(configuration.GetSection("Logging:FileLog:LogLevel").GetChildren()); var category = list.LastOrDefault(f => this.categoryName.StartsWith(f.Key)); if (category == null)
{
category = list.LastOrDefault(f => f.Key == "Default");
} if (category != null && Enum.TryParse(typeof(LogLevel), category.Value, out var level))
{
return (int)(LogLevel)level <= (int)logLevel;
}
return 2 <= (int)logLevel;
} /// <summary>
/// 日志
/// </summary>
/// <typeparam name="TState">状态类型</typeparam>
/// <param name="logLevel">日志级别</param>
/// <param name="eventId">事件ID</param>
/// <param name="state">状态</param>
/// <param name="exception">异常</param>
/// <param name="formatter">格式化委托</param>
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (IsEnabled(logLevel))
{
try
{
Lock.fileLockSlim.EnterWriteLock();
var baseDirectory = configuration.GetSection("Logging:FileLog:BaseDirectory").Value;
var fileName = configuration.GetSection("Logging:FileLog:FileName").Value;
var extensionName = configuration.GetSection("Logging:FileLog:ExtensionName").Value; var directory = Path.Combine(AppContext.BaseDirectory, string.IsNullOrWhiteSpace(baseDirectory) ? "app_log" : baseDirectory); if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
if (string.IsNullOrWhiteSpace(fileName))
{
fileName = DateTime.Now.ToString("yyyy-MM-dd");
}
else
{
fileName = DateTime.Now.ToString(fileName);
}
extensionName = string.IsNullOrWhiteSpace(extensionName) ? ".log" : extensionName; var path = Path.Combine(directory, $"{fileName}{extensionName}");
var flag = true;
if (File.Exists(path))
{
var maxSize = configuration.GetSection("Logging:FileLog:MaxFileSize").Value;
var fileInfo = new FileInfo(path);
flag = fileInfo.Length / 1024.00 > (string.IsNullOrWhiteSpace(maxSize) ? 2048.00 : Convert.ToDouble(maxSize));
} var streamWrite = flag ? File.CreateText(path) : File.AppendText(path);
var dateTimeFormart = configuration.GetSection("Logging:FileLog:DateTimeFormat").Value; var logTime = DateTime.Now.ToString((string.IsNullOrWhiteSpace(dateTimeFormart) ? "yyyy-MM-dd HH:mm:ss.fff" : dateTimeFormart));
var message = formatter(state, exception); var stackTrace = exception?.StackTrace; var template = configuration.GetSection("Logging:FileLog:Template").Value; if (string.IsNullOrWhiteSpace(template))
{
streamWrite.WriteLine($"日志时间:{logTime} 类别名称:{categoryName} 日志级别:{logLevel} 消息:{message}"); if (!string.IsNullOrWhiteSpace(stackTrace))
{
streamWrite.WriteLine(stackTrace);
}
}
else
{
template = template.Replace("{logTime}", logTime, StringComparison.OrdinalIgnoreCase);
template = template.Replace("{catetoryName}", categoryName, StringComparison.OrdinalIgnoreCase);
template = template.Replace("{eventId}", eventId.Id.ToString(), StringComparison.OrdinalIgnoreCase);
template = template.Replace("{eventName}", eventId.Name, StringComparison.OrdinalIgnoreCase);
template = template.Replace("{logLevel}", logLevel.ToString(), StringComparison.OrdinalIgnoreCase);
template = template.Replace("{message}", message, StringComparison.OrdinalIgnoreCase);
template = template.Replace("{stackTrace}", stackTrace, StringComparison.OrdinalIgnoreCase);
template = template.Trim();
streamWrite.WriteLine(template);
} streamWrite.WriteLine();
streamWrite.Close(); var directoryInfo = new DirectoryInfo(directory);
var fileInfos = directoryInfo.GetFiles();
var fileCount = Convert.ToInt32(configuration.GetSection("Logging:FileLog:MaxFileCount").Value);
if (fileInfos.Length > fileCount && fileCount > 0)
{
var removeFileInfo = fileInfos.OrderBy(o => o.CreationTime).ThenBy(o => o.LastWriteTime).SkipLast(fileCount);
foreach (var item in removeFileInfo)
{
File.Delete(item.FullName);
}
}
}
catch (Exception ex)
{
Console.WriteLine($"写入文件日志异常:{ex.Message}");
Console.WriteLine(ex.StackTrace);
}
finally
{
Lock.fileLockSlim.ExitWriteLock();
}
}
}
}
  ILoggingBuilderExtensions
/// <summary>
/// 日志构造扩展类
/// </summary>
public static class ILoggingBuilderExtensions
{ /// <summary>
/// 添加文件日志
/// </summary>
/// <param name="loggingBuilder">日志构建</param>
public static ILoggingBuilder AddFileLog(this ILoggingBuilder loggingBuilder)
{
loggingBuilder.Services.AddSingleton<FileLoggerProvider>();
var sevices = loggingBuilder.Services.BuildServiceProvider();
return loggingBuilder.AddProvider(sevices.GetService<FileLoggerProvider>());
} }

  

Json配置格式示例

{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
},
"FileLog": {
"LogLevel": {
"Default": "Information"
},
"BaseDirectory": "app_log",
"FileName": "yyyy-MM-dd",
"ExtensionName": ".log",
"Template": "LogTime:{LogTime} CatetoryName:{CatetoryName} LogLevel:{LogLevel}\r\n{Message}\r\n{StackTrace}\r\n",
"MaxFileCount": 10,
"MaxFileSize": 2048,
"DateTimeFormat": "yyyy-MM-dd HH:mm:ss.fff"
}
}
}

  

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,122
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,594
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,439
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,210
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,846
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,931