1
hutongqing
2024-12-13 4261951c50fadb3cdac395086974a715487bab82
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_Core/LogHelper/Logger.cs
@@ -1,10 +1,9 @@

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Http;
using SqlSugar;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -15,138 +14,191 @@
namespace WIDESEA_Core.LogHelper
{
    public class Logger
    public static class Logger
    {
        /// <summary>
        /// å†™å…¥è°ƒè¯•日志
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="msg"></param>
        public void WriteDebug(string fileName, string msg)
        public static ConcurrentQueue<dynamic> loggerQueueData = new ConcurrentQueue<dynamic>();
        static Logger()
        {
            if (AppSettings.Get(new string[] { "LogDeubgEnable" }).ObjToBool())
            Task.Run(() =>
            {
                StringBuilder builder = new StringBuilder(msg);
                builder.Append(Environment.NewLine);
                builder.Append(Environment.NewLine);
                WriteLogToFile($"Debug_{fileName}", builder.ToString());
            }
                StartWriteLog();
            });
        }
        /// <summary>
        /// å†™å…¥ä¿¡æ¯æ—¥å¿—
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="msg"></param>
        public void WriteInfo(string fileName, string msg)
        static void StartWriteLog()
        {
            StringBuilder builder = new StringBuilder(msg);
            builder.Append(Environment.NewLine);
            builder.Append(Environment.NewLine);
            WriteLogToFile($"Info_{fileName}", builder.ToString());
        }
        /// <summary>
        /// å†™å…¥é”™è¯¯æ—¥å¿—
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="msg"></param>
        /// <param name="ex"></param>
        public void WriteError(string fileName, string msg, Exception ex)
        {
            StringBuilder builder = new StringBuilder(msg);
            builder.Append(Environment.NewLine);
            builder.Append("错误信息:");
            builder.Append(ex.Message);
            builder.Append(Environment.NewLine);
            builder.Append("错误源:");
            builder.Append(ex.Source);
            builder.Append(Environment.NewLine);
            builder.Append("错误堆栈:");
            builder.Append(ex.StackTrace);
            builder.Append(Environment.NewLine);
            builder.Append("错误类型:");
            builder.Append(ex.GetType().ToString());
            builder.Append(Environment.NewLine);
            builder.Append("错误方法:");
            builder.Append(ex.TargetSite?.ToString());
            builder.Append(Environment.NewLine);
            builder.Append(Environment.NewLine);
            WriteLogToFile($"Error_{fileName}", builder.ToString());
        }
        ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim();
        string folderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"Log\\{DateTime.Now.ToString("yyyy-MM-dd")}");
        private void WriteLogToFile(string fileName, string log)
            DataTable queueTable = CreateEmptyTable();
            while (true)
        {
            try
            {
                // è¿›å…¥å†™é”
                LogWriteLock.EnterWriteLock();
                    //如果队列中有数据且队列表中的行数小于500,则将队列中的数据写入队列表
                    if (loggerQueueData.Count() > 0 && queueTable.Rows.Count < 500)
                    {
                        DequeueToTable(queueTable); continue;
                    }
                    //每5秒写一次数据
                    Thread.Sleep(5000);
                // å¦‚果文件夹不存在,则创建文件夹
                if (!Directory.Exists(folderPath))
                {
                    Directory.CreateDirectory(folderPath);
                }
                // èŽ·å–æ—¥å¿—æ–‡ä»¶è·¯å¾„
                string logFilePath = Path.Combine(folderPath, GetLastAccessFileName(fileName));
                // èŽ·å–å½“å‰æ—¶é—´
                DateTime now = DateTime.Now;
                // æž„造日志内容
                string logContent = $"【{now}】{Environment.NewLine}{log}";
                    //如果队列表中的行数为0,则跳过本次循环
                    if (queueTable.Rows.Count == 0) { continue; }
                // å°†æ—¥å¿—内容追加到日志文件中
                File.AppendAllText(logFilePath, logContent);
            }
            catch { }
            finally
                    //创建SqlSugarClient对象,用于连接数据库
                    SqlSugarClient sugarClient = new SqlSugarClient(new ConnectionConfig()
            {
                // é€€å‡ºå†™é”
                LogWriteLock.ExitWriteLock();
            }
        }
        int size = 10 * 1024 * 1024;
        string ext = ".log";
        private string GetLogFilePath(string folderPath, string fileName)
        {
            // èŽ·å–æŒ‡å®šæ–‡ä»¶å¤¹ä¸‹çš„æ‰€æœ‰æ–‡ä»¶
            var allFiles = new DirectoryInfo(folderPath);
            // èŽ·å–ç¬¦åˆæ¡ä»¶çš„æ–‡ä»¶ï¼ŒæŒ‰æ–‡ä»¶åé™åºæŽ’åˆ—
            var selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(fileName.ToLower()) && fi.Extension.ToLower() == ext.ToLower() && fi.Length < size).OrderByDescending(d => d.Name).ToList();
                        ConnectionString = DBContext.GetMainConnectionDb().Connection,
                        IsAutoCloseConnection = true,
                        DbType = MainDb.DbType,
                    });
            FileInfo? file = selectFiles.FirstOrDefault();
            // å¦‚果有符合条件的文件,返回第一个文件的完整路径
            if (file != null)
            {
                return file.FullName;
            }
                    //将队列表中的数据批量插入数据库
                    int rows = sugarClient.Fastest<DataTable>().AS("Sys_Log").BulkCopy(queueTable);
            // å¦‚果没有符合条件的文件,返回一个新的文件路径,文件名为原文件名加上当前时间
            return Path.Combine(folderPath, $@"{fileName}_{DateTime.Now.ToString("HH-mm-ss")}.log");
                    //清空队列表
                    queueTable.Clear();
        }
        private string GetLastAccessFileName(string fileName)
                catch (Exception ex)
        {
            foreach (var m in GetExistLogFileNames(fileName))
            {
                FileInfo fileInfo = new FileInfo(m);
                if (fileInfo.Length < size)
                {
                    return m;
                    //打印异常信息
                    Console.WriteLine(ex.ToString());
                }
                }
            }
            // è¿”回一个新的默认当前时间的日志名称
            return $@"{fileName}_{DateTime.Now.ToString("HH-mm-ss")}.log";
        private static void DequeueToTable(DataTable queueTable)
        {
            loggerQueueData.TryDequeue(out dynamic log);
            if (log != null)
            {
                DataRow row = queueTable.NewRow();
                // å¦‚æžœlog的BeginDate为空或者BeginDate的年份小于2010,则将BeginDate设置为当前时间
                if (log.BeginDate == null || log.BeginDate?.Year < 2010)
                {
                    log.BeginDate = DateTime.Now;
                }
                // å¦‚æžœlog的EndDate为空,则将EndDate设置为当前时间
                if (log.EndDate == null)
                {
                    log.EndDate = DateTime.Now;
                }
                //  row["Id"] = log.Id;
                // å°†RequestParam中的换行符替换为空字符串
                row["RequestParam"] = log.RequestParam?.Replace("\r\n", "");
                // å°†ResponseParam中的换行符替换为空字符串
                row["ResponseParam"] = log.ResponseParam?.Replace("\r\n", "");
                //row["Success"] = log.Success ?? -1;
                // å°†BeginDate设置为log的BeginDate
                row["BeginDate"] = log.BeginDate;
                // å°†EndDate设置为log的EndDate
                row["EndDate"] = log.EndDate;
                // è®¡ç®—ElapsedTime,即EndDate减去BeginDate的毫秒数
                row["ElapsedTime"] = ((DateTime)log.EndDate - (DateTime)log.BeginDate).TotalMilliseconds;
                // å°†UserIP设置为log的UserIP
                row["UserIP"] = log.UserIP;
                // å°†Url设置为log的Url
                row["Url"] = log.Url;
                // å¦‚æžœlog的UserId为空,则将UserId设置为-1,否则设置为log的UserId
                row["UserId"] = log.UserId ?? -1;
                // å°†UserName设置为log的UserName
                row["UserName"] = log.UserName;
                // å°†row添加到queueTable中
                queueTable.Rows.Add(row);
            }
        }
        private string[] GetExistLogFileNames(string fileName)
        private static DataTable CreateEmptyTable()
        {
            string[] fileNames = Directory.GetFiles(folderPath, fileName + "*.log");
            return fileNames;
            DataTable queueTable = new DataTable();
            queueTable.Columns.Add("BeginDate", Type.GetType("System.DateTime"));
            queueTable.Columns.Add("ElapsedTime", Type.GetType("System.Int32"));
            queueTable.Columns.Add("EndDate", Type.GetType("System.DateTime"));
            queueTable.Columns.Add("RequestParam", typeof(string));
            queueTable.Columns.Add("ResponseParam", typeof(string));
            //queueTable.Columns.Add("Success", Type.GetType("System.Int32"));
            queueTable.Columns.Add("Url", typeof(string));
            queueTable.Columns.Add("UserIP", typeof(string));
            queueTable.Columns.Add("UserName", typeof(string));
            queueTable.Columns.Add("UserId", Type.GetType("System.Int32"));
            //queueTable.Columns.Add("LogType", typeof(string));
            //queueTable.Columns.Add("ExceptionInfo", typeof(string));
            //queueTable.Columns.Add("ServiceIP", typeof(string));
            //queueTable.Columns.Add("BrowserType", typeof(string));
            //queueTable.Columns.Add("Role_Id", Type.GetType("System.Int32"));
            return queueTable;
        }
        public static void Add(string requestParameter, string responseParameter)
        {
            dynamic log = null;
            try
            {
                //获取当前HttpContext
                HttpContext context = App.HttpContext;
                //如果HttpContext为空,则返回
                if (context == null)
                {
                    return;
                }
                //如果请求方法为OPTIONS,则返回
                if (context.Request.Method == "OPTIONS") return;
                //获取RequestLogModel实例
                RequestLogModel logModel = (context.RequestServices.GetService(typeof(RequestLogModel)) as RequestLogModel) ?? new RequestLogModel { RequestDate = DateTime.Now };
                //获取当前用户
                IUser user = App.User;
                //创建日志对象
                log = new
                {
                    //请求开始时间
                    BeginDate = logModel.RequestDate,
                    //请求结束时间
                    EndDate = DateTime.Now,
                    //请求参数
                    RequestParam = requestParameter,
                    //响应参数
                    ResponseParam = responseParameter,
                    //请求URL
                    Url = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase + context.Request.Path,
                    //客户端IP
                    UserIP = GetClientIP(context)?.Replace("::ffff:", "").Replace("::1", "127.0.0.1"),
                    //用户ID
                    UserId = user.UserId,
                    //用户名
                    UserName = user.UserName
                };
            }
            catch (Exception exception)
            {
                //如果发生异常,则创建日志对象
                log = log ?? new
                {
                    //请求开始时间
                    BeginDate = DateTime.Now,
                    //请求结束时间
                    EndDate = DateTime.Now,
                    //请求参数
                    RequestParam = requestParameter,
                    //响应参数
                    ResponseParam = responseParameter,
                };
            }
            //添加系统日志
            loggerQueueData.Enqueue(log);
        }
        public static string GetClientIP(HttpContext context)
        {
            // èŽ·å–è¯·æ±‚å¤´ä¸­çš„X-Forwarded-For字段,并将其转换为字符串
            var ip = context.Request.Headers["X-Forwarded-For"].ObjToString();
            // å¦‚æžœX-Forwarded-For字段为空,则获取远程IP地址
            if (string.IsNullOrEmpty(ip))
            {
                ip = context.Connection.RemoteIpAddress.ObjToString();
            }
            // è¿”回IP地址
            return ip;
        }
    }
}