【C#】日志文件类

    public class LogInfo
    {
        public string AddTime;
        public string Content;
        public string Type;
        public Exception Ex;

        public LogInfo(string addTime, string content, string type, Exception ex = null)
        {
            AddTime = addTime;
            Content = content;
            Type = type;
            Ex = ex;
        }
    }

    interface ILogger
    {
        void Warn(string msg);
        void Info(string msg);
        void Debug(string msg);
        void Error(string msg);
        void Error(Exception ex, string msg);
    }

    /// <summary>
    /// 支持多线程写日志
    /// </summary>
    public class SimpleLogger : ILogger
    {
        private BlockingCollection<LogInfo> _queue = new BlockingCollection<LogInfo>();
        private readonly string _filePath = $"{AppDomain.CurrentDomain.BaseDirectory}Logs\\";
        private CancellationTokenSource _cancellationTokenSource;
        private CancellationToken _cancellToken;

        //使用Lazy创建线程安全单例模式
        //如果不用Lazy,则需要lock来判断对象是否需要实例化
        private static Lazy<SimpleLogger> _instance = new Lazy<SimpleLogger>(() => new SimpleLogger());
        public static SimpleLogger Instance => _instance?.Value;

        private SimpleLogger()
        {
            _cancellationTokenSource = new CancellationTokenSource();
            _cancellToken = _cancellationTokenSource.Token;
            Task.Factory.StartNew(HandleLogQueue);
        }

        /// <summary>
        /// 关闭日志队列线程
        /// </summary>
        public void CloseLogThread()
        {
            _cancellationTokenSource.Cancel();
            _cancellationTokenSource.Dispose();
        }

        /// <summary>
        /// 判断日志队列是否为空
        /// </summary>
        /// <returns></returns>
        public bool QueueIsEmpty()
        {
            return _queue.IsCompleted;
        }

        public int Count()
        {
            return _queue.Count;
        }

        public void Debug(string msg)
        {
            _queue?.TryAdd(new LogInfo(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), msg, "Debug"));
        }

        public void Warn(string msg)
        {
            _queue?.TryAdd(new LogInfo(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), msg, "Warn"));
        }

        public void Info(string msg)
        {
            _queue?.TryAdd(new LogInfo(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), msg, "Info"));
        }

        public void Error(string msg)
        {
            _queue?.TryAdd(new LogInfo(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), msg, "Error"));
        }

        public void Error(Exception ex, string msg = "")
        {
            _queue?.TryAdd(new LogInfo(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), msg, "Error", ex));
        }

        private void HandleLogQueue()
        {
            try
            {
                foreach (var logInfo in _queue.GetConsumingEnumerable(_cancellToken))
                {
                    WriteLine(logInfo.Content, logInfo.Type, logInfo.AddTime, logInfo.Ex);
                }
            }
            catch
            {
                // ignored
            }
        }

        private void WriteLine(string content, string category, string time, Exception ex = null)
        {
            var path = $"{_filePath}{DateTime.Now.ToString("yyyyMMdd")}\\";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            var filePath = $"{GetFileName(path, category)}.txt";
            using (var sw = new StreamWriter(filePath, true, Encoding.UTF8))
            {
                sw.WriteLine(Format(content, category, time, ex));
            }
        }

        private string Format(string content, string category, string time, Exception ex = null)
        {
            var builder = new StringBuilder();
            builder.AppendFormat("{0} ", time);
            if (!string.IsNullOrEmpty(category))
            {
                builder.AppendFormat("[{0}]", category);
            }

            if (content != "")
            {
                builder.Append(content + "\r\n");
            }

            if (ex != null)
            {
                builder.Append(ex.Message + "\r\n");
                builder.Append(ex.StackTrace + "\r\n");
            }

            return builder.ToString();
        }

        private string GetFileName(string path, string category)
        {
            if (!File.Exists($"{path}Log-{category}-0.txt"))
            {
                return $"{path}Log-{category}-0";
            }

            var no = 0;
            var info = new FileInfo($"{path}Log-{category}-0.txt");
            while (info.Length >= 10 * 1024 * 1024)
            {
                no++;
                if (!File.Exists($"{path}Log-{category}-{no}.txt"))
                {
                    return $"{path}Log-{category}-{no}";
                }
                info = new FileInfo($"{path}Log-{category}-{no}.txt");
            }

            return $"{path}Log-{category}-{no}";
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值