林豪 左 3 lat temu
rodzic
commit
99bb46c628

+ 179 - 0
WCS.Core/Log/InfoLog.cs

@@ -0,0 +1,179 @@
+using System.Collections.Generic;
+
+namespace Log
+{
+    /// <summary>
+    /// 信息日志
+    /// </summary>
+    public class InfoLog : ILogType
+    {
+        /// <summary>
+        /// 日志名称
+        /// </summary>
+        public string LogName => "Info";
+
+        /// <summary>
+        /// 信息日志
+        /// </summary>
+        public static ILogType Log { get; set; }
+
+        /// <summary>
+        /// 日志子项集合
+        /// </summary>
+        public Dictionary<string, string> SubLogNames { get; set; }
+
+        static InfoLog()
+        {
+            Log ??= new InfoLog();
+        }
+
+        public InfoLog()
+        {
+            SubLogNames = new Dictionary<string, string>
+            {
+                ["INFO"] = "Info"
+            };
+            LogHelper.Init(this);
+        }
+
+        /// <summary>
+        /// 系统执行信息 
+        /// </summary>
+        /// <param name="msg"></param>
+        public static void INFO_INIT(string msg)
+        {
+            Log.Info(msg, "INFO_INIT");
+        }
+
+        /// <summary>
+        /// 系统执行信息
+        /// </summary>
+        /// <param name="msg"></param>
+        public static void INFO_SRMALARM(string msg)
+        {
+            Log.Info(msg, "INFO_SRMALARM");
+        }
+
+        /// <summary>
+        /// 系统执行信息  基本检查条件不满足时记录
+        /// </summary>
+        /// <param name="msg"></param>
+        public static void INFO_INFO(string msg)
+        {
+            Log.Info(msg, "INFO_INFO");
+        }
+
+        /// <summary>
+        /// 系统执行错误
+        /// </summary>
+        /// <param name="msg"></param>
+        public static void INFO_ERROR(string msg)
+        {
+            Log.Error(msg, "INFO_ERROR");
+            //Console.WriteLine(msg);
+        }
+
+        /// <summary>
+        /// 系统执行警告 所有一直错误都归类为警告
+        /// </summary>
+        /// <param name="msg"></param>
+        public static void INFO_WARN(string msg)
+        {
+            Log.Warn(msg, "INFO_WARN");
+            //Console.WriteLine(msg);
+        }
+
+        /// <summary>
+        /// 系统执行警告 所有一直错误都归类为警告,存入数据库
+        /// </summary>
+        /// <param name="msg">错误内容</param>
+        /// <param name="code">设备</param>
+        public static void INFO_WarnDb(string msg, string code)
+        {
+            Log.Warn(msg, "INFO_WARN");
+            //WCS.Service.Helpers.LogHelper.AddWCS_EXCEPTION(msg, code, type.ToString());
+            //WMS.TaskException(code, msg);
+        }
+
+        /// <summary>
+        /// 堆垛机写入记录
+        /// </summary>
+        /// <param name="msg"></param>
+        public static void INFO_SRMINFO(string msg)
+        {
+            Log.Info(msg, "INFO_SRMINFO");
+        }
+
+        /// <summary>
+        /// 任务状态更新记录
+        /// </summary>
+        /// <param name="msg"></param>
+        public static void INFO_SYTASKSTATUS(string msg)
+        {
+            Log.Info(msg, "INFO_SYTASKSTATUS");
+        }
+
+        /// <summary>
+        /// WMS请求记录
+        /// </summary>
+        /// <param name="msg"></param>
+        public static void INFO_WMSREQUEST(string msg)
+        {
+            Log.Info(msg, "INFO_WMSREQUEST");
+        }
+
+        /// <summary>
+        /// PLC读取记录
+        /// </summary>
+        /// <param name="msg"></param>
+        public static void INFO_PLCREADLOG(string msg)
+        {
+            Log.Info(msg, "INFO_PLCREADLOG");
+        }
+
+        /// <summary>
+        /// 计时器
+        /// </summary>
+        /// <param name="msg"></param>
+        public static void INFO_TIMING(string msg)
+        {
+            Log.Info(msg, "INFO_TIMING");
+        }
+
+        /// <summary>
+        /// WCS异常上抛记录
+        /// </summary>
+        /// <param name="msg"></param>
+        public static void INFO_I_WCS_GetExcTask(string msg)
+        {
+            Log.Info(msg, "INFO_UPEX");
+        }
+
+        /// <summary>
+        /// 任务创建记录
+        /// </summary>
+        /// <param name="msg"></param>
+        public static void INFO_CREATETASKIN(string msg)
+        {
+            Log.Info(msg, "INFO_CREATETASKIN");
+        }
+
+        /// <summary>
+        /// RGV的写入记录
+        /// </summary>
+        /// <param name="msg"></param>
+        public static void INFO_RGVINFO(string msg)
+        {
+            Log.Info(msg, "INFO_RGVINFO");
+        }
+
+        /// <summary>
+        /// AGV相关日志
+        /// </summary>
+        /// <param name="msg"></param>
+        public static void INFO_AGV(string msg)
+        {
+            Log.Info(msg, "INFO_AGV");
+        }
+    }
+}

+ 51 - 0
WCS.Core/Log/LogConfigModel.cs

@@ -0,0 +1,51 @@
+using System.Collections.Generic;
+
+namespace Log
+{
+    /// <summary>
+    /// 日志配置实体对象
+    /// </summary>
+    public class LogConfig
+    {
+        /// <summary>
+        /// 路径
+        /// </summary>
+        public string LogPath { get; set; } = null!;
+
+        /// <summary>
+        /// 保留天数
+        /// </summary>
+        public int LogDays { get; set; }
+
+        /// <summary>
+        /// 日志
+        /// </summary>
+        public int LogSize { get; set; }
+
+        /// <summary>
+        /// 日志集合
+        /// </summary>
+        public List<LogConfigModel>? Logs { get; set; }
+    }
+
+    /// <summary>
+    /// 日志配置项
+    /// </summary>
+    public class LogConfigModel
+    {
+        /// <summary>
+        /// 配置名称
+        /// </summary>
+        public string? Name { get; set; }
+
+        /// <summary>
+        /// 文件名称
+        /// </summary>
+        public string? FileName { get; set; }
+
+        /// <summary>
+        /// 日志子项类型
+        /// </summary>
+        public Dictionary<string, string>? SubLogNames { get; set; }
+    }
+}

+ 372 - 0
WCS.Core/Log/LogHelper.cs

@@ -0,0 +1,372 @@
+using log4net;
+using log4net.Config;
+using log4net.Repository;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Timers;
+using System.Xml;
+
+namespace Log
+{
+    /// <summary>
+    /// 日志帮助类
+    /// </summary>
+    public static class LogHelper
+    {
+        /// <summary>
+        /// 日志仓库
+        /// </summary>
+        public static ILoggerRepository? LoggerRepository { get; set; }
+
+        #region 写入日志
+
+        private static ILog? GetLog(ILogType type, string flagKey)
+        {
+            if (LoggerRepository == null)
+                return null;
+
+            if (type.SubLogNames.ContainsKey(flagKey))
+                return LogManager.GetLogger(LoggerRepository.Name, type.SubLogNames[flagKey]);
+
+            var defaultKey = string.Empty;
+            foreach (var key in type.SubLogNames.Keys)
+            {
+                defaultKey = key;
+                break;
+            }
+            return LogManager.GetLogger(LoggerRepository.Name, type.SubLogNames[defaultKey]);
+        }
+
+        #region Info
+
+        /// <summary>
+        /// 运行记录
+        /// </summary>
+        /// <param name="type">日志类型</param>
+        /// <param name="message">消息</param>
+        /// <param name="ex">异常</param>
+        /// <param name="flagKey">日志子项索引Key</param>
+        public static void Info(this ILogType type, string message, Exception ex, string flagKey) => GetLog(type, flagKey.ToUpper())?.Info(GetLogMessage(message, ex));
+
+        /// <summary>
+        /// 运行记录
+        /// </summary>
+        /// <param name="type">日志类型</param>
+        /// <param name="message">消息</param>
+        /// <param name="flagKey">日志子项索引Key</param>
+        public static void Info(this ILogType type, string message, string flagKey) => type.Info(message, null!, flagKey);
+
+        /// <summary>
+        /// 运行记录
+        /// </summary>
+        /// <param name="type">日志类型</param>
+        /// <param name="ex">异常</param>
+        /// <param name="flagKey">日志子项索引Key</param>
+        public static void Info(this ILogType type, Exception ex, string flagKey) => type.Info(null!, ex, flagKey);
+
+        #endregion Info
+
+        #region Error
+
+        /// <summary>
+        /// 错误记录
+        /// </summary>
+        /// <param name="type">日志类型</param>
+        /// <param name="message">消息</param>
+        /// <param name="ex">异常</param>
+        /// <param name="flagKey">日志子项索引Key</param>
+        public static void Error(this ILogType type, string message, Exception ex, string flagKey) => GetLog(type, flagKey.ToUpper())?.Error(GetLogMessage(message, ex));
+
+        /// <summary>
+        /// 错误记录
+        /// </summary>
+        /// <param name="type">日志类型</param>
+        /// <param name="message">消息</param>
+        /// <param name="flagKey">日志子项索引Key</param>
+        public static void Error(this ILogType type, string message, string flagKey) => type.Error(message, null!, flagKey);
+
+        /// <summary>
+        /// 错误记录
+        /// </summary>
+        /// <param name="type">日志类型</param>
+        /// <param name="ex">异常</param>
+        /// <param name="flagKey">日志子项索引Key</param>
+        public static void Error(this ILogType type, Exception ex, string flagKey) => type.Error(null!, ex, flagKey);
+
+        #endregion Error
+
+        #region Warn
+
+        /// <summary>
+        /// 警告
+        /// </summary>
+        /// <param name="type">日志类型</param>
+        /// <param name="message">消息</param>
+        /// <param name="ex">异常</param>
+        /// <param name="flagKey">日志子项索引Key</param>
+        public static void Warn(this ILogType type, string message, Exception ex, string flagKey) => GetLog(type, flagKey.ToUpper())?.Warn(GetLogMessage(message, ex));
+
+        /// <summary>
+        /// 警告
+        /// </summary>
+        /// <param name="type">日志类型</param>
+        /// <param name="message">消息</param>
+        /// <param name="flagKey">日志子项索引Key</param>
+        public static void Warn(this ILogType type, string message, string flagKey) => type.Warn(message, null!, flagKey);
+
+        /// <summary>
+        /// 警告
+        /// </summary>
+        /// <param name="type">日志类型</param>
+        /// <param name="ex">异常</param>
+        /// <param name="flagKey">日志子项索引Key</param>
+        public static void Warn(this ILogType type, Exception ex, string flagKey) => type.Warn(null!, ex, flagKey);
+
+        #endregion Warn
+
+        /// <summary>
+        /// 获取详细日志信息
+        /// </summary>
+        /// <param name="message">信息</param>
+        /// <param name="ex">异常</param>
+        /// <returns>详细信息</returns>
+        private static string GetLogMessage(string message, Exception ex)
+        {
+            if (string.IsNullOrEmpty(message) && ex == null)
+                return "Unknown error.";
+            if (string.IsNullOrEmpty(message) && ex != null)
+                return $"[Type:{ex.GetType().Name}][StackTrace:{ex.StackTrace}][Message:{ex.Message.Replace("\r\n", " ")}]";
+            if (!string.IsNullOrEmpty(message) && ex == null)
+                return message;
+            return $"[Message:{message}][Type:{ex!.GetType().Name}][StackTrace:{ex.StackTrace}][Ex Message:{ex.Message.Replace("\r\n", " ")}]";
+        }
+
+        #endregion 写入日志
+
+        #region 初始化日志
+
+        private static string? _configPath = "Log";
+        private static int _fileSize = 500;
+
+        private static readonly List<ILogType> InitList = new List<ILogType>();
+
+        private static readonly LogConfig ConfigModel = new LogConfig();
+
+        private static bool _cleanSet = false;
+        private static string? _previousCleanDay = null;
+        private static int _cleanDays = 30;
+        private static Timer? _logCleanTimer;
+
+        /// <summary>
+        /// 设置配置信息
+        /// </summary>
+        /// <param name="logConfig"></param>
+        public static void SetConfigInfo(LogConfig logConfig)
+        {
+            SetConfigPath(logConfig.LogPath);
+            SetLogFileSize(logConfig.LogSize);
+            SetLogCleanDays(logConfig.LogDays);
+            SetConfigInfo(logConfig.Logs!);
+        }
+
+        /// <summary>
+        /// 日志配置
+        /// </summary>
+        /// <param name="path"></param>
+        public static void SetConfigPath(string path)
+        {
+            _configPath = path;
+        }
+
+        /// <summary>
+        /// 设置日志层级关系
+        /// </summary>
+        /// <param name="logConfigs">配置信息</param>
+        public static void SetConfigInfo(List<LogConfigModel> logConfigs)
+        {
+            ConfigModel.Logs = logConfigs;
+        }
+
+        /// <summary>
+        /// 设置日志项目文件数量和大小
+        /// </summary>
+        /// <param name="size">单文件大小(单位MB,最小10)</param>
+        public static void SetLogFileSize(int size)
+        {
+            if (size < 10)
+                return;
+            _fileSize = size;
+        }
+
+        /// <summary>
+        /// 设置日志清理周期
+        /// </summary>
+        /// <param name="days">清理周期</param>
+        public static void SetLogCleanDays(int days)
+        {
+            if (days < 7)
+                return;
+            _cleanDays = days;
+        }
+
+        /// <summary>
+        /// 初始化Log组件
+        /// </summary>
+        /// <param name="types">日志类型数组</param>
+        public static void Init(params ILogType[] types)
+        {
+            var addedTypes = types.Where(p => !InitList.Contains(p)).ToList();
+            if (addedTypes.Count == 0)
+                return;
+            if (ConfigModel.Logs == null || ConfigModel.Logs.Count == 0)
+                throw new Exception("Log init, config is null.");
+            _configPath = ConfigModel.Logs.FirstOrDefault(p => !string.IsNullOrEmpty(p.FileName))!.FileName;
+            var xmlDoc = new XmlDocument();
+            xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null));
+            var configuration = xmlDoc.CreateElement("configuration");
+            var root = xmlDoc.CreateElement("log4net");
+
+            foreach (var item in addedTypes)
+            {
+                InitList.Add(item);
+                var config = ConfigModel.Logs.FirstOrDefault(p => p.Name == item.LogName);
+                if (config is null)
+                {
+                    config = new LogConfigModel
+                    {
+                        Name = item.LogName,
+                        FileName = _configPath,
+                        SubLogNames = item.SubLogNames
+                    };
+                }
+                else
+                {
+                    config.SubLogNames ??= new Dictionary<string, string>();
+
+                    foreach (var key in config.SubLogNames.Keys.Where(key => item.SubLogNames == null || !item.SubLogNames.ContainsKey(key)))
+                    {
+                        item.SubLogNames?.Add(key, config.SubLogNames[key]);
+                    }
+                    foreach (var key in item.SubLogNames!.Keys.Where(key => !config.SubLogNames.ContainsKey(key)))
+                    {
+                        config.SubLogNames.Add(key, item.SubLogNames[key]);
+                    }
+                }
+                if (item.SubLogNames == null || item.SubLogNames.Count == 0)
+                    continue;
+                CreateXml(xmlDoc, root, config);
+            }
+            configuration.AppendChild(root);
+            xmlDoc.AppendChild(configuration);
+
+            //InitRepository.LoggerRepository ??= LogManager.CreateRepository("NETCoreRepository");
+            LoggerRepository ??= LogManager.CreateRepository("NETCoreRepository");
+            XmlConfigurator.Configure(LoggerRepository, new StreamReader(new MemoryStream(Encoding.ASCII.GetBytes(xmlDoc.OuterXml))).BaseStream);
+
+            xmlDoc.Save("./log4net.config");
+
+            if (_cleanSet) return;
+            _cleanSet = true;
+            _previousCleanDay = DateTime.Now.ToString("yyyyMMdd");
+            // clean log
+            _logCleanTimer = new Timer(1000 * 60);
+            _logCleanTimer.Elapsed += LogCleanTimer_Elapsed;
+            _logCleanTimer.Enabled = true;
+        }
+
+        /// <summary>
+        /// 创建XML节点
+        /// </summary>
+        /// <param name="xmlDoc">XML文档</param>
+        /// <param name="root"></param>
+        /// <param name="config"></param>
+        private static void CreateXml(XmlDocument xmlDoc, XmlElement root, LogConfigModel config)
+        {
+            foreach (var key in config.SubLogNames!.Keys)
+            {
+                // 创建 Logger
+                var logger = xmlDoc.CreateElement("logger");
+                logger.SetAttribute("name", config.SubLogNames[key]);
+                var level = xmlDoc.CreateElement("level");
+                level.SetAttribute("value", "ALL");
+                var appenderRef = xmlDoc.CreateElement("appender-ref");
+                appenderRef.SetAttribute("ref", $"{config.SubLogNames[key]}Appender");
+                logger.AppendChild(level);
+                logger.AppendChild(appenderRef);
+                // 创建 Appender
+                var appender = xmlDoc.CreateElement("appender");
+                appender.SetAttribute("name", $"{config.SubLogNames[key]}Appender");
+                appender.SetAttribute("type", "log4net.Appender.RollingFileAppender");
+                var param = xmlDoc.CreateElement("param");
+                param.SetAttribute("name", "Encoding");
+                param.SetAttribute("value", "utf-8");
+                appender.AppendChild(param);
+                var file = xmlDoc.CreateElement("file");
+                file.SetAttribute("value", Path.Combine(config.FileName!, config.Name!));
+                appender.AppendChild(file);
+                var appendToFile = xmlDoc.CreateElement("appendToFile");
+                appendToFile.SetAttribute("value", "true");
+                appender.AppendChild(appendToFile);
+                var rollingStyle = xmlDoc.CreateElement("rollingStyle");
+                rollingStyle.SetAttribute("value", "Composite");
+                appender.AppendChild(rollingStyle);
+                var maxSizeRollBackups = xmlDoc.CreateElement("maxSizeRollBackups");
+                maxSizeRollBackups.SetAttribute("value", "-1");
+                appender.AppendChild(maxSizeRollBackups);
+                var maximumFileSize = xmlDoc.CreateElement("maximumFileSize");
+                maximumFileSize.SetAttribute("value", $"{_fileSize}MB");
+                appender.AppendChild(maximumFileSize);
+                var lockingModel = xmlDoc.CreateElement("lockingModel");
+                lockingModel.SetAttribute("type", "log4net.Appender.FileAppender+MinimalLock");
+                appender.AppendChild(lockingModel);
+                var staticLogFileName = xmlDoc.CreateElement("staticLogFileName");
+                staticLogFileName.SetAttribute("value", "false");
+                appender.AppendChild(staticLogFileName);
+                var datePattern = xmlDoc.CreateElement("DatePattern");
+                datePattern.SetAttribute("value", $"/yyyyMMdd/'{config.SubLogNames[key]}.log'");
+                appender.AppendChild(datePattern);
+                var layout = xmlDoc.CreateElement("layout");
+                layout.SetAttribute("type", "log4net.Layout.PatternLayout");
+                var conversionPattern = xmlDoc.CreateElement("conversionPattern");
+                conversionPattern.SetAttribute("value", "%date || %5level || %logger || %message || %exception || end %newline");
+                layout.AppendChild(conversionPattern);
+                appender.AppendChild(layout);
+
+                root.AppendChild(appender);
+                root.AppendChild(logger);
+            }
+        }
+
+        private static void LogCleanTimer_Elapsed(object sender, ElapsedEventArgs e)
+        {
+            try
+            {
+                if (_previousCleanDay!.Equals(DateTime.Now.ToString("yyyyMMdd")))
+                    return;
+                _previousCleanDay = DateTime.Now.ToString("yyyyMMdd");
+                if (!Directory.Exists(_configPath))
+                    return;
+                string[] typeDirs = Directory.GetDirectories(_configPath);
+                foreach (var t in typeDirs)
+                {
+                    string[] dateDirs = Directory.GetDirectories(t);
+                    foreach (var t1 in dateDirs)
+                    {
+                        var dirName = t1[(t1.LastIndexOf('\\') + 1)..];
+                        if (Convert.ToInt32(dirName) < Convert.ToInt32(DateTime.Now.AddDays(_cleanDays * -1).ToString("yyyyMMdd")))
+                            Directory.Delete(t1, true);
+                    }
+                }
+            }
+            catch (Exception)
+            {
+                //TODO:增加日志
+            }
+        }
+
+        #endregion 初始化日志
+    }
+}

+ 37 - 0
WCS.Core/Log/LogType.cs

@@ -0,0 +1,37 @@
+using System.Collections.Generic;
+
+namespace Log
+{
+    /// <summary>
+    /// 日志类型接口
+    /// 在config.json中配置日志
+    /// 根节点加
+    /// "Logs": [
+    ///    {
+    ///      "Name": "",//日志名称
+    ///      "File": "",//日志存放位置,相对或绝对
+    ///      "SubLogNames": {
+    ///         "Key1": "Value1",
+    ///         "Key2": "Value2",
+    ///         "Key3": "Value3"
+    ///         }
+    ///     }
+    ///  ]
+    ///  自定义日志:
+    ///  继承接口 ILogType
+    ///  调用日志:
+    ///  继承ILogType的对象对应的Info,Error等方法写入对应日志
+    /// </summary>
+    public interface ILogType
+    {
+        /// <summary>
+        /// 日志名称
+        /// </summary>
+        string LogName { get; }
+
+        /// <summary>
+        /// 日志子项集合
+        /// </summary>
+        Dictionary<string, string> SubLogNames { get; set; }
+    }
+}