using log4net;
using log4net.Appender;
using log4net.Config;
using log4net.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static log4net.Appender.FileAppender;
namespace AJR.Acquisition.Platform.Core.Helpers;
/// <summary>
/// Log4net帮助类
/// </summary>
public static class Log4Helper
{
static object lockObj = new object();
const string _defaultPath = @"logs\";
const string _defaultLogName = "log4Default";
static log4net.Filter.LevelRangeFilter levRangeFilter = new log4net.Filter.LevelRangeFilter();
static log4net.Layout.PatternLayout logLayout = new log4net.Layout.PatternLayout("%date [线程:%thread] %logger %newline %-5level [%class.%method 行%L]:%newline %message%newline%newline");
static ConcurrentDictionary<string, ILoggerRepository> repositoryList = new ConcurrentDictionary<string, ILoggerRepository>();
static Log4Helper()
{
levRangeFilter.LevelMax = log4net.Core.Level.Fatal;
levRangeFilter.LevelMin = log4net.Core.Level.Debug;
levRangeFilter.ActivateOptions();
initRepository();
}
static void repositoryCreateByDirection(string direction)
{
lock (lockObj)
{
if (repositoryList.ContainsKey(direction))
{
return;
}
var repository = LogManager.CreateRepository(direction);
BasicConfigurator.Configure(repository, AppenderCreator(direction));
repositoryList.AddOrUpdate(direction, repository, (k, v) => repository);
}
}
static void initRepository()
{
repositoryCreateByDirection(_defaultLogName);
}
static RollingOverThirtyMinutesFileAppender AppenderCreator(string logerDirection)
{
RollingOverThirtyMinutesFileAppender rollingFileAppender = new RollingOverThirtyMinutesFileAppender();
rollingFileAppender.Name = logerDirection;
rollingFileAppender.File = Path.Combine(_defaultPath, logerDirection, "log");
rollingFileAppender.Encoding = System.Text.Encoding.UTF8;
rollingFileAppender.AppendToFile = true;
rollingFileAppender.RollingStyle = RollingFileAppender.RollingMode.Composite;
rollingFileAppender.DatePattern = "\"_\"yyyyMMddHHmm\".log\"";
rollingFileAppender.MaxSizeRollBackups = 1000;
rollingFileAppender.MaximumFileSize = "15MB";
rollingFileAppender.AddFilter(levRangeFilter);
rollingFileAppender.LockingModel = new MinimalLock();
rollingFileAppender.Layout = logLayout;
rollingFileAppender.ActivateOptions();
return rollingFileAppender;
}
public static ILog log
{
get
{
if (!repositoryList.ContainsKey(_defaultLogName))
{
initRepository();
}
return LogManager.GetLogger(repositoryList[_defaultLogName].Name, _defaultPath);
}
}
/// <summary>
/// 允许将日志文件输出到自定义的路径里; D 为 direction 缩写<br/>
/// 路径为日志根目录的相对目录, 不要用完整路径;<br/>
/// 不要用日期或时间创建路径, 以免文件自动删除配置不起效<br/>
/// </summary>
/// <param name="direction"></param>
/// <returns></returns>
public static ILog D(string direction)
{
if (repositoryList.ContainsKey(direction))
{
return LogManager.GetLogger(repositoryList[direction].Name, direction);
}
repositoryCreateByDirection(direction);
return LogManager.GetLogger(repositoryList[direction].Name, direction);
}
/// <summary>
/// 授权日志
/// </summary>
public static ILog AuthorizeDirection
{
get
{
return D("Authorize");
}
}
}
/// <summary>
/// 每隔30分钟创建一个日志文件
/// </summary>
internal class RollingOverThirtyMinutesFileAppender : RollingFileAppender
{
// 间隔时间
const int _intervalMinutes = 30;
private DateTime nextThirtyMinutes;
public RollingOverThirtyMinutesFileAppender()
{
CalcNextThirtyMinutes(DateTime.Now);
}
/// <summary>
/// 计算下一个三十分钟
/// </summary>
/// <param name="time"></param>
private void CalcNextThirtyMinutes(DateTime time)
{
time = time.AddMilliseconds((double)-time.Millisecond);
time = time.AddSeconds((double)-time.Second);
int interNumber = time.Minute / _intervalMinutes;
nextThirtyMinutes = time.AddMinutes((double)-(time.Minute - _intervalMinutes)).AddMinutes(_intervalMinutes * interNumber);
}
protected override void AdjustFileBeforeAppend()
{
DateTime now = DateTime.Now;
if (now >= nextThirtyMinutes)
{
CalcNextThirtyMinutes(now);
base.AdjustFileBeforeAppend();
}
}
}