using System; using System.Collections.Generic; using System.IO; using System.Diagnostics; using System.Threading; using System.Windows.Forms; using System.Reflection; using log4net; using log4net.Repository.Hierarchy; using log4net.Appender; using log4net.Layout; using log4net.Core; using log4net.Repository; #pragma warning disable 219 //禁止未用变量警告 #pragma warning disable 168 //禁止未用变量警告 namespace CommonLib.LOG { /// /// Log4net 类 /// public static class CLog4NetParser { /* * 步骤: * 1. 使用 NuGet 安装 log4net。 * 2. 主执行程序目录另外添加 log4net.config 配置文件(注意:设置该文件属性的“复制到输出目录”为“始终复制”)。 * 3 . 主执行程序 AssemblyInfo.cs 中添加 [assembly: log4net.Config.XmlConfigurator(ConfigFileExtension = "config", Watch = true)] * 3. 调用。 * */ // 日志分日期保存 /// /// 根据类名获取日志记录器对象。 /// 必须初始化,不然无法写入文档 /// private static void InitLog4net() { try { //从dll中获取exe文件名字 //解决同一目录下加载配置文件被锁定得问题 Assembly asm = Assembly.GetEntryAssembly(); if (asm == null) return; string exeFileName = asm.GetName().Name; string ConfigFileName = exeFileName+"_" + "log4net.config"; if (!File.Exists(ConfigFileName)) { string srcFileName = Path.Combine(Environment.CurrentDirectory, "log4net.config"); if (File.Exists(srcFileName)) { File.Copy(srcFileName, ConfigFileName); } else { throw new Exception(ConfigFileName + " Not Found ,Please Copy log4net.config "); } } FileInfo fileinfo = new System.IO.FileInfo(ConfigFileName); // ICollection icol = log4net.Config.XmlConfigurator.Configure(fileinfo);// } catch(Exception ex) { m_Logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); ; MessageBox.Show(ex.Message + "\n" + ex.StackTrace); } } public static void Setup(string ExeName) { Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository(); PatternLayout patternLayout = new PatternLayout(); patternLayout.ConversionPattern = "%date [%thread] %-5level %logger - %message%newline"; patternLayout.ActivateOptions(); RollingFileAppender roller = new RollingFileAppender(); roller.AppendToFile = false; string LogFileName = string.Format(@"Log\{0}.log", ExeName); roller.File = LogFileName; roller.Layout = patternLayout; roller.MaxSizeRollBackups = 5; roller.MaximumFileSize = "10MB"; roller.RollingStyle = RollingFileAppender.RollingMode.Size; roller.StaticLogFileName = false; roller.ActivateOptions(); hierarchy.Root.AddAppender(roller); MemoryAppender memory = new MemoryAppender(); memory.ActivateOptions(); hierarchy.Root.AddAppender(memory); hierarchy.Root.Level = Level.Info; hierarchy.Configured = true; } /* private static readonly ILog m_Logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); */ private static ILog m_Logger = null; private static ILog Logger { get { if(m_Logger==null) { m_Logger =LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); } if(m_Logger.IsErrorEnabled==false) { InitLog4net(); //string exeFileName = Assembly.GetEntryAssembly().GetName().Name; //Setup(exeFileName); } return m_Logger; } } /// /// /// /// public static void WriteLine(string message) { try { Logger.Info(message); } catch (Exception ex) { } } public static void ErrorLine(string message) { try { Logger.Error(message); } catch (Exception ex) { } } public static void FatalLine(string message) { try { Logger.Fatal(message); } catch (Exception ex) { } } public static string GetFileName() { ILoggerRepository[] allRepositories = LogManager.GetAllRepositories(); for (int i = 0; i < allRepositories.Length; i++) { IAppender[] appenders = allRepositories[i].GetAppenders(); for (int j = 0; j < appenders.Length; j++) { FileAppender fileAppender = appenders[j] as FileAppender; if (fileAppender != null) { return fileAppender.File; } } } return null; } public static void ProcessInfo() { Process proc = Process.GetCurrentProcess(); CLog4NetParser.WriteLine("Private MemorySize : " + ((double)proc.PrivateMemorySize64 / 1024.0 / 1024.0).ToString("F2") + " [MByte]"); CLog4NetParser.WriteLine("Virtual MemorySize : " + ((double)proc.VirtualMemorySize64 / 1024.0 / 1024.0).ToString("F2") + " [MByte]"); } /// /// 测试方法1。 /// public static void Method1() { Logger.Info("这是 Info() 方法,用于记录【消息】。"); Logger.Debug("这是 Debug() 方法,用于记录【调试】消息。"); Logger.Warn("这是 Warn() 方法,用于记录【警告】消息。"); Logger.Error("这是 Error() 方法,用于记录【异常】消息。"); Logger.Fatal("这是 Fatal() 方法,用于记录【严重错误】消息。"); try { string str = null; str = str.ToString(); } catch (Exception ex) { Logger.Info(ex); } try { Method2(); } catch (Exception ex) { Logger.Error(ex); } } public static void Method2() { throw new Exception("方法2 抛出自定义异常"); } } public class LogCollection { public LogCollection(int maxSize) { RingList obj = this.logRingList; lock (obj) { this.MaxSize = maxSize; } } public LogCollection() { } public int MaxSize { get { return this.logRingList.MaxSize; } set { if (value <= 0) { throw new ArgumentOutOfRangeException(); } RingList obj = this.logRingList; lock (obj) { this.logRingList.MaxSize = value; foreach (KeyValuePair> log in classifiedLogRingList) { log.Value.MaxSize = value; } } } } public int Count(LogLevel type) { RingList log; if (type < 0) { log = this.logRingList; } else { try { if (!this.classifiedLogRingList.TryGetValue(type, out log)) { return 0; } } catch (KeyNotFoundException) { return 0; } } return log.Count; } public uint ElementCount { get { return this.elementCount; } } public void Add(LogLevel level, string format, object arg0) { RingList obj = this.logRingList; lock (obj)// { this.Add(level, string.Format(format, arg0)); } } public void Add(LogLevel level, string format, params object[] args) { RingList obj = this.logRingList; lock (obj)// { this.Add(level, string.Format(format, args)); } } private event EventHandler m_EventAdd; /// /// 添加消息事件 /// public event EventHandler EventAdd { add { if (m_EventAdd == null) { //没有 Assembly System.Core 无法使用 // if (!m_EventAdd.GetInvocationList().Contains(value)) { //关键部分,如果已经注册过事件,则能防止重复注册 m_EventAdd += value; } } } remove { m_EventAdd -= value; } } Boolean bInitError = false; public void Add(LogLevel level, string message) { Stopwatch watch = new Stopwatch(); watch.Start(); RingList obj = this.logRingList; double t1, t2, t3, t4; lock (obj)// { LogElement log = new LogElement(this.elementCount, level, message); //Debug.WriteLine(message); //特浪费时间 if(m_EventAdd!=null) m_EventAdd.Invoke(this, log); t1 = watch.Elapsed.TotalMilliseconds; this.elementCount += 1u; this.logRingList.Add(log); try { Int32 ThreadID = Thread.CurrentThread.ManagedThreadId; //////////////////////////////////////////////// string Info = string.Format("[{0}],[{1}],{2}", (LogLevel)level,ThreadID, message); if (!bInitError) CLog4NetParser.WriteLine(Info); //初始化失败,不保存log // Debug.WriteLine(Info);//特浪费时间 t2 = watch.Elapsed.TotalMilliseconds; //////////////////////////////////////////////////////////// RingList RingList; if (this.classifiedLogRingList.TryGetValue(level, out RingList)) { RingList.Add(log); } else { // //带参数得模板构造函数 // RingList = (RingList)Activator.CreateInstance(typeof(RingList), logRingList.MaxSize); RingList = new RingList(); RingList.Capacity = logRingList.MaxSize; RingList.Add(log); this.classifiedLogRingList.Add(level, RingList); } t3 = watch.Elapsed.TotalMilliseconds; } catch (KeyNotFoundException) { RingList RingList2 = new RingList(); RingList2.Capacity = logRingList.MaxSize; RingList2.Add(log); this.classifiedLogRingList.Add(level, RingList2); } catch(Exception ex) { bInitError = true; MessageBox.Show(ex.Message + ex.StackTrace); } finally { watch.Stop(); t4 = watch.Elapsed.TotalMilliseconds ; } } } /// /// 挂上点击事件钩子,每次点击都会在log中增加信息 /// /// public void HookAllCtrlLogHandler(Control ParentCtrl) { foreach (Control ctrl in ParentCtrl.Controls) { //if (ctrl is Button) { //TODO:怎么吧BtnClickHandler 插到回调队列得最前面? //ctrl.Click += BtnClickHandler; ctrl.MouseDown += BtnClickHandler; } //if(ctrl is ContainerControl) { HookAllCtrlLogHandler(ctrl); } } } private void BtnClickHandler(object sender, EventArgs e) { if (sender is Control) { Control xBtn = sender as Control; Add(LogLevel.Trace, xBtn.Name + "[" +"Caption: "+ xBtn.Text + "]" + "Clicked"); } } public LogElement Fetch(int type, int index) { RingList obj = this.logRingList; LogElement result; lock (obj) { RingList log; if (type < 0) { log = this.logRingList; } else { log = this.classifiedLogRingList[(LogLevel)type]; } if (index < 0 || index > log.Count) { throw new ArgumentOutOfRangeException(); } //动态求最后一行 result = log.Get(index); //更新到第一行让人误以为没有更新 // result = log[index]; } return result; } public void WriteToStream(StreamWriter stream) { RingList obj = this.logRingList; lock (obj) { foreach (LogElement log in this.logRingList) { stream.WriteLine("{0},{1},{2}", log.Number.ToString(), log.TimeStamp.ToString("yyyy/MM/dd HH:mm:ss.fff"), log.Message); } } } //所有的log都则这里 private RingList logRingList = new RingList(); // private Dictionary> classifiedLogRingList = new Dictionary>(10); private uint elementCount; } }