問題說明
配置文件示例
在Net程序中,經常使用log4net存儲日誌文件,下面是一個log4net配置文件的示例,文件名爲log.config。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender" >
<lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
<file value="Logs/App_" />
<datePattern value="yyyyMMdd.'txt'"/>
<appendToFile value="true" />
<!--<rollingStyle value="Date" />-->
<staticLogFileName value="false"/>
<rollingStyle value="Date" />
<maxSizeRollBackups value="10"/>
<maximumFileSize value="1MB"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level - %date - [%-5.5thread] - %logger - [%class.%method] - %f - %l %message%newline" />
</layout>
</appender>
<appender name="PlcAppender" type="log4net.Appender.RollingFileAppender" >
<lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
<file value="Logs/Plc_" />
<datePattern value="yyyyMMdd HH.'txt'"/>
<appendToFile value="true" />
<rollingStyle value="Composite" />
<staticLogFileName value="false"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="1MB"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level - %date - [%-5.5thread] - %logger - [%class.%method] - %f - %l %message%newline" />
</layout>
</appender>
<appender name="DebugAppender" type="log4net.Appender.RollingFileAppender" >
<lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
<file value="Logs/Debug_" />
<datePattern value="yyyyMMdd.'txt'"/>
<appendToFile value="true" />
<!--<rollingStyle value="Date" />-->
<staticLogFileName value="false"/>
<rollingStyle value="Composite" />
<maxSizeRollBackups value="10"/>
<maximumFileSize value="1MB"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level - %date - [%-5.5thread] - %logger - [%class.%method] - %f - %l %message%newline" />
</layout>
</appender>
<appender name="DbAppender" type="log4net.Appender.RollingFileAppender" >
<lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
<file value="Logs/Db_" />
<datePattern value="yyyyMMdd.'txt'"/>
<appendToFile value="true" />
<staticLogFileName value="false"/>
<rollingStyle value="Composite" />
<maxSizeRollBackups value="10"/>
<maximumFileSize value="1MB"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level - %date - [%-5.5thread] - %logger - [%class.%method] - %f - %l %message%newline" />
</layout>
</appender>
<!--<root>
<appender-ref ref="RollingFileAppender" />
<level value="DEBUG" />
</root>-->
<logger name="AppLogger" additivity="false">
<level value="ALL" />
<appender-ref ref="RollingFileAppender" />
</logger>
<!--PLC日誌-->
<logger name="PlcLogger" additivity="false">
<level value="ALL" />
<!--<appender-ref ref="RollingFileAppender" />-->
<appender-ref ref ="PlcAppender"/>
</logger>
<!-- 調試日誌-->
<logger name="DebugLogger" additivity="false">
<level value="ALL" />
<appender-ref ref ="DebugAppender"/>
</logger>
<!-- 數據庫日誌-->
<logger name="DbLogger" additivity="false">
<level value="ALL" />
<appender-ref ref ="DbAppender"/>
</logger>
</log4net>
</configuration>
從配置文件可以看出來,有4個Appender,軟件會建立4個日誌文件,路徑都在Logs/文件夾下,通常這個Logs文件夾在主程序所在路徑下。要注意的是每個日誌文件的文件名不同,例如DbAppender的日誌文件名爲Db_xxxx.txt,而DebugAppender的日誌文件名爲Debug_xxxx.txt。
修改存儲路徑
如果用戶想改變這個路徑到其它位置該怎麼辦呢?
方法1:修改這個配置文件log.config裏邊的每個Appender的配置;
方法2:在軟件運行時動態修改Appender的參數。
網上最典型的修改文件名的辦法,非常好,缺點是不夠徹底。
下面的例子引用自https://blog.csdn.net/yw1688/article/details/52590072
/// <summary>
/// 改變默認的日誌位置
/// </summary>
/// <param name="folder"></param>
public static void UpdateFolder(string folder)
{
var storedPath = LogManager.GetRepository();
var appenders = storedPath.GetAppenders();
//一般多種日誌目錄是寫在一起
if (appenders == null) return;
foreach (var app in appenders)
{
if (app.Name.Equals("ErrorAppender") || app.Name.Equals("InfoAppender"))
{
var ra = app as RollingFileAppender;
ra.File = folder;
ra.ActivateOptions();
}
}
}
這個例子的結果是,所有Appender的存儲文件名變成同一個,因此不是修改存儲路徑,而是修改存儲文件名。
修改多個Appender的存儲路徑
沒有datePattern設置的情況
下面是本篇在上述原理基礎上的改進。
public static void ChangeDir(string configFile,string newDir)
{
XmlConfigurator.Configure(new FileInfo(configFile));
var curPath = LogManager.GetRepository();
var appenders = curPath.GetAppenders();
if (appenders == null)
return;
foreach (var appender in appenders)
{
var rollingFileAppender = appender as RollingFileAppender;
if(rollingFileAppender == null)
continue;
var oldPath = rollingFileAppender.File;
var oldFile = Path.GetFileName(oldPath);
if(oldFile == null)
continue;
var newFile = Path.Combine(newDir, oldFile);
rollingFileAppender.File = newFile;
rollingFileAppender.ActivateOptions();
}
}
調用方法如下。
LogHelper.ChangeDir("Log.config",newDir);
有datePattern設置的情況
本篇的log4net的配置文件中由於有datePattern配置,修改日誌路徑要用如下方法。
public static void ChangeDir(string configFile,string newDir)
{
XmlConfigurator.Configure(new FileInfo(configFile));
var curPath = LogManager.GetRepository();
var appenders = curPath.GetAppenders();
if (appenders == null)
return;
foreach (var appender in appenders)
{
var rollingFileAppender = appender as RollingFileAppender;
if(rollingFileAppender == null)
continue;
var oldPath = rollingFileAppender.File;
var oldFile = Path.GetFileName(oldPath);
if(oldFile == null)
continue;
var newFile = Path.Combine(newDir, oldFile);
rollingFileAppender.Writer = new StreamWriter(newFile, rollingFileAppender.AppendToFile,rollingFileAppender.Encoding);
}
}
即不能用修改appender的File屬性,而是,直接指定Writer屬性的內容。
修改配置文件方法
有些複雜datepattern,修改後,log4net會在file屬性的值變了後,又恢復的配置文件的file的設置模式,因此最徹底的方法還是修改xml文件。
代碼如下。
public static void ChangeDirXml(string configFile, string newDir)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(configFile);
XmlNode nodes= xmlDoc.SelectSingleNode("configuration");
var appenderNodes = nodes.ChildNodes[0];
foreach (XmlNode xn in appenderNodes)
{
if (xn.Name == "appender")
{
foreach (XmlNode ele in xn)
{
if (ele.Name == "#comment")
continue;
XmlElement xe = (XmlElement)ele;
if (xe.Name != "file")
{
continue;
}
var oldFileValue = xe.GetAttribute("value");
var oldFile = Path.GetFileName(oldFileValue);
if (oldFile == null)
continue;
var newFile = Path.Combine(newDir, oldFile);
xe.SetAttribute("value", newFile);
}
}
}
xmlDoc.Save(configFile);
XmlConfigurator.Configure(new FileInfo(configFile));
}
本人親自測試沒毛病。歡迎各位批評指正。