优点:懒加载模式,IO流不会重复实例化使用,多线程安全。
日志基类接口
- ///
- /// 日志基类接口
- ///
- public interface LogBase:IDisposable
- {
- ///
- /// 记录信息
- ///
- /// 消息内容
- void LogInfo(string message);
- ///
- /// 记录警告信息
- ///
- /// 消息内容
- void LogWarning(string message);
- ///
- /// 记录错误信息
- ///
- /// 消息内容
- void LogError(string message);
- }
FileLogger文件日志类实现LogBase接口
- public class FileLogger<T> : LogBase where T : class, new()
- {
- private StreamWriter streamWriter;
- private string _filePath;
- private bool _disposed;
- private string _className;
- private static Lazy
> lazy; - private Object writerLock = new Object();
-
- private FileLogger(string filePath, string className)
- {
- if (string.IsNullOrEmpty(filePath))
- return;
-
- _filePath = filePath;
- _className = className;
-
- string path = Path.GetDirectoryName(filePath);
- if (!Directory.Exists(path))
- Directory.CreateDirectory(path);
- // 不覆盖
- streamWriter = new StreamWriter(filePath,true);
- }
- public static FileLogger
GetInstance(string path = null) - {
- if (path == null)
- path = System.Environment.CurrentDirectory + "\\Log\\"+ DateTime.Now.ToString("yyyyMMdd")+"\\" + DateTime.Now.ToString("yyyyMMddHH") + ".txt";
-
- lazy = new Lazy
>(() => - {
-
- return new FileLogger
(path, typeof(T).Name); - });
-
- return lazy.Value;
- }
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- protected virtual void Dispose(bool disposing)
- {
- lock (writerLock)
- {
- if (!_disposed)
- {
- if (disposing)
- {
- // Release managed resources
- _filePath = null;
- _className = null;
- }
-
- // Release unmanaged resources
- streamWriter.Close();
- streamWriter.Dispose();
-
- _disposed = true;
- }
- }
- }
- public void LogInfo(string message)
- {
- Write("LogInfo", message, _className);
- }
-
- public void LogWarning(string message)
- {
- Write("LogWarning", message, _className);
- }
-
- public void LogError(string message)
- {
- Write("LogError", message, _className);
- }
- ///
- /// 写入消息方法
- ///
- /// 消息类型
- /// 消息内容
- /// 类名
- private void Write(string mesType, string message, string className)
- {
- lock (writerLock)
- {
- StringBuilder stringBuilder = new StringBuilder(mesType);
- stringBuilder.Append("\t");
- stringBuilder.Append(className);
- stringBuilder.Append("\t");
- stringBuilder.Append(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"));
- stringBuilder.Append("\t");
- stringBuilder.Append(message);
- streamWriter.WriteLine(stringBuilder.ToString());
- stringBuilder.Clear();
- streamWriter.Flush();
- }
- }
-
- ~FileLogger()
- {
- Dispose(false);
- }
- }
其它类型实现:
- ///
- /// 事件日志实现类
- ///
- ///
- internal class EventLogger<T> : LogBase where T : class, new()
- {
- private readonly Object lockObj=new object();
- public void Dispose()
- {
- throw new NotImplementedException();
- }
-
- public void LogError(string message)
- {
- throw new NotImplementedException();
- }
-
- public void LogInfo(string message)
- {
- lock (lockObj)
- {
-
- }
- }
-
- public void LogWarning(string message)
- {
- throw new NotImplementedException();
- }
- }
- ///
- /// 数据库实现类
- ///
- ///
- internal class DBLogger<T> : LogBase where T : class, new()
- {
- public void Dispose()
- {
- throw new NotImplementedException();
- }
-
- public void LogError(string message)
- {
- throw new NotImplementedException();
- }
-
- public void LogInfo(string message)
- {
- throw new NotImplementedException();
- }
-
- public void LogWarning(string message)
- {
- throw new NotImplementedException();
- }
- }
数据库与事件日志文件没有具体实现,需要的话自行实现。
- ///
- /// 日志可以输出到目标地点
- ///
- public enum LogTarget
- {
- ///
- /// txt文件
- ///
- FILE,
- ///
- /// 数据库
- ///
- DATABASE,
- ///
- /// 事件日志
- ///
- EVENTLOG
- }
看日志工厂:
- ///
- /// 日志工厂
- ///
- ///
- public class LogFactory<T> where T : class, new()
- {
- ///
- /// 工厂方法
- /// 如果是非文件日志,不必传参fileName与path
- ///
- /// 默认文件
- /// 默认以时间格式命名
- /// 默认当前项目路径
- ///
- public static LogBase InstanceLog(LogTarget target = LogTarget.FILE, string fileName = null, string path = null)
- {
- LogBase logBase = null;
-
- switch (target)
- {
- case LogTarget.FILE:
- if (fileName == null)
- fileName = DateTime.Now.ToString("yyyyMMddHH") + ".txt";
- if (path == null)
- path = System.Environment.CurrentDirectory + "\\Log\\"+ DateTime.Now.ToString("yyyyMMdd");
- logBase = FileLogger
.GetInstance(Path.Combine(path, fileName)); - break;
- case LogTarget.DATABASE:
- logBase = new DBLogger
(); - break;
- case LogTarget.EVENTLOG:
- logBase = new EventLogger
(); - break;
- }
-
- return logBase;
- }
- }
调用
- LogBase log = LogFactory
.InstanceLog(); -
- for (int i = 0; i < 10000; i++)
- {
- log.LogInfo("ddd");
- log.LogError("sss");
- log.LogWarning("qqq");
- }
- for (int i = 0; i < 10000; i++)
- {
- new Task(() =>
- {
- log.LogInfo("ddd");
- log.LogError("sss");
- log.LogWarning("qqq");
- }).Start();
- }
- int n = 0;
- while (true)
- {
- if (n >= 1000)
- break;
- new Task(() =>
- {
- log.LogInfo("ddd");
- log.LogError("sss");
- log.LogWarning("qqq");
- }).Start();
- n++;
- }
- log.LogInfo($"ddd");
-
- log.Dispose();
log.Dispose();如果就当前函数使用的话就手动调用释放资源,如果全局使用就不需要调用,能手动的尽量手动(比如窗体关闭closed事件调用),不调用的也没事,等待GC调用,不过GC调用不会及时的。