注册博客员也满长时间了,这算是一个开篇文章把.
最近项目使用到log4net来记录日志,当然二话不说先到cnblogs上查看一下各位高手关于log4net的教程和心得
主要参看了摩诘 的Log4Net使用指南 (确实是非常好的log4net的入门指南),在此篇文章的评论中@所罗门 有个
问题可能摩诘比较忙没有时间去是实验和解答,问题如下:
如果我在配置文件里不设定Appender的File,即删除了<param name="File" value="log-file.txt" /> 一行信息,
我想要在程序运行时动态的设定log日志的文件名(例如以日期来作文件名),该怎么处理才能实现
刚好项目也需要动态的更改log的文件名,就尝试着去跟踪一下log4net的写日志的过程,看看它是如果写日志的.
在跟踪的工程中发现log4net.Repository.Hierarchy.Logger类下面有Appenders属性,就是返回当前所有的append
集合,刚好通过调试跟踪发现

类型,所以想当然的有以下修改log路径的函数
1
private
void
ChangeLog4netLogFileName(log4net.ILog iLog,
string
fileName)
2 {
3 log4net.Core.LogImpl logImpl = iLog as log4net.Core.LogImpl;
4 if (logImpl != null )
5 {
6 log4net.Appender.AppenderCollection ac = ((log4net.Repository.Hierarchy.Logger)logImpl.Logger).Appenders;
7 for ( int i = 0 ;i < ac.Count;i ++ )
8 { // 这里我只对RollingFileAppender类型做修改
9 log4net.Appender.RollingFileAppender rfa = ac[i] as log4net.Appender.RollingFileAppender;
10 if (rfa != null )
11 {
12 rfa.File = fileName;
13 if ( ! System.IO.File.Exists(fileName))
14 {
15 System.IO.File.Create(fileName);
16 }
17 }
18 }
19 }
20 }
ok,让我们测试一下2 {
3 log4net.Core.LogImpl logImpl = iLog as log4net.Core.LogImpl;
4 if (logImpl != null )
5 {
6 log4net.Appender.AppenderCollection ac = ((log4net.Repository.Hierarchy.Logger)logImpl.Logger).Appenders;
7 for ( int i = 0 ;i < ac.Count;i ++ )
8 { // 这里我只对RollingFileAppender类型做修改
9 log4net.Appender.RollingFileAppender rfa = ac[i] as log4net.Appender.RollingFileAppender;
10 if (rfa != null )
11 {
12 rfa.File = fileName;
13 if ( ! System.IO.File.Exists(fileName))
14 {
15 System.IO.File.Create(fileName);
16 }
17 }
18 }
19 }
20 }
private
void
TestChangeLog4netLogFileName()
{
string fileName = @" c:/chang.log " ;
log4net.ILog iLog = log4net.LogManager.GetLogger( " AppLogger " );
ChangeLog4netLogFileName(iLog, fileName);
iLog.Info( " Test:info " );
}
运行,哦C盘根目录下并没有要预期一样没有出现chang.log文件.why?猜想RollingFileAppender在初始化的时候就{
string fileName = @" c:/chang.log " ;
log4net.ILog iLog = log4net.LogManager.GetLogger( " AppLogger " );
ChangeLog4netLogFileName(iLog, fileName);
iLog.Info( " Test:info " );
}
固定了文件名,后期对文件名的修改是不起作用的.继续跟踪代码,发现RollingFileAppender在记录日志时直接使用
初始化时就实例化的一个QuietTextWriter类型的私有变量m_qtw(直接继承于基类TextWriterAppender),继续跟踪发现
基类(TextWriterAppender)提供了Writer属性来修改m_qtw的值,所有修改一下上面的ChangeLog4netLogFileName函数
1
private
void
ChangeLog4netLogFileName(log4net.ILog iLog,
string
fileName)
2 {
3 log4net.Core.LogImpl logImpl = iLog as log4net.Core.LogImpl;
4 if (logImpl != null )
5 {
6 log4net.Appender.AppenderCollection ac = ((log4net.Repository.Hierarchy.Logger)logImpl.Logger).Appenders;
7 for ( int i = 0 ;i < ac.Count;i ++ )
8 { // 这里我只对RollingFileAppender类型做修改
9 log4net.Appender.RollingFileAppender rfa = ac[i] as log4net.Appender.RollingFileAppender;
10 if (rfa != null )
11 {
12 rfa.File = fileName;
13 if ( ! System.IO.File.Exists(fileName))
14 {
15 System.IO.File.Create(fileName);
16 }
17 // 更新Writer属性
18 rfa.Writer = new System.IO.StreamWriter(rfa.File,rfa.AppendToFile,rfa.Encoding);
19 }
20 }
21 }
22 }
在运行上面的测试代码,ok,chang.log文件如愿的出现.2 {
3 log4net.Core.LogImpl logImpl = iLog as log4net.Core.LogImpl;
4 if (logImpl != null )
5 {
6 log4net.Appender.AppenderCollection ac = ((log4net.Repository.Hierarchy.Logger)logImpl.Logger).Appenders;
7 for ( int i = 0 ;i < ac.Count;i ++ )
8 { // 这里我只对RollingFileAppender类型做修改
9 log4net.Appender.RollingFileAppender rfa = ac[i] as log4net.Appender.RollingFileAppender;
10 if (rfa != null )
11 {
12 rfa.File = fileName;
13 if ( ! System.IO.File.Exists(fileName))
14 {
15 System.IO.File.Create(fileName);
16 }
17 // 更新Writer属性
18 rfa.Writer = new System.IO.StreamWriter(rfa.File,rfa.AppendToFile,rfa.Encoding);
19 }
20 }
21 }
22 }
第一次写blogs,罗里罗嗦一大段,希望不会挑战你的耐心^_^
最后附上log4net的配置(也直接从cnblogs上的某位大侠上面copy下来的)
1
<?
xml version="1.0" encoding="utf-8"
?>
2
<
configuration
>
3
<!--
如果不用App.config作配置文件,则configSections节不是必须的。
-->
4
<
configSections
>
5
<!--
“type”属性的完整格式为:配置节处理器类名,程序集名称,Version=程序集版本号,Culture=区域信息,PublicKeyToken=公钥
-->
6
<
section
name
="log4net"
type
="log4net.Config.Log4NetConfigurationSectionHandler,log4net"
/>
7
</
configSections
>
8
<
log4net
>
9
<!--
日志记录器logger,可以有多个
-->
10
<
logger
name
="AppLogger"
>
11
<
level
value
="ALL"
/>
12
<
appender-ref
ref
="RollingLogFileAppender"
/>
13
<
appender-ref
ref
="ConsoleAppender"
/>
14
</
logger
>
15
<
logger
name
="Form1"
>
16
<
level
value
="DEBUG"
/>
17
<
appender-ref
ref
="LogFileAppender"
/>
18
</
logger
>
19
<!--
所有logger的基,root的设置在所有logger中都起作用。
20
当在root和logger中重复设定相同的appender时,你会发现同一日志信息将被记录两次。
-->
21
<!--
<root>
22
<level value="WARN" />
23
<appender-ref ref="LogFileAppender" />
24
<appender-ref ref="ConsoleAppender" />
25
</root>
-->
26
<!--
一个appender可以由多个logger共用,当然一个logger可以指定多个appender。
-->
27
<
appender
name
="LogFileAppender"
type
="log4net.Appender.FileAppender"
>
28
<
param
name
="File"
value
="App.log"
/>
29
<
param
name
="AppendToFile"
value
="true"
/>
30
<
layout
type
="log4net.Layout.PatternLayout"
>
31
<
param
name
="ConversionPattern"
value
="%d [%t] %-5p %c [%x] %X{auth} - %m%n"
/>
32
</
layout
>
33
<
filter
type
="log4net.Filter.LevelRangeFilter"
>
34
<
param
name
="LevelMin"
value
="ALL"
/>
35
<
param
name
="LevelMax"
value
="FATAL"
/>
36
</
filter
>
37
</
appender
>
38
<
appender
name
="RollingLogFileAppender"
type
="log4net.Appender.RollingFileAppender"
>
39
<
file
value
="log/logfile1.log"
/>
40
<
appendToFile
value
="true"
/>
41
<
rollingStyle
value
="Date"
/>
42
<
datePattern
value
="yyyyMMdd"
/>
43
<
encoding
value
="utf-8"
/>
44
<
layout
type
="log4net.Layout.PatternLayout"
>
45
<
conversionPattern
value
="%d [%r] [%-5level]: - %message%newline"
/>
46
</
layout
>
47
</
appender
>
48
<
appender
name
="ConsoleAppender"
type
="log4net.Appender.ConsoleAppender"
>
49
<
layout
type
="log4net.Layout.PatternLayout"
>
50
<
param
name
="ConversionPattern"
value
="%d [%t] %-5p %c [%x] %X{auth} - %m%n"
/>
51
</
layout
>
52
</
appender
>
53
</
log4net
>
54
</
configuration
>

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
