diff --git a/Tiobon.Core.Common/DB/DbSql/DbInsert.cs b/Tiobon.Core.Common/DB/DbSql/DbInsert.cs index 2bf925e3..ef83ef5a 100644 --- a/Tiobon.Core.Common/DB/DbSql/DbInsert.cs +++ b/Tiobon.Core.Common/DB/DbSql/DbInsert.cs @@ -270,11 +270,11 @@ namespace Tiobon.Core.Common //create_by var createBy = UserContext.Current.User_Id; - Values("CreatedBy", createBy); + Values("CreateBy", createBy); //create_date DateTime createDate = DateTime.Now; - Values("CreatedTime", createDate); + Values("CreateTime", createDate); //create_program //Values("CREATED_PROGRAM", createProgram); diff --git a/Tiobon.Core.Common/Helper/FileHelper.cs b/Tiobon.Core.Common/Helper/FileHelper.cs index e256c653..6b2c3e2d 100644 --- a/Tiobon.Core.Common/Helper/FileHelper.cs +++ b/Tiobon.Core.Common/Helper/FileHelper.cs @@ -73,15 +73,14 @@ namespace Tiobon.Core.Common.Helper /// 可用文件名 public static string GetAvailableFileWithPrefixOrderSize(string folderPath, string prefix, int size = 1 * 1024 * 1024, string ext = ".log") { - var allFiles = new DirectoryInfo(folderPath); - var selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(prefix.ToLower()) && fi.Extension.ToLower() == ext.ToLower() && fi.Length < size).OrderByDescending(d => d.Name).ToList(); - - if (selectFiles.Count > 0) - { - return selectFiles.FirstOrDefault().FullName; - } + //var allFiles = new DirectoryInfo(folderPath); + //var selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(prefix.ToLower()) && fi.Extension.ToLower() == ext.ToLower() && fi.Length < size).OrderByDescending(d => d.Name).ToList(); - return Path.Combine(folderPath, $@"{prefix}_{DateTime.Now.DateToTimeStamp()}.log"); + //if (selectFiles.Count > 0) + //{ + // return selectFiles.FirstOrDefault().FullName; + //} + return Path.Combine(folderPath, $@"{prefix}.log"); } public static string GetAvailableFileNameWithPrefixOrderSize(string _contentRoot, string prefix, int size = 1 * 1024 * 1024, string ext = ".log") { diff --git a/Tiobon.Core.Common/LogHelper/LogContextStatic.cs b/Tiobon.Core.Common/LogHelper/LogContextStatic.cs index 6a8fe04b..1144cfc3 100644 --- a/Tiobon.Core.Common/LogHelper/LogContextStatic.cs +++ b/Tiobon.Core.Common/LogHelper/LogContextStatic.cs @@ -1,6 +1,4 @@ -using System.IO; - -namespace Tiobon.Core.Common.LogHelper; +namespace Tiobon.Core.Common.LogHelper; public class LogContextStatic { @@ -13,7 +11,7 @@ public class LogContextStatic } public static readonly string BaseLogs = "Logs"; - public static readonly string BasePathLogs = @"Logs"; + public static string BasePathLogs { get { return DateTime.Now.ToString("yyyyMMdd"); } } public static readonly string LogSource = "LogSource"; public static readonly string AopSql = "AopSql"; diff --git a/Tiobon.Core.Common/LogHelper/LogLock.cs b/Tiobon.Core.Common/LogHelper/LogLock.cs index 696a73e9..017d0d7e 100644 --- a/Tiobon.Core.Common/LogHelper/LogLock.cs +++ b/Tiobon.Core.Common/LogHelper/LogLock.cs @@ -1,614 +1,627 @@ -using Tiobon.Core.Common.Helper; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; +using Newtonsoft.Json; using System.Text; -using System.Threading; using Serilog; +using Tiobon.Core.Common.Helper; +using Tiobon.Core.Model; +using Tiobon.Core.Common.DB.Dapper; -namespace Tiobon.Core.Common.LogHelper +namespace Tiobon.Core.Common.LogHelper; + +public class LogLock { - public class LogLock + static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim(); + static int WritedCount = 0; + static int FailedCount = 0; + static string _contentRoot = string.Empty; + + public LogLock(string contentPath) { - static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim(); - static int WritedCount = 0; - static int FailedCount = 0; - static string _contentRoot = string.Empty; + _contentRoot = contentPath; + } - public LogLock(string contentPath) + public static void OutLogAOP(string prefix, string traceId, string[] dataParas, bool IsHeader = true) + { + string AppSetingNodeName = "AppSettings"; + string AppSetingName = "LogAOP"; + switch (prefix) { - _contentRoot = contentPath; + case "AOPLog": + AppSetingName = "LogAOP"; + break; + case "AOPLogEx": + AppSetingName = "LogAOP"; + break; + case "RequestIpInfoLog": + AppSetingNodeName = "Middleware"; + AppSetingName = "IPLog"; + break; + case "RecordAccessLogs": + AppSetingNodeName = "Middleware"; + AppSetingName = "RecordAccessLogs"; + break; + case "SqlLog": + AppSetingName = "SqlAOP"; + break; + case "RequestResponseLog": + AppSetingNodeName = "Middleware"; + AppSetingName = "RequestResponseLog"; + break; + default: + break; } - public static void OutLogAOP(string prefix, string traceId, string[] dataParas, bool IsHeader = true) + if (AppSettings.app(new string[] { AppSetingNodeName, AppSetingName, "Enabled" }).ObjToBool()) { - string AppSetingNodeName = "AppSettings"; - string AppSetingName = "LogAOP"; - switch (prefix) + if (AppSettings.app(new string[] { AppSetingNodeName, AppSetingName, "LogToDB", "Enabled" }).ObjToBool()) { - case "AOPLog": - AppSetingName = "LogAOP"; - break; - case "AOPLogEx": - AppSetingName = "LogAOP"; - break; - case "RequestIpInfoLog": - AppSetingNodeName = "Middleware"; - AppSetingName = "IPLog"; - break; - case "RecordAccessLogs": - AppSetingNodeName = "Middleware"; - AppSetingName = "RecordAccessLogs"; - break; - case "SqlLog": - AppSetingName = "SqlAOP"; - break; - case "RequestResponseLog": - AppSetingNodeName = "Middleware"; - AppSetingName = "RequestResponseLog"; - break; - default: - break; + OutSql2LogToDB(prefix, traceId, dataParas, IsHeader); } - if (AppSettings.app(new string[] { AppSetingNodeName, AppSetingName, "Enabled" }).ObjToBool()) + if (AppSettings.app(new string[] { AppSetingNodeName, AppSetingName, "LogToFile", "Enabled" }).ObjToBool()) { - if (AppSettings.app(new string[] { AppSetingNodeName, AppSetingName, "LogToDB", "Enabled" }).ObjToBool()) - { - OutSql2LogToDB(prefix, traceId, dataParas, IsHeader); - } - - if (AppSettings.app(new string[] { AppSetingNodeName, AppSetingName, "LogToFile", "Enabled" }).ObjToBool()) - { - OutSql2LogToFile(prefix, traceId, dataParas, IsHeader); - } + OutSql2LogToFile(prefix, traceId, dataParas, IsHeader); } - - //if (AppSettings.app(new string[] { "AppSettings", "LogFile", "Enabled" }).ObjToBool()) - //{ - // OutSql2LogFile(prefix, dataParas, IsHeader); - //} - //else - //{ - // OutSql2Log(prefix, dataParas, IsHeader); - //} } - public static void OutSql2LogToFile(string prefix, string traceId, string[] dataParas, bool IsHeader = true, bool isWrt = false) - { - try - { - //设置读写锁为写入模式独占资源,其他写入请求需要等待本次写入结束之后才能继续写入 - //注意:长时间持有读线程锁或写线程锁会使其他线程发生饥饿 (starve)。 为了得到最好的性能,需要考虑重新构造应用程序以将写访问的持续时间减少到最小。 - // 从性能方面考虑,请求进入写入模式应该紧跟文件操作之前,在此处进入写入模式仅是为了降低代码复杂度 - // 因进入与退出写入模式应在同一个try finally语句块内,所以在请求进入写入模式之前不能触发异常,否则释放次数大于请求次数将会触发异常 - LogWriteLock.EnterWriteLock(); - - var folderPath = Path.Combine(_contentRoot, "Log"); - if (!Directory.Exists(folderPath)) - { - Directory.CreateDirectory(folderPath); - } - - //string logFilePath = Path.Combine(path, $@"{filename}.log"); - var logFilePath = FileHelper.GetAvailableFileWithPrefixOrderSize(folderPath, prefix); - switch (prefix) - { - case "AOPLog": - AOPLogInfo apiLogAopInfo = JsonConvert.DeserializeObject(dataParas[1]); - //记录被拦截方法信息的日志信息 - var dataIntercept = "" + - $"【操作时间】:{apiLogAopInfo.RequestTime}\r\n" + - $"【当前操作用户】:{apiLogAopInfo.OpUserName} \r\n" + - $"【当前执行方法】:{apiLogAopInfo.RequestMethodName} \r\n" + - $"【携带的参数有】: {apiLogAopInfo.RequestParamsName} \r\n" + - $"【携带的参数JSON】: {apiLogAopInfo.RequestParamsData} \r\n" + - $"【响应时间】:{apiLogAopInfo.ResponseIntervalTime}\r\n" + - $"【执行完成时间】:{apiLogAopInfo.ResponseTime}\r\n" + - $"【执行完成结果】:{apiLogAopInfo.ResponseJsonData}\r\n"; - dataParas = new string[] { dataIntercept }; - break; - case "AOPLogEx": - AOPLogExInfo apiLogAopExInfo = JsonConvert.DeserializeObject(dataParas[1]); - var dataInterceptEx = "" + - $"【操作时间】:{apiLogAopExInfo.ApiLogAopInfo.RequestTime}\r\n" + - $"【当前操作用户】:{apiLogAopExInfo.ApiLogAopInfo.OpUserName} \r\n" + - $"【当前执行方法】:{apiLogAopExInfo.ApiLogAopInfo.RequestMethodName} \r\n" + - $"【携带的参数有】: {apiLogAopExInfo.ApiLogAopInfo.RequestParamsName} \r\n" + - $"【携带的参数JSON】: {apiLogAopExInfo.ApiLogAopInfo.RequestParamsData} \r\n" + - $"【响应时间】:{apiLogAopExInfo.ApiLogAopInfo.ResponseIntervalTime}\r\n" + - $"【执行完成时间】:{apiLogAopExInfo.ApiLogAopInfo.ResponseTime}\r\n" + - $"【执行完成结果】:{apiLogAopExInfo.ApiLogAopInfo.ResponseJsonData}\r\n" + - $"【执行完成异常信息】:方法中出现异常:{apiLogAopExInfo.ExMessage}\r\n" + - $"【执行完成异常】:方法中出现异常:{apiLogAopExInfo.InnerException}\r\n"; - dataParas = new string[] { dataInterceptEx }; - break; - } + //if (AppSettings.app(new string[] { "AppSettings", "LogFile", "Enabled" }).ObjToBool()) + //{ + // OutSql2LogFile(prefix, dataParas, IsHeader); + //} + //else + //{ + // OutSql2Log(prefix, dataParas, IsHeader); + //} + } - var now = DateTime.Now; - string logContent = String.Join("\r\n", dataParas); - if (IsHeader) - { - logContent = ( - "--------------------------------\r\n" + - DateTime.Now + "|\r\n" + - String.Join("\r\n", dataParas) + "\r\n" - ); - } - else - { - logContent = ( - dataParas[1] + ",\r\n" - ); - } + public static void OutSql2LogToFile(string prefix, string traceId, string[] dataParas, bool IsHeader = true, bool isWrt = false) + { + try + { + //设置读写锁为写入模式独占资源,其他写入请求需要等待本次写入结束之后才能继续写入 + //注意:长时间持有读线程锁或写线程锁会使其他线程发生饥饿 (starve)。 为了得到最好的性能,需要考虑重新构造应用程序以将写访问的持续时间减少到最小。 + // 从性能方面考虑,请求进入写入模式应该紧跟文件操作之前,在此处进入写入模式仅是为了降低代码复杂度 + // 因进入与退出写入模式应在同一个try finally语句块内,所以在请求进入写入模式之前不能触发异常,否则释放次数大于请求次数将会触发异常 + LogWriteLock.EnterWriteLock(); - //if (logContent.IsNotEmptyOrNull() && logContent.Length > 500) - //{ - // logContent = logContent.Substring(0, 500) + "\r\n"; - //} - if (isWrt) - { - File.WriteAllText(logFilePath, logContent); - } - else - { - File.AppendAllText(logFilePath, logContent); - } + var folderPath = Path.Combine(_contentRoot, $@"Logs\\{DateTime.Now.ToString("yyyyMMdd")}"); + if (!Directory.Exists(folderPath)) + { + Directory.CreateDirectory(folderPath); + } - WritedCount++; + //string logFilePath = Path.Combine(path, $@"{filename}.log"); + var logFilePath = FileHelper.GetAvailableFileWithPrefixOrderSize(folderPath, prefix); + switch (prefix) + { + case "AOPLog": + AOPLogInfo apiLogAopInfo = JsonConvert.DeserializeObject(dataParas[1]); + //记录被拦截方法信息的日志信息 + var dataIntercept = "" + + $"【操作时间】:{apiLogAopInfo.RequestTime}\r\n" + + $"【当前操作用户】:{apiLogAopInfo.OpUserName} \r\n" + + $"【当前执行方法】:{apiLogAopInfo.RequestMethodName} \r\n" + + $"【携带的参数有】: {apiLogAopInfo.RequestParamsName} \r\n" + + $"【携带的参数JSON】: {apiLogAopInfo.RequestParamsData} \r\n" + + $"【响应时间】:{apiLogAopInfo.ResponseIntervalTime}\r\n" + + $"【执行完成时间】:{apiLogAopInfo.ResponseTime}\r\n" + + $"【执行完成结果】:{apiLogAopInfo.ResponseJsonData}\r\n"; + dataParas = new string[] { dataIntercept }; + break; + case "AOPLogEx": + AOPLogExInfo apiLogAopExInfo = JsonConvert.DeserializeObject(dataParas[1]); + var dataInterceptEx = "" + + $"【操作时间】:{apiLogAopExInfo.ApiLogAopInfo.RequestTime}\r\n" + + $"【当前操作用户】:{apiLogAopExInfo.ApiLogAopInfo.OpUserName} \r\n" + + $"【当前执行方法】:{apiLogAopExInfo.ApiLogAopInfo.RequestMethodName} \r\n" + + $"【携带的参数有】: {apiLogAopExInfo.ApiLogAopInfo.RequestParamsName} \r\n" + + $"【携带的参数JSON】: {apiLogAopExInfo.ApiLogAopInfo.RequestParamsData} \r\n" + + $"【响应时间】:{apiLogAopExInfo.ApiLogAopInfo.ResponseIntervalTime}\r\n" + + $"【执行完成时间】:{apiLogAopExInfo.ApiLogAopInfo.ResponseTime}\r\n" + + $"【执行完成结果】:{apiLogAopExInfo.ApiLogAopInfo.ResponseJsonData}\r\n" + + $"【执行完成异常信息】:方法中出现异常:{apiLogAopExInfo.ExMessage}\r\n" + + $"【执行完成异常】:方法中出现异常:{apiLogAopExInfo.InnerException}\r\n"; + dataParas = new string[] { dataInterceptEx }; + break; } - catch (Exception e) + + var now = DateTime.Now; + string logContent = String.Join("\r\n", dataParas); + if (IsHeader) { - Console.Write(e.Message); - FailedCount++; + logContent = ( + "--------------------------------\r\n" + + DateTime.Now + "|\r\n" + + String.Join("\r\n", dataParas) + "\r\n" + ); } - finally + else { - //退出写入模式,释放资源占用 - //注意:一次请求对应一次释放 - // 若释放次数大于请求次数将会触发异常[写入锁定未经保持即被释放] - // 若请求处理完成后未释放将会触发异常[此模式不下允许以递归方式获取写入锁定] - LogWriteLock.ExitWriteLock(); + logContent = ( + dataParas[1] + ",\r\n" + ); } - } - public static void OutSql2LogToDB(string prefix, string traceId, string[] dataParas, bool IsHeader = true) - { - //log4net.LogicalThreadContext.Properties["LogType"] = prefix; - //log4net.LogicalThreadContext.Properties["TraceId"] = traceId; - //if (dataParas.Length >= 2) + //if (logContent.IsNotEmptyOrNull() && logContent.Length > 500) //{ - // log4net.LogicalThreadContext.Properties["DataType"] = dataParas[0]; + // logContent = logContent.Substring(0, 500) + "\r\n"; //} - - dataParas = dataParas.Skip(1).ToArray(); - - string logContent = String.Join("", dataParas); - if (IsHeader) + if (isWrt) { - logContent = (String.Join("", dataParas)); + File.WriteAllText(logFilePath, logContent); } - - switch (prefix) + else { - //DEBUG | INFO | WARN | ERROR | FATAL - case "AOPLog": - Log.Information(logContent); - break; - case "AOPLogEx": - Log.Error(logContent); - break; - case "RequestIpInfoLog": - //TODO 是否需要Debug输出? - Log.Information(logContent); - break; - case "RecordAccessLogs": - //TODO 是否需要Debug输出? - Log.Information(logContent); - break; - case "SqlLog": - Log.Information(logContent); - break; - case "RequestResponseLog": - //TODO 是否需要Debug输出? - Log.Information(logContent); - break; - default: - break; + File.AppendAllText(logFilePath, logContent); } + + WritedCount++; } + catch (Exception e) + { + Console.Write(e.Message); + FailedCount++; + } + finally + { + //退出写入模式,释放资源占用 + //注意:一次请求对应一次释放 + // 若释放次数大于请求次数将会触发异常[写入锁定未经保持即被释放] + // 若请求处理完成后未释放将会触发异常[此模式不下允许以递归方式获取写入锁定] + LogWriteLock.ExitWriteLock(); + } + } - /// - /// 读取文件内容 - /// - /// 文件夹路径 - /// 文件名 - /// 编码 - /// 读取类型(0:精准,1:前缀模糊) - /// - public static string ReadLog(string folderPath, string fileName, Encoding encode, ReadType readType = ReadType.Accurate, int takeOnlyTop = -1) - { - string s = ""; - try - { - LogWriteLock.EnterReadLock(); + public static void OutSql2LogToDB(string prefix, string traceId, string[] dataParas, bool IsHeader = true) + { + //log4net.LogicalThreadContext.Properties["LogType"] = prefix; + //log4net.LogicalThreadContext.Properties["TraceId"] = traceId; + //if (dataParas.Length >= 2) + //{ + // log4net.LogicalThreadContext.Properties["DataType"] = dataParas[0]; + //} + + dataParas = dataParas.Skip(1).ToArray(); - // 根据文件名读取当前文件内容 - if (readType == ReadType.Accurate) + string logContent = String.Join("", dataParas); + if (IsHeader) + { + logContent = (String.Join("", dataParas)); + } + + switch (prefix) + { + //DEBUG | INFO | WARN | ERROR | FATAL + case "AOPLog": + Log.Information(logContent); + break; + case "AOPLogEx": + Log.Error(logContent); + break; + case "RequestIpInfoLog": + //TODO 是否需要Debug输出? + Log.Information(logContent); + break; + case "RecordAccessLogs": + //TODO 是否需要Debug输出? + Log.Information(logContent); + Task.Factory.StartNew(() => { - var filePath = Path.Combine(folderPath, fileName); - if (!File.Exists(filePath)) + var requestInfo = JsonHelper.JsonToObj(logContent); + if (requestInfo != null && requestInfo.API != "/api/file/upload") { - s = null; - } - else - { - StreamReader f2 = new StreamReader(filePath, encode); - s = f2.ReadToEnd(); - f2.Close(); - f2.Dispose(); + DbInsert di = new DbInsert("Ghre_ApiLog"); + di.Values("UserId", requestInfo.User); + di.Values("IP", requestInfo.IP); + di.Values("Path", requestInfo.API); + di.Values("Method", requestInfo.RequestMethod); + di.Values("RequestData", requestInfo.RequestData); + di.Values("BeginTime", requestInfo.BeginTime); + di.Values("OPTime", requestInfo.OPTime.Replace("ms", null)); + di.Values("Agent", requestInfo.Agent); + DbAccess.ExcuteNonQuery(di.GetSql()); } - } + }); + break; + case "SqlLog": + Log.Information(logContent); + break; + case "RequestResponseLog": + //TODO 是否需要Debug输出? + Log.Information(logContent); + break; + default: + break; + } + } + + /// + /// 读取文件内容 + /// + /// 文件夹路径 + /// 文件名 + /// 编码 + /// 读取类型(0:精准,1:前缀模糊) + /// + public static string ReadLog(string folderPath, string fileName, Encoding encode, ReadType readType = ReadType.Accurate, int takeOnlyTop = -1) + { + string s = ""; + try + { + LogWriteLock.EnterReadLock(); - // 根据前缀读取所有文件内容 - if (readType == ReadType.Prefix) + // 根据文件名读取当前文件内容 + if (readType == ReadType.Accurate) + { + var filePath = Path.Combine(folderPath, fileName); + if (!File.Exists(filePath)) { - var allFiles = new DirectoryInfo(folderPath); - var selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(fileName.ToLower())).ToList(); + s = null; + } + else + { + StreamReader f2 = new StreamReader(filePath, encode); + s = f2.ReadToEnd(); + f2.Close(); + f2.Dispose(); + } + } - selectFiles = takeOnlyTop > 0 ? selectFiles.OrderByDescending(d => d.Name).Take(takeOnlyTop).ToList() : selectFiles; + // 根据前缀读取所有文件内容 + if (readType == ReadType.Prefix) + { + var allFiles = new DirectoryInfo(folderPath); + var selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(fileName.ToLower())).ToList(); - foreach (var item in selectFiles) - { - if (File.Exists(item.FullName)) - { - StreamReader f2 = new StreamReader(item.FullName, encode); - s += f2.ReadToEnd(); - f2.Close(); - f2.Dispose(); - } - } - } + selectFiles = takeOnlyTop > 0 ? selectFiles.OrderByDescending(d => d.Name).Take(takeOnlyTop).ToList() : selectFiles; - // 根据前缀读取 最新文件 时间倒叙 - if (readType == ReadType.PrefixLatest) + foreach (var item in selectFiles) { - var allFiles = new DirectoryInfo(folderPath); - var selectLastestFile = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(fileName.ToLower())).OrderByDescending(d => d.Name).FirstOrDefault(); - - if (selectLastestFile != null && File.Exists(selectLastestFile.FullName)) + if (File.Exists(item.FullName)) { - StreamReader f2 = new StreamReader(selectLastestFile.FullName, encode); - s = f2.ReadToEnd(); + StreamReader f2 = new StreamReader(item.FullName, encode); + s += f2.ReadToEnd(); f2.Close(); f2.Dispose(); } } } - catch (Exception) - { - FailedCount++; - } - finally + + // 根据前缀读取 最新文件 时间倒叙 + if (readType == ReadType.PrefixLatest) { - LogWriteLock.ExitReadLock(); - } + var allFiles = new DirectoryInfo(folderPath); + var selectLastestFile = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(fileName.ToLower())).OrderByDescending(d => d.Name).FirstOrDefault(); - return s; + if (selectLastestFile != null && File.Exists(selectLastestFile.FullName)) + { + StreamReader f2 = new StreamReader(selectLastestFile.FullName, encode); + s = f2.ReadToEnd(); + f2.Close(); + f2.Dispose(); + } + } + } + catch (Exception) + { + FailedCount++; + } + finally + { + LogWriteLock.ExitReadLock(); } - private static List GetRequestInfo(ReadType readType) + return s; + } + + private static List GetRequestInfo(ReadType readType) + { + List requestInfos = new(); + var accessLogs = ReadLog(Path.Combine(_contentRoot, "Log"), "RequestIpInfoLog_", Encoding.UTF8, readType).ObjToString(); + try { - List requestInfos = new(); - var accessLogs = ReadLog(Path.Combine(_contentRoot, "Log"), "RequestIpInfoLog_", Encoding.UTF8, readType).ObjToString(); - try - { - return JsonConvert.DeserializeObject>("[" + accessLogs + "]"); - } - catch (Exception) + return JsonConvert.DeserializeObject>("[" + accessLogs + "]"); + } + catch (Exception) + { + var accLogArr = accessLogs.Split("\r\n"); + foreach (var item in accLogArr) { - var accLogArr = accessLogs.Split("\r\n"); - foreach (var item in accLogArr) + if (item.ObjToString() != "") { - if (item.ObjToString() != "") + try + { + var accItem = JsonConvert.DeserializeObject(item.TrimEnd(',')); + requestInfos.Add(accItem); + } + catch (Exception) { - try - { - var accItem = JsonConvert.DeserializeObject(item.TrimEnd(',')); - requestInfos.Add(accItem); - } - catch (Exception) - { - } } } } - - return requestInfos; } + return requestInfos; + } - public static List GetLogData() - { - List aopLogs = new List(); - List excLogs = new List(); - List sqlLogs = new List(); - List reqresLogs = new List(); - try - { - var aoplogContent = ReadLog(Path.Combine(_contentRoot, "Log"), "AOPLog_", Encoding.UTF8, ReadType.Prefix); + public static List GetLogData() + { + List aopLogs = new List(); + List excLogs = new List(); + List sqlLogs = new List(); + List reqresLogs = new List(); - if (!string.IsNullOrEmpty(aoplogContent)) - { - aopLogs = aoplogContent.Split("--------------------------------") - .Where(d => !string.IsNullOrEmpty(d) && d != "\n" && d != "\r\n") - .Select(d => new LogInfo - { - Datetime = d.Split("|")[0].ObjToDate(), - Content = d.Split("|")[1]?.Replace("\r\n", "
"), - LogColor = "AOP", - }).ToList(); - } - } - catch (Exception) + try + { + var aoplogContent = ReadLog(Path.Combine(_contentRoot, "Log"), "AOPLog_", Encoding.UTF8, ReadType.Prefix); + + if (!string.IsNullOrEmpty(aoplogContent)) { + aopLogs = aoplogContent.Split("--------------------------------") + .Where(d => !string.IsNullOrEmpty(d) && d != "\n" && d != "\r\n") + .Select(d => new LogInfo + { + Datetime = d.Split("|")[0].ObjToDate(), + Content = d.Split("|")[1]?.Replace("\r\n", "
"), + LogColor = "AOP", + }).ToList(); } + } + catch (Exception) + { + } - try - { - var exclogContent = ReadLog(Path.Combine(_contentRoot, "Log"), $"GlobalExceptionLogs_{DateTime.Now.ToString("yyyMMdd")}.log", Encoding.UTF8); + try + { + var exclogContent = ReadLog(Path.Combine(_contentRoot, "Log"), $"GlobalExceptionLogs_{DateTime.Now.ToString("yyyMMdd")}.log", Encoding.UTF8); - if (!string.IsNullOrEmpty(exclogContent)) - { - excLogs = exclogContent.Split("--------------------------------") - .Where(d => !string.IsNullOrEmpty(d) && d != "\n" && d != "\r\n") - .Select(d => new LogInfo - { - Datetime = (d.Split("|")[0]).Split(',')[0].ObjToDate(), - Content = d.Split("|")[1]?.Replace("\r\n", "
"), - LogColor = "EXC", - Import = 9, - }).ToList(); - } - } - catch (Exception) + if (!string.IsNullOrEmpty(exclogContent)) { + excLogs = exclogContent.Split("--------------------------------") + .Where(d => !string.IsNullOrEmpty(d) && d != "\n" && d != "\r\n") + .Select(d => new LogInfo + { + Datetime = (d.Split("|")[0]).Split(',')[0].ObjToDate(), + Content = d.Split("|")[1]?.Replace("\r\n", "
"), + LogColor = "EXC", + Import = 9, + }).ToList(); } + } + catch (Exception) + { + } - try - { - var sqllogContent = ReadLog(Path.Combine(_contentRoot, "Log"), "SqlLog_", Encoding.UTF8, ReadType.PrefixLatest); + try + { + var sqllogContent = ReadLog(Path.Combine(_contentRoot, "Log"), "SqlLog_", Encoding.UTF8, ReadType.PrefixLatest); - if (!string.IsNullOrEmpty(sqllogContent)) - { - sqlLogs = sqllogContent.Split("--------------------------------") - .Where(d => !string.IsNullOrEmpty(d) && d != "\n" && d != "\r\n") - .Select(d => new LogInfo - { - Datetime = d.Split("|")[0].ObjToDate(), - Content = d.Split("|")[1]?.Replace("\r\n", "
"), - LogColor = "SQL", - }).ToList(); - } - } - catch (Exception) + if (!string.IsNullOrEmpty(sqllogContent)) { + sqlLogs = sqllogContent.Split("--------------------------------") + .Where(d => !string.IsNullOrEmpty(d) && d != "\n" && d != "\r\n") + .Select(d => new LogInfo + { + Datetime = d.Split("|")[0].ObjToDate(), + Content = d.Split("|")[1]?.Replace("\r\n", "
"), + LogColor = "SQL", + }).ToList(); } + } + catch (Exception) + { + } - //try - //{ - // reqresLogs = ReadLog(Path.Combine(_contentRoot, "Log", "RequestResponseLog.log"), Encoding.UTF8)? - // .Split("--------------------------------") - // .Where(d => !string.IsNullOrEmpty(d) && d != "\n" && d != "\r\n") - // .Select(d => new LogInfo - // { - // Datetime = d.Split("|")[0].ObjToDate(), - // Content = d.Split("|")[1]?.Replace("\r\n", "
"), - // LogColor = "ReqRes", - // }).ToList(); - //} - //catch (Exception) - //{ - //} + //try + //{ + // reqresLogs = ReadLog(Path.Combine(_contentRoot, "Log", "RequestResponseLog.log"), Encoding.UTF8)? + // .Split("--------------------------------") + // .Where(d => !string.IsNullOrEmpty(d) && d != "\n" && d != "\r\n") + // .Select(d => new LogInfo + // { + // Datetime = d.Split("|")[0].ObjToDate(), + // Content = d.Split("|")[1]?.Replace("\r\n", "
"), + // LogColor = "ReqRes", + // }).ToList(); + //} + //catch (Exception) + //{ + //} + + try + { + var Logs = GetRequestInfo(ReadType.PrefixLatest); - try + Logs = Logs.Where(d => d.Datetime.ObjToDate() >= DateTime.Today).ToList(); + + reqresLogs = Logs.Select(d => new LogInfo { - var Logs = GetRequestInfo(ReadType.PrefixLatest); + Datetime = d.Datetime.ObjToDate(), + Content = $"IP:{d.Ip}
{d.Url}", + LogColor = "ReqRes", + }).ToList(); + } + catch (Exception) + { + } - Logs = Logs.Where(d => d.Datetime.ObjToDate() >= DateTime.Today).ToList(); + if (excLogs != null) + { + aopLogs.AddRange(excLogs); + } - reqresLogs = Logs.Select(d => new LogInfo - { - Datetime = d.Datetime.ObjToDate(), - Content = $"IP:{d.Ip}
{d.Url}", - LogColor = "ReqRes", - }).ToList(); - } - catch (Exception) - { - } + if (sqlLogs != null) + { + aopLogs.AddRange(sqlLogs); + } - if (excLogs != null) - { - aopLogs.AddRange(excLogs); - } + if (reqresLogs != null) + { + aopLogs.AddRange(reqresLogs); + } - if (sqlLogs != null) - { - aopLogs.AddRange(sqlLogs); - } + aopLogs = aopLogs.OrderByDescending(d => d.Import).ThenByDescending(d => d.Datetime).Take(100).ToList(); - if (reqresLogs != null) - { - aopLogs.AddRange(reqresLogs); - } + return aopLogs; + } - aopLogs = aopLogs.OrderByDescending(d => d.Import).ThenByDescending(d => d.Datetime).Take(100).ToList(); - return aopLogs; - } + public static RequestApiWeekView RequestApiinfoByWeek() + { + List Logs = new List(); + List apiWeeks = new List(); + string apiWeeksJson = string.Empty; + List columns = new List(); + columns.Add("日期"); - public static RequestApiWeekView RequestApiinfoByWeek() + try { - List Logs = new List(); - List apiWeeks = new List(); - string apiWeeksJson = string.Empty; - List columns = new List(); - columns.Add("日期"); + Logs = GetRequestInfo(ReadType.Prefix); + apiWeeks = (from n in Logs + group n by new { n.Week, n.Url } + into g + select new ApiWeek + { + week = g.Key.Week, + url = g.Key.Url, + count = g.Count(), + }).ToList(); - try - { - Logs = GetRequestInfo(ReadType.Prefix); - - apiWeeks = (from n in Logs - group n by new { n.Week, n.Url } - into g - select new ApiWeek - { - week = g.Key.Week, - url = g.Key.Url, - count = g.Count(), - }).ToList(); - - //apiWeeks = apiWeeks.OrderByDescending(d => d.count).Take(8).ToList(); - } - catch (Exception) - { - } + //apiWeeks = apiWeeks.OrderByDescending(d => d.count).Take(8).ToList(); + } + catch (Exception) + { + } - StringBuilder jsonBuilder = new StringBuilder(); - jsonBuilder.Append("["); + StringBuilder jsonBuilder = new StringBuilder(); + jsonBuilder.Append("["); - var weeks = apiWeeks.GroupBy(x => new { x.week }).Select(s => s.First()).ToList(); - foreach (var week in weeks) - { - var apiweeksCurrentWeek = apiWeeks.Where(d => d.week == week.week).OrderByDescending(d => d.count).Take(5).ToList(); - jsonBuilder.Append("{"); + var weeks = apiWeeks.GroupBy(x => new { x.week }).Select(s => s.First()).ToList(); + foreach (var week in weeks) + { + var apiweeksCurrentWeek = apiWeeks.Where(d => d.week == week.week).OrderByDescending(d => d.count).Take(5).ToList(); + jsonBuilder.Append("{"); + + jsonBuilder.Append("\""); + jsonBuilder.Append("日期"); + jsonBuilder.Append("\":\""); + jsonBuilder.Append(week.week); + jsonBuilder.Append("\","); + foreach (var item in apiweeksCurrentWeek) + { + columns.Add(item.url); jsonBuilder.Append("\""); - jsonBuilder.Append("日期"); + jsonBuilder.Append(item.url); jsonBuilder.Append("\":\""); - jsonBuilder.Append(week.week); + jsonBuilder.Append(item.count); jsonBuilder.Append("\","); - - foreach (var item in apiweeksCurrentWeek) - { - columns.Add(item.url); - jsonBuilder.Append("\""); - jsonBuilder.Append(item.url); - jsonBuilder.Append("\":\""); - jsonBuilder.Append(item.count); - jsonBuilder.Append("\","); - } - - if (apiweeksCurrentWeek.Count > 0) - { - jsonBuilder.Remove(jsonBuilder.Length - 1, 1); - } - - jsonBuilder.Append("},"); } - if (weeks.Count > 0) + if (apiweeksCurrentWeek.Count > 0) { jsonBuilder.Remove(jsonBuilder.Length - 1, 1); } - jsonBuilder.Append("]"); - - //columns.AddRange(apiWeeks.OrderByDescending(d => d.count).Take(8).Select(d => d.url).ToList()); - columns = columns.Distinct().ToList(); - - return new RequestApiWeekView() - { - columns = columns, - rows = jsonBuilder.ToString(), - }; + jsonBuilder.Append("},"); } - public static AccessApiDateView AccessApiByDate() + if (weeks.Count > 0) { - List Logs = new List(); - List apiDates = new List(); - try - { - Logs = GetRequestInfo(ReadType.Prefix); - - apiDates = (from n in Logs - group n by new { n.Date } - into g - select new ApiDate - { - date = g.Key.Date, - count = g.Count(), - }).ToList(); - - apiDates = apiDates.OrderByDescending(d => d.date).Take(7).ToList(); - } - catch (Exception) - { - } - - return new AccessApiDateView() - { - columns = new string[] { "date", "count" }, - rows = apiDates.OrderBy(d => d.date).ToList(), - }; + jsonBuilder.Remove(jsonBuilder.Length - 1, 1); } - public static AccessApiDateView AccessApiByHour() + jsonBuilder.Append("]"); + + //columns.AddRange(apiWeeks.OrderByDescending(d => d.count).Take(8).Select(d => d.url).ToList()); + columns = columns.Distinct().ToList(); + + return new RequestApiWeekView() { - List Logs = new List(); - List apiDates = new List(); - try - { - Logs = GetRequestInfo(ReadType.Prefix); - - apiDates = (from n in Logs - where n.Datetime.ObjToDate() >= DateTime.Today - group n by new { hour = n.Datetime.ObjToDate().Hour } - into g - select new ApiDate - { - date = g.Key.hour.ToString("00"), - count = g.Count(), - }).ToList(); - - apiDates = apiDates.OrderBy(d => d.date).Take(24).ToList(); - } - catch (Exception) - { - } + columns = columns, + rows = jsonBuilder.ToString(), + }; + } - return new AccessApiDateView() - { - columns = new string[] { "date", "count" }, - rows = apiDates, - }; + public static AccessApiDateView AccessApiByDate() + { + List Logs = new List(); + List apiDates = new List(); + try + { + Logs = GetRequestInfo(ReadType.Prefix); + + apiDates = (from n in Logs + group n by new { n.Date } + into g + select new ApiDate + { + date = g.Key.Date, + count = g.Count(), + }).ToList(); + + apiDates = apiDates.OrderByDescending(d => d.date).Take(7).ToList(); } + catch (Exception) + { + } + + return new AccessApiDateView() + { + columns = new string[] { "date", "count" }, + rows = apiDates.OrderBy(d => d.date).ToList(), + }; } - public enum ReadType + public static AccessApiDateView AccessApiByHour() { - /// - /// 精确查找一个 - /// - Accurate, - - /// - /// 指定前缀,模糊查找全部 - /// - Prefix, - - /// - /// 指定前缀,最新一个文件 - /// - PrefixLatest + List Logs = new List(); + List apiDates = new List(); + try + { + Logs = GetRequestInfo(ReadType.Prefix); + + apiDates = (from n in Logs + where n.Datetime.ObjToDate() >= DateTime.Today + group n by new { hour = n.Datetime.ObjToDate().Hour } + into g + select new ApiDate + { + date = g.Key.hour.ToString("00"), + count = g.Count(), + }).ToList(); + + apiDates = apiDates.OrderBy(d => d.date).Take(24).ToList(); + } + catch (Exception) + { + } + + return new AccessApiDateView() + { + columns = new string[] { "date", "count" }, + rows = apiDates, + }; } +} + +public enum ReadType +{ + /// + /// 精确查找一个 + /// + Accurate, + + /// + /// 指定前缀,模糊查找全部 + /// + Prefix, + + /// + /// 指定前缀,最新一个文件 + /// + PrefixLatest } \ No newline at end of file diff --git a/Tiobon.Core.Extensions/Middlewares/RecordAccessLogsMiddleware.cs b/Tiobon.Core.Extensions/Middlewares/RecordAccessLogsMiddleware.cs index c43b61e6..6a5eb871 100644 --- a/Tiobon.Core.Extensions/Middlewares/RecordAccessLogsMiddleware.cs +++ b/Tiobon.Core.Extensions/Middlewares/RecordAccessLogsMiddleware.cs @@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Newtonsoft.Json; +using Tiobon.Core.Model; namespace Tiobon.Core.Extensions.Middlewares { @@ -122,15 +123,4 @@ namespace Tiobon.Core.Extensions.Middlewares } - public class UserAccessModel - { - public string User { get; set; } - public string IP { get; set; } - public string API { get; set; } - public string BeginTime { get; set; } - public string OPTime { get; set; } - public string RequestMethod { get; set; } - public string RequestData { get; set; } - public string Agent { get; set; } - } } \ No newline at end of file diff --git a/Tiobon.Core.Model/ViewModels/UserAccessModel.cs b/Tiobon.Core.Model/ViewModels/UserAccessModel.cs new file mode 100644 index 00000000..264b7f51 --- /dev/null +++ b/Tiobon.Core.Model/ViewModels/UserAccessModel.cs @@ -0,0 +1,14 @@ +namespace Tiobon.Core.Model; + + +public class UserAccessModel +{ + public string User { get; set; } + public string IP { get; set; } + public string API { get; set; } + public string BeginTime { get; set; } + public string OPTime { get; set; } + public string RequestMethod { get; set; } + public string RequestData { get; set; } + public string Agent { get; set; } +} \ No newline at end of file