前言
即使是小型項目,也需要日志的功能,這裡就不讨論log4net之類的架構,提供一個異步的、控制台輸出+日志檔案輸出的簡易日志幫助類。
正文
一、幫助類檔案logger.cs

//=========================================
//
// 作 者:農民伯伯
// 郵 箱:[email protected]
// 博 客:http://over140.cnblogs.com/
// 時 間:2009-7-16
// 描 述:日志類,注意需要在日志記錄的目錄給使用者寫入權限!
using system;
using system.configuration;
using system.collections.generic;
using system.data.sqlclient;
using system.diagnostics;
using system.io;
using system.text;
using system.runtime.compilerservices;
using system.web;
namespace centralhousestest
{
/// <summary>
/// 日志類
/// </summary>
public sealed class logger
{
#region member variables
/// <summary>
/// 用于trace的組織輸出的類别名稱
/// </summary>
private const string trace_sql = "\r\n***********************trace_sql {0}*****************************\r\ntrace_sql";
private const string trace_exception = "\r\n***********************trace_exception {0}***********************";
/// 目前日志的日期
private static datetime currentlogfiledate = datetime.now;
/// 日志對象
private static textwritertracelistener twtl;
/// 日志根目錄
private const string log_root_directory = @"d:\log";
/// 日志子目錄
private static string log_subdir;
/// " {0} = {1}"
private const string format_trace_param = " {0} = {1}";
/// 1 僅控制台輸出
/// 2 僅日志輸出
/// 3 控制台+日志輸出
private static readonly int flag = 2; //可以修改成從配置檔案讀取
#endregion
#region constructor
static logger()
{
system.diagnostics.trace.autoflush = true;
switch (flag)
{
case 1:
system.diagnostics.trace.listeners.add(new consoletracelistener());
break;
case 2:
system.diagnostics.trace.listeners.add(twtl);
case 3:
}
}
#region method
#region trace
/// 異步錯誤日志
/// <param name="value"></param>
public static void trace(exception ex)
new asynclogexception(begintraceerror).begininvoke(ex, null, null);
/// 異步sql日志
/// <param name="cmd"></param>
public static void trace(sqlcommand cmd)
new asynclogsqlcommand(begintracesqlcommand).begininvoke(cmd, null, null);
/// <param name="sql"></param>
/// <param name="parameter"></param>
public static void trace(string sql, params sqlparameter[] parameter)
new asynclogsql(begintracesql).begininvoke(sql, parameter, null, null);
#region delegate
private delegate void asynclogexception(exception ex);
private delegate void asynclogsqlcommand(sqlcommand cmd);
private delegate void asynclogsql(string sql, params sqlparameter[] parameter);
private static void begintraceerror(exception ex)
if (null != ex)
//檢測日志日期
strategylog();
//輸出日志頭
system.diagnostics.trace.writeline(string.format(trace_exception, datetime.now));
while (null != ex)
{
system.diagnostics.trace.writeline(string.format("{0} {1}\r\n{2}\r\nsource:{3}", ex.gettype().name, ex.message, ex.stacktrace, ex.source));
ex = ex.innerexception;
}
private static void begintracesqlcommand(sqlcommand cmd)
if (null != cmd)
sqlparameter[] parameter = new sqlparameter[cmd.parameters.count];
cmd.parameters.copyto(parameter, 0);
begintracesql(cmd.commandtext, parameter);
private static void begintracesql(string sql, params sqlparameter[] parameter)
if (!string.isnullorempty(sql))
system.diagnostics.trace.writeline(sql, string.format(trace_sql, datetime.now));
if (parameter != null)
foreach (sqlparameter param in parameter)
{
system.diagnostics.trace.writeline(string.format(format_trace_param, param.parametername, param.value));
}
#region helper
/// 根據日志政策生成日志
private static void strategylog()
//判斷日志日期
if (datetime.compare(datetime.now.date, currentlogfiledate.date) != 0)
datetime currentdate = datetime.now.date;
//生成子目錄
buiderdir(currentdate);
//更新目前日志日期
currentlogfiledate = currentdate;
system.diagnostics.trace.flush();
//更改輸出
if (twtl != null)
system.diagnostics.trace.listeners.remove(twtl);
system.diagnostics.trace.listeners.add(twtl);
/// 根據年月生成子目錄
/// <param name="currentdate"></param>
private static void buiderdir(datetime currentdate)
int year = currentdate.year;
int month = currentdate.month;
//年/月
string subdir = string.concat(year, '\\', month);
string path = path.combine(log_root_directory, subdir);
if (!directory.exists(path))
directory.createdirectory(path);
log_subdir = subdir;
#region properties
/// 日志檔案路徑
/// <returns></returns>
private static string getlogfullpath
get
return string.concat(log_root_directory, '\\', string.concat(log_subdir, @"\log", currentlogfiledate.toshortdatestring(), ".txt"));
/// 跟蹤輸出日志檔案
private static textwritertracelistener twtl
if (twtl == null)
if (string.isnullorempty(log_subdir))
buiderdir(datetime.now);
else
string logpath = getlogfullpath;
if (!directory.exists(path.getdirectoryname(logpath)))
buiderdir(datetime.now);
twtl = new textwritertracelistener(getlogfullpath);
return twtl;
}
}

二、示例
2.1 錯誤記錄

static void main(string[] args)
ilist<string> list = null;
try
console.writeline(list.count);
catch (exception ex)
logger.trace(ex);
console.readline();

代碼說明:錯誤很明顯,未執行個體化就使用count屬性。
日志截圖:
2.2 資料庫記錄

using (sqlconnection con = new sqlconnection("data source=overa;initial catalog=northwind;user id=sa;password=sa;"))
con.open();
sqlcommand sqlcmd = new sqlcommand("select * from customers where companyname = @companyname", con);
sqlcmd.parameters.add(new sqlparameter("@companyname", "alfreds futterkiste"));
logger.trace(sqlcmd);
sqldatareader sdr = sqlcmd.executereader();
while (sdr.read())
console.write(sdr.getname(1));
console.write(" : ");
console.writeline( sdr[1]);
sdr.close();

需要注意這裡日志政策改為了僅日志檔案輸出。
三、注意事項
3.1 進行日志檔案輸出的時候需要有寫的權限。
3.2 實際使用中可能還會有一個變量控制是否進行日志記錄。
3.3 錯誤記錄一般會在global.asax的application_error裡面加上。
結束語
對于一般的小項目這個日志類是夠用的了,日志的政策還可以根據自己的需求改變一下,合适就行: )
轉載:http://www.cnblogs.com/over140/archive/2009/07/16/1524735.html