log4net 在代码中动态添加logger

网上大篇的教程教人怎么使用log4net,大部分是用配置文件,当然也有用代码的。能解决大部分需求。

但是!!怎么在代码里创建隔离的logger 呢,就是说这个logger 只使用某一个appender,跟其他的logger 互不影响。

Create a log4net logger in code

5/11/2013 at 6:26:13 PM
Posted under .NET | Logging |

I found myself requiring to instantiate a log4net logger in code (not through the xml configuration). 
However, there are a few things that I haven’t worked around yet, here’s the code I came up with.

 1 var hierarchy = (Hierarchy)LogManager.GetRepository();
 2 var logger = hierarchy.LoggerFactory.CreateLogger((ILoggerRepository)hierarchy, "logname");
 3 logger.Hierarchy = hierarchy;
 4  
 5 logger.AddAppender(CreateFileAppender());
 6 logger.AddAppender(CreateDbAppender());
 7  
 8 logger.Repository.Configured = true;
 9  
10 // alternative use the LevelMap to set the Log level based on a string
11 // hierarchy.LevelMap["ERROR"]
12 hierarchy.Threshold = Level.Debug; 
13 logger.Level = Level.Debug;
14  
15 ILog log = new LogImpl(logger);
16  
17 log.Error(“This is my error message”);

Note that setting the level needs to be both on the hierarchy and the logger. This is based on the log4net hierarchy implementation.

Creating the Appenders is quite simple.

 1 private IAppender CreateFileAppender()
 2 {
 3     var fileAppender = new RollingFileAppender
 4     {
 5         Name = "myFileAppenderName",
 6         File = "logfile.log",
 7         LockingModel = new FileAppender.MinimalLock(),
 8         AppendToFile = true,
 9         RollingStyle = RollingFileAppender.RollingMode.Size,
10         MaxSizeRollBackups = 2,
11         MaximumFileSize = "1MB",
12         StaticLogFileName = true,
13         Layout = new log4net.Layout.PatternLayout("%d [%t] %-5p %c %m%n")
14     };
15     fileAppender.ActivateOptions();
16     return fileAppender;
17 }
18  
19 private IAppender CreateDBAppender()
20 {
21     RawLayoutConverter layoutConverter = new RawLayoutConverter();
22  
23     var databaseAppender = new AdoNetAppender
24     {
25         Name = "myDbAppender",
26         ConnectionString = connectionStringBuilder.ConnectionString,
27         CommandText = @"INSERT INTO [Log] ([DateTime], [Exception], [Level], [Logger], [Message], [Thread]) 
28                         VALUES (@logdate, @exception, @level, @logger, @message, @thread)",
29         CommandType = System.Data.CommandType.Text,
30         ConnectionType = "System.Data.SqlClient.SqlConnection",
31         UseTransactions = true
32     };
33  
34     databaseAppender.AddParameter(new AdoNetAppenderParameter
35         {
36             ParameterName = "@logdate",
37             DbType = System.Data.DbType.DateTime,
38             Layout = new RawTimeStampLayout()
39         });
40  
41     databaseAppender.AddParameter(new AdoNetAppenderParameter
42         {
43             ParameterName = "@message",
44             DbType = System.Data.DbType.String,
45             Size = 4000,
46             Layout = (IRawLayout)layoutConverter.ConvertFrom(new PatternLayout("%m"))
47         });
48  
49     databaseAppender.AddParameter(new AdoNetAppenderParameter
50         {
51             ParameterName = "@exception",
52             DbType = System.Data.DbType.String,
53             Size = 2000,
54             Layout = (IRawLayout)layoutConverter.ConvertFrom(new ExceptionLayout())
55         });
56  
57     databaseAppender.AddParameter(new AdoNetAppenderParameter
58         {
59             ParameterName = "@level",
60             DbType = System.Data.DbType.String,
61             Size = 50,
62             Layout = (IRawLayout)layoutConverter.ConvertFrom(new PatternLayout("%-5p"))
63         });
64  
65     databaseAppender.AddParameter(new AdoNetAppenderParameter
66         {
67             ParameterName = "@logger",
68             DbType = System.Data.DbType.String,
69             Size = 255,
70             Layout = (IRawLayout)layoutConverter.ConvertFrom(new PatternLayout("%c"))
71         });
72  
73     databaseAppender.AddParameter(new AdoNetAppenderParameter
74         {
75             ParameterName = "@thread",
76             DbType = System.Data.DbType.String,
77             Size = 255,
78             Layout = (IRawLayout)layoutConverter.ConvertFrom(new PatternLayout("%t"))
79         });
80  
81     databaseAppender.ActivateOptions();
82     return databaseAppender;
83 }

The one thing I could not get to work is accessing the logger through the default way for accessing a logger.

1 LogManager.GetLogger("logname");

This action will create a new logger, with the same name, but will not use my registered version. This means the logger has no appenders registered.

If anyone knows how this can be accomplished, please let me know.

My actual goals was to accomplish following xml configuration through code where I would only configure some appenders to a specific logger without needing to add them to the root.

1 <root>
2     <level value="DEBUG" />
3 </root>
4 <logger name="mylogger">
5     <level value="ERROR" />
6     <appender-ref ref="myFileAppender" />
7     <appender-ref ref="myDbAppender" />
8 </logger>

没有错,上面这一大坨是我从http://ronaldrosiernet.azurewebsites.net/blog/2013/05/11/create_a_log4net_logger_in_code#addcomment 这里粘下来的,很明显有人遇到了和我一样的问题,而且原po 主因为广告轰炸关闭了留言。。。就是

hierarchy.LoggerFactory.CreateLogger((ILoggerRepository)hierarchy, “logname”) 这货创建出来的东西在其他地方用不了。
解决方法很猥琐,就是这样:
 
1 var hierarchy = (Hierarchy)LogManager.GetRepository();
2 var logger = (Hierarchy.Logger)LogManager.GetLogger("logname").Logger;
3 logger.AddAppender(CreateFileAppender());
4 logger.AddAppender(CreateDbAppender());
5 hierarchy.Configured = true;
6 logger.Additivity = false;   // loggingEvent won't be bubbled to its parent logger in this case.

然后其他地方就可以直接GetLogger("logname") 了,会使用注册的那两个appender。

原文地址:https://www.cnblogs.com/strawhatboy/p/3783321.html