您的位置:首页 > 编程语言 > C#

C#自定义log机制

2015-07-31 09:18 411 查看
在写一些后台处理的时候,通常出现一些异常问题我们都是通过输出一些log来提示用户,这样可以大大方便程序的调试和维护,

本例采用的是队列(Queue)来推送log,在一个单独的线程里面执行log输出,具体代码如下:

/// <summary>
/// 程序日志输出工具类
/// </summary>
class Logger
{
/// <summary>
/// log所在目录
/// </summary>
private const String LOG_DIR = "D:\\log";
/// <summary>
/// log全路径
/// </summary>
private const String LOG_PATH = "D:\\log\\{0}.log";
/// <summary>
/// log队列
/// </summary>
private static Queue<Log> logs = new Queue<Log>();
/// <summary>
/// 线程启停标示
/// </summary>
private static Boolean isSaving = false;
/// <summary>
/// 输出log的线程
/// </summary>
private static Thread saveThread;
/// <summary>
/// log线程触发器
/// </summary>
public static EventWaitHandle _wh = new AutoResetEvent(false);

/// <summary>
/// 日志类型
/// </summary>
public struct LogType
{
public static String ERROR { get { return "错误"; } }
public static String WARnING { get { return "警告"; } }
public static String INFO { get { return "信息"; } }
}
/// <summary>
/// 启动log输出
/// </summary>
public static void Start()
{
try
{
isSaving = true;
saveThread = new Thread(save);
saveThread.IsBackground = true;
saveThread.Start();
}
catch (Exception e)
{

}

}
/// <summary>
/// 停止log输出
/// </summary>
public void Stop()
{
try
{
_wh.Close();
}
catch (Exception e)
{

}

}
/// <summary>
/// 输出LOG
/// </summary>
private static void save()
{

while (true)
{
if (!isSaving)
break;
try
{
Log log = null;
lock (logs.GetType())
if (logs.Count > 0)
{
//移除并返回队列的第一个对象
log = logs.Dequeue();
if (log == null) return;
}
if (log != null)
{

StreamWriter sw = null;
String logStr;
String today = log.now.ToString("yyyy-MM-dd");

try
{
if (!Directory.Exists(LOG_DIR))
{
Directory.CreateDirectory(LOG_DIR);
}
//创建输出流
if (!File.Exists(String.Format(LOG_PATH, today)))
{
File.Create(String.Format(LOG_PATH, today)).Close();
}
sw = new StreamWriter(String.Format(LOG_PATH, today), true);
//输出log日期
logStr = "时间:" + DateTime.Now.ToLocalTime().ToString();
sw.WriteLine(logStr);
//输出log日期
logStr = "区域:" + log.logPlace;
sw.WriteLine(logStr);
//输出log类型
logStr = "类型:" + log.logType;
sw.WriteLine(logStr);
if (log.ex != null)
{
//输出log日期
logStr = "信息:" + log.ex.Message;
logStr += Environment.NewLine + log.ex.StackTrace;
}
else {
//输出log日期
logStr = "信息:" + log.message;
}

sw.WriteLine(logStr);
//输出log结束标记
logStr = "------------------------------------------------------------------------------------------------------------------";
sw.WriteLine(logStr);
}
catch
{
//do nothing
}
finally
{
if (sw != null)
{
sw.Close();
}
}
}
else
{
//当队列里面没有需要保存到数据库里面的内容时,线程进入等待状态
//直到_wh调用set(),线程才继续执行
_wh.WaitOne();
}
}
catch (Exception e)
{
//do nothing
}
}

}
/// <summary>
/// 推送log
/// </summary>
/// <param name="log"></param>
public static void push(Log log)
{
logs.Enqueue(log);
_wh.Set();
}

}
/// <summary>
/// log实体类
/// </summary>
class Log
{
/// <summary>
/// log类型
/// </summary>
public String logType;
/// <summary>
/// log发生位置
/// </summary>
public String logPlace;
/// <summary>
/// log信息
/// </summary>
public String message;
/// <summary>
/// log发生时间
/// </summary>
public DateTime now;
/// <summary>
/// log发生时间
/// </summary>
public Exception ex;
/// <summary>
/// log构造函数
/// </summary>
/// <param name="logType"></param>
/// <param name="logPlace"></param>
/// <param name="message"></param>
public Log(String logType, String logPlace, String message)
{
this.logType = logType;
this.logPlace = logPlace;
this.message = message;
this.now = DateTime.Now;
}
public Log(String logType, String logPlace, Exception ex)
{
this.logType = logType;
this.logPlace = logPlace;
this.ex = ex;
this.now = DateTime.Now;
}
}


通过这种方式可以防止程序阻塞,也不会过多的影响处理线程的执行效率。

欢迎指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: