C# 单例日志

解决多线程模式下日志记录

1.日志功能类,记录方法只实现了Info与Warning,其它自行加上即可运行。

public class LogDemo
    {
        private static Lazy<LogDemo> _logDemo = new Lazy<LogDemo>(() => new LogDemo());
        private static object _locker = new object();
        private const int _fileSize = 0xB71B00;// 10MB
        private ConcurrentDictionary<string, string> _logKey = new ConcurrentDictionary<string, string>();

        private LogDemo() { }
        public static LogDemo Instance => _logDemo.Value;
        private void CreateFilePath(string path)
        {
            string fp = Path.GetDirectoryName(path);
            // 判断文件夹是否存在
            if (!Directory.Exists(fp))
                Directory.CreateDirectory(fp);
            // 文件是否存在
            if (!File.Exists(path))
            {
                using (var file = File.Create(path)) ;
            }
        }
        private bool WirteIn(string log, string path, LogType logType, Exception exception = null)
        {
            lock (_locker)
            {
                if (string.IsNullOrEmpty(log))
                    throw new ArgumentNullException(nameof(log));

                if (_logKey.ContainsKey(path))
                    path = _logKey[path];
                CreateFilePath(path);
                using (FileStream fs = new FileStream(path, FileMode.Append))
                {
                    if (fs.Length > _fileSize)// 文件大了重新创建
                    {
                        string oldPath = path;
                        foreach (var item in _logKey)
                        {
                            if (item.Value == path)
                                oldPath = item.Key;
                        }
                        string path2 = Path.Combine(Path.GetDirectoryName(oldPath), Path.GetFileNameWithoutExtension(oldPath) + "-" + DateTime.Now.ToString("yyyyMMddHHmmssffff") + Path.GetExtension(oldPath));
                        _logKey.AddOrUpdate(oldPath, path2, (oldPath, path2) => path2);
                        WirteIn(log, path2, logType, exception);
                        return true;
                    }
                    using (StreamWriter sw = new StreamWriter(fs))
                    {
                        string txt = $"{logType.ToString()} {DateTime.Now.ToString("yyyy年MM月dd日 HH:mm:ss.ffff")}:{log}";
                        if (exception != null)
                            txt += "\r\n" + ExceptionToString(exception);
                        sw.WriteLine(txt);
                    }
                }
                return true;
            }
        }
        public void Info(string log, string path)
        {
            WirteIn(log, path, LogType.Info);
        }
        public void Warning(string log, string path)
        {
            WirteIn(log, path, LogType.Warning);
        }
        public void Error(string log, string path, Exception ex)
        {
            WirteIn(log, path, LogType.Error, ex);
        }
        private string ExceptionToString(Exception ex)
        {
            if (ex.InnerException == null)
            {
                return GetExceptionMessage(ex);
            }
            return GetExceptionMessage(ex) + "\r\n***\r\n" + ExceptionToString(ex.InnerException);
        }
        private string GetExceptionMessage(Exception ex)
        {
            string message = "", source = "", stackTrace = "", targetSite = "", helpLink = "";
            if (ex.Message != null)
            {
                message = ex.Message;
            }
            if (ex.Source != null)
            {
                source = ex.Source;
            }
            if (ex.StackTrace != null)
            {
                stackTrace = ex.StackTrace;
            }
            if (ex.TargetSite != null)
            {
                targetSite = ex.TargetSite.ToString();
            }
            if (ex.HelpLink != null)
            {
                helpLink = ex.HelpLink;
            }
            return message + "\r\n" + source + "\r\n" + stackTrace + "\r\n" + targetSite + helpLink;
        }
    }

2.枚举

public enum LogType
    {
        Info,
        Warning,
        Error,
        Fatal,
        Debug,
        Trace
    }

3.工厂

    /// <summary>
    /// 用作创建多个文件
    /// </summary>
    public class LogDemoFactory
    {
        public static readonly LogDemoFactory logDemoFactory1;
        public static readonly LogDemoFactory logDemoFactory2;
        public static readonly LogDemoFactory logDemoFactory3;
        static LogDemoFactory()
        {
            logDemoFactory1=new LogDemoFactory("E:\\"+Guid.NewGuid().ToString()+".txt");
            logDemoFactory2 = new LogDemoFactory("E:\\" + Guid.NewGuid().ToString() + ".txt");
            logDemoFactory3 = new LogDemoFactory("E:\\" + Guid.NewGuid().ToString() + ".txt");
        }


        private string _filePath;
        private LogDemo _logDemo;
        private LogDemoFactory(string filePath)
        {
            _filePath = filePath;
            _logDemo = LogDemo.Instance;
        }
        public void Info(string log)
        {
            _logDemo.Info(log, _filePath);
        }
        public void Warning(string log)
        {
            _logDemo.Warning(log, _filePath);
        }
    }

4.多线程测试

for (int j = 0; j < 10; j++)
            {
                int n = 100;
                int m = n + 2;
                Task[] tasks = new Task[m];
                for (int i = 0; i < n; i++)
                {
                    tasks[i] = Task.Factory.StartNew(() =>
                    {
                        LogDemoFactory.logDemoFactory1.Info("你好,阿泽!");
                    });
                    tasks[i + 1] = Task.Factory.StartNew(() =>
                    {
                        LogDemoFactory.logDemoFactory2.Info("你好,阿泽!");
                    });
                    tasks[i + 2] = Task.Factory.StartNew(() =>
                    {
                        LogDemoFactory.logDemoFactory3.Info("你好,阿泽!");
                    });
                }
                await Task.WhenAll(tasks);
            }

5. 单线程测试

 while (true)
            {
                LogDemoFactory.logDemoFactory1.Info("你好,阿泽!");
                LogDemoFactory.logDemoFactory2.Info("你好,阿泽!");
                LogDemoFactory.logDemoFactory3.Info("你好,阿泽!");  
                Thread.Sleep(100);
            }

  

 6.完毕。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值