相信不少coder都有這樣的癖好:「自戀」!!對本身編寫的code老是那麼的自信,自豪,Always believe it to be so perfect!!html
不喜歡作單元測試(總以爲它就那樣了能出什麼錯?),不喜歡作日誌(總以爲他沒有什麼用!),不作日誌也就算了還把異常給「吃」了(只是爲了讓別人看不到那又黃又紅的像坨屎同樣的頁面),最終只能獨自一人默默的抓狂,累的像那什麼同樣,自做孽不可活!!數據庫
其實......餓......我就是這樣的啦(ˉ▽ˉ;)...編程
爲了讓生活的幸福美滿,爲了工做的輕鬆快樂,我決定虔誠的懺悔,痛定思痛,寫一個簡單日誌!(◎﹏◎)...數組
基於TraceSource的系統日誌安全
TraceSource官方給出的描述是這樣的:「提供一組方法和屬性,利用這些方法和屬性,應用程序能夠跟蹤代碼的執行並將跟蹤消息和它們的源關聯起來」。總以爲這描述跟系統日誌掛不上勾額,但事實它是用來作系統日誌的一個不錯的東西;編輯器
首先爲了迎合當今編程思想,先來建2個接口:ide
1.ILogger:用於實現日誌的寫入源post
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
/// <summary>
/// 系統日誌接口
/// </summary>
public
interface
ILogger
{
/// <summary>
/// 系統崩潰錯誤日誌
/// </summary>
/// <param name="message">錯誤信息</param>
/// <param name="args">設置格式的對象的數組</param>
void
Fatal(
string
message,
params
object
[] args);
/// <summary>
/// 系統崩潰錯誤日誌
/// </summary>
/// <param name="message">錯誤信息</param>
/// <param name="exception">異常對象</param>
/// <param name="args">設置格式的對象的數組</param>
void
Fatal(
string
message, Exception exception,
params
object
[] args);
/// <summary>
/// 系統消息日誌
/// </summary>
/// <param name="message">要記錄的信息</param>
/// <param name="args">設置格式的對象的數組</param>
void
Infomation(
string
message,
params
object
[] args);
/// <summary>
/// 系統警告日誌
/// </summary>
/// <param name="message">警告信息</param>
/// <param name="args">設置格式的對象的數組</param>
void
Warning(
string
message,
params
object
[] args);
/// <summary>
/// 系統錯誤日誌
/// </summary>
/// <param name="message">錯誤信息</param>
/// <param name="args">設置格式的對象的數組</param>
void
Error(
string
message,
params
object
[] args);
/// <summary>
/// 系統錯誤日誌
/// </summary>
/// <param name="message">錯誤信息</param>
/// <param name="exception">異常對象</param>
/// <param name="args">設置格式的對象的數組</param>
void
Error(
string
message, Exception exception,
params
object
[] args);
}
|
2.ILoggerFactory:用於生產指定的日誌寫入源單元測試
1
2
3
4
5
6
7
8
9
10
|
/// <summary>
/// 系統日誌工廠
/// </summary>
public
interface
ILoggerFactory
{
/// <summary>
/// 建立一個系統日誌
/// </summary>
ILogger Create();
}
|
爲了方便編碼和保持日誌的統一性,咱們再建一個日誌上下文測試
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
/// <summary>
/// 系統日誌上下文.
/// </summary>
public
static
class
LoggerContext
{
static
ILoggerFactory _currentLogFactory =
null
;
/// <summary>
/// 設置固然上下文使用的日誌工廠
/// <remarks>
/// 該上下文始終使用一個日誌工廠進行建立日誌,建議在系統啓動時進行設置,設置後將沒法再進行設置
/// </remarks>
/// </summary>
/// <param name="factory">日誌工廠</param>
public
static
void
SetCurrent(ILoggerFactory factory)
{
if
(_currentLogFactory !=
null
)
throw
new
ArgumentException(
"該日誌上下文已經設置使用的日誌工廠,沒法進行再次設置,如需使用其餘日誌工廠,請直接實例日誌工廠進行操做。"
,
"factory"
);
_currentLogFactory = factory;
}
/// <summary>
/// 建立一個日誌
/// </summary>
public
static
ILogger CreateLog()
{
if
(_currentLogFactory ==
null
)
throw
new
NullReferenceException(
"該日誌上下文還沒有設置日誌工廠,請使用SetCurrent方法進行設置。"
);
return
_currentLogFactory.Create();
}
}
|
好的,如今咱們進入正題,使用TraceSource進行日誌記錄,不要介意哈,進入正題前總要有些前奏, 目的你懂得o(^▽^)o.....
TraceSource 位於命名空間System.Diagnostics下,該命名空間在System.dll中,因此無需添加引用,比較方便。
下面是基於TraceSource的ILogger實現:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
public
sealed
class
TraceSourceLogger
:ILogger
{
private
const
string
EXCEPTION_FORMAT =
"{0} 捕獲異常信息:{1}"
;
TraceSource _source;
public
TraceSourceLogger()
{
_source =
new
TraceSource(
"Bulrush"
);
}
public
void
Fatal(
string
message,
params
object
[] args)
{
if
(String.IsNullOrWhiteSpace(message))
return
;
string
messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args);
Trace(TraceEventType.Critical, messageToTrace);
}
public
void
Fatal(
string
message, Exception exception,
params
object
[] args)
{
if
(String.IsNullOrWhiteSpace(message) || exception ==
null
)
return
;
string
messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args);
string
exceptionString = exception.ToString();
Trace(TraceEventType.Critical, String.Format(CultureInfo.InvariantCulture, EXCEPTION_FORMAT, messageToTrace, exceptionString));
}
public
void
Infomation(
string
message,
params
object
[] args)
{
if
(String.IsNullOrWhiteSpace(message))
return
;
string
messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args);
Trace(TraceEventType.Information, messageToTrace);
}
public
void
Warning(
string
message,
params
object
[] args)
{
if
(String.IsNullOrWhiteSpace(message))
return
;
string
messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args);
Trace(TraceEventType.Warning, messageToTrace);
}
public
void
Error(
string
message,
params
object
[] args)
{
if
(String.IsNullOrWhiteSpace(message))
return
;
string
messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args);
Trace(TraceEventType.Error, messageToTrace);
}
public
void
Error(
string
message, Exception exception,
params
object
[] args)
{
if
(String.IsNullOrWhiteSpace(message) || exception ==
null
)
return
;
string
messageToTrace = String.Format(CultureInfo.InvariantCulture, message, args);
string
exceptionString = exception.ToString();
Trace(TraceEventType.Error, String.Format(CultureInfo.InvariantCulture, EXCEPTION_FORMAT, messageToTrace, exceptionString));
}
void
Trace(TraceEventType eventType,
string
message)
{
if
(_source !=
null
)
{
try
{
_source.TraceEvent(eventType, (
int
)eventType, message);
}
catch
(SecurityException)
{
//這裏處理寫入是出現的安全問題,如文件沒有寫入權限。
}
}
}
}
|
這個實現比較簡單,可是這裏有一個很好的哦,那是什麼呢?嘻嘻就TraceSource裏的Listeners傾聽器,微軟給咱們提供了幾個經常使用的傾聽器,我以爲基本已經夠用了,
1.DefaultTraceListener:默認使用這個,這個傾聽器會輸出在調試器的輸出窗口。
2.EventLogTraceListener: 這個是操做系統日誌的傾聽器,會把日誌記錄在操做系統的事件裏,我仍是比較喜歡這個,畢竟比較完善,安全性也比較好。
3.TextWriterTraceListener:這個是文本編輯器的傾聽器,簡單點就是以文件流的形式進行記錄,固然了文件路徑是本身定義的,這個也比較經常使用。
4.XmlWriterTraceListener:這個Xml文件的傾聽器,用法和TextWriterTraceListener差很少,只是使用Xml流格式進行記錄。
等等,固然還有幾個傾聽器,這裏就不一一列出了,有興趣的能夠查看MSDN的System.Diagnostics。
若是你想拓展也能夠,如記錄在數據庫,或者使用Log4net等等,只要繼承TraceListener基類進行重寫就能夠了。
下面是一個最簡單的自定義傾聽器:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public
class
CustomeTraceListener
: TraceListener
{
public
override
void
Write(
string
message)
{
File.AppendAllText(
@"d:\log.txt"
, message);
}
public
override
void
WriteLine(
string
message)
{
File.AppendAllText(
@"d:\log.txt"
, message+ Environment.NewLine);
}
}
|
下面咱們在寫一個TraceSourceLogger工廠就能夠了,代碼以下:
1
2
3
4
5
6
7
8
9
|
public
class
TraceSourceLoggerFactory
: ILoggerFactory
{
public
ILogger Create()
{
var
logger =
new
TraceSourceLogger();
return
logger;
}
}
|
OK,代碼已經寫好了,那又的同窗就要問了傾聽器在哪裏設置呢?
這個問題很簡單,固然是在配置文件裏配置了;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<configuration>
<system.diagnostics>
<sources>
<source name=
"Bulrush"
switchName=
"SourceSwitch"
switchType=
"System.Diagnostics.SourceSwitch"
>
<listeners>
<clear/>
<add name=
"eventLog"
></add>
</listeners>
</source>
</sources>
<switches>
<!--這裏設置TraceSource的寫入開關,默認爲Off關閉,不進行寫入,具體值能夠查看SourceLevels枚舉-->
<add name=
"SourceSwitch"
value=
"All"
/>
</switches>
<sharedListeners>
<!--
這裏使用操做系統的事件傾聽器,initializeData屬性是事件源,
false
爲默認。
不一樣的傾聽器initalizeData有不一樣的意義,如TextWriterTraceListnener傾聽器,能夠設置爲「d:\log.txt」,意思就是保存的路徑。
-->
<add name=
"eventLog"
type=
"System.Diagnostics.EventLogTraceListener"
initializeData=
"false"
/>
</sharedListeners>
</system.diagnostics>
</configuration>
|
到這裏就結束了,下面作個簡單的測試,是使用EventLogTraceListener傾聽器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
[ClassInitialize()]
public
static
void
ClassInitialze(TestContext context)
{
LoggerContext.SetCurrent(
new
TraceSourceLoggerFactory());
}
[TestMethod]
public
void
TestTraceSourceLogger()
{
//LoggerContext.CreateLog().Error("錯誤日誌");
var
logger = LoggerContext.CreateLog();
try
{
logger.Error(
"錯誤日誌"
);
logger.Fatal(
"系統崩潰日誌"
);
logger.Infomation(
"普通消息日誌"
);
logger.Warning(
"非關鍵性,警告日誌"
);
}
catch
{
Assert.Fail();
}
}
|
結果爲:
太晚了,該睡覺了哦!!
出處:http://www.cnblogs.com/zcylife/p/3657579.html