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;
}
}