如何以编程方式更改文件位置?
我对 Log4net 完全陌生。我已经设法通过添加配置文件和简单的日志记录来完成一些事情。我已将值硬编码为 "C:\temp\log.txt"
但这还不够好。
日志必须转到特殊文件夹
path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
,并且此路径会根据您使用的是 Windows Server 2008、Windows XP 还是 Vista 等而变化...
我怎样才能以编程方式更改 log4net 中文件的位置?
这就是我所做的:
<configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
</configSections>
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</root>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="C:\temp\log.txt" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%-5p%d{yyyy-MM-dd hh:mm:ss} – %m%n" />
</layout>
</appender>
</log4net>
class Program
{
protected static readonly ILog log = LogManager.GetLogger(typeof(Program));
static void Main(string[] args)
{
log4net.Config.XmlConfigurator.Configure();
log.Warn("Log something");
path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
// How can I change where I log stuff?
}
}
只需要弄清楚如何更改以将内容记录到我想要的位置。
有什么建议吗? 多谢
I am totally new to Log4net. I have managed to get something going by adding a config file and simple logging. I have hardcoded the value to be "C:\temp\log.txt"
but this is not good enough.
The logs must go to the special folders
path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
and this path changes depending whether you are using Windows Server 2008 or Windows XP or Vista etc...
How can I just change the location of the file in log4net programmatically?
This is what I have done:
<configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
</configSections>
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</root>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="C:\temp\log.txt" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%-5p%d{yyyy-MM-dd hh:mm:ss} – %m%n" />
</layout>
</appender>
</log4net>
class Program
{
protected static readonly ILog log = LogManager.GetLogger(typeof(Program));
static void Main(string[] args)
{
log4net.Config.XmlConfigurator.Configure();
log.Warn("Log something");
path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
// How can I change where I log stuff?
}
}
Just need to figure out how I can change to log stuff to where I want to.
Any suggestions?
Thanks a lot
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
log4net 可以为您处理这个问题。任何字符串类型的附加器属性都可以格式化,在本例中,使用 log4net.Util.PatternString 选项处理程序。 PatternString 甚至支持 SpecialFolder 枚举,它支持以下优雅的配置:
这是一个证明布丁的单元测试:
以下测试验证 log4net 是否实际写入磁盘(这基本上使这是一个“集成”测试,而不是单元测试,但我们暂时保留它):
注意:我强烈建议使用上面示例中演示的紧凑属性语法。删除所有这些“
log4net can handle this for you. Any appender property of type string can be formatted, in this case, using the log4net.Util.PatternString option handler. PatternString even supports the SpecialFolder enum which enables the following elegant config:
Here's a unit test that proofs the pudding:
The following test verifies that log4net actually writes to disk (which basically makes this an "integration" test, not a unit test, but we'll leave it at that for now):
NB: I strongly suggest using the compact property syntax demonstrated in the above sample. Removing all those "<property name=" makes your config that much more readable.
我在互联网上发现了这段代码的变体:
这对我有用。我们的应用程序需要将日志文件放在包含基于 AssemblyInfo.cs 文件的应用程序版本号的文件夹中。
您应该能够以编程方式设置 logFileLocation(例如,如果这是一个 Web 应用程序,您可以使用 Server.MapPath())以满足您的需要。
I found a mutation of this code in the interwebs:
This works for me. Our application needs to put the log file in a folder that contains the version number of the app based on the AssemblyInfo.cs file.
You should be able to set the logFileLocation programmatically (e.g. you can use Server.MapPath() if this is a web application) to suit your needs.
看起来像彼得的回答不适用于 Log4net v1.2.10.0。
此处描述了另一种方法。
基本上,该方法是为 log4net 配置文件实现自定义模式转换器。
首先将此类添加到您的项目中:
然后按如下方式设置 FileAppender 的 File 参数:
基本上
%folder
告诉它查看名为folder
的转换器,该转换器指向它到 SpecialFolderPatternConverter 类。然后,它在该类上调用Convert
,传入 CommonApplicationData(或其他)枚举值。Looks like Peter's answer doesn't work for Log4net v1.2.10.0.
An alternative method is described here.
Basically the method is to implement a custom pattern converter for the log4net config file.
First add this class to your project:
Then set up the File parameter of your FileAppender as follows:
Basically the
%folder
tells it to look at the converter calledfolder
which points it to the SpecialFolderPatternConverter class. It then callsConvert
on that class, passing in the CommonApplicationData (or whatever) enum value.简单的怎么样:
为什么做一件非常简单的事情却如此复杂?
How about a simple:
Why is it so complex to do a really simple thing?
还要更改错误日志的路径(基于 JackAce 的答案):
To also change the error log's path (based on JackAce's answer):
这对我有用:
如果需要写入特殊文件夹,我在 here 找到了帮助(第二个和第三个示例)。
编辑:
回答OP..这适用于“所有用户”区域:
在较新版本的Windows中通常是“C:\ ProgramData”。
也请参阅这些:
如何为log4net指定通用应用程序数据文件夹? == https://stackoverflow.com/a/1889591/503621 和评论
&
https://superuser.com/q/405097/47628
https://stackoverflow.com/a/5550502/503621
This worked for me:
If needing to write to special folders I found help here (2nd and 3rd example).
Edit:
To answer OP.. This works for 'all users' area:
Which is normally "C:\ProgramData" in newer versions of Windows.
See these too:
How to specify common application data folder for log4net? == https://stackoverflow.com/a/1889591/503621 and comments
&
https://superuser.com/q/405097/47628
https://stackoverflow.com/a/5550502/503621
JackAce的答案,使用Linq更简洁:
C#
VB.NET
JackAce's answer, just more concise using Linq:
C#
VB.NET
LINQ 的绝佳用例
OfType
过滤器:如果 app.config 中的文件名是
log.txt
,这会将日志输出更改为logs/some_name_log.txt
:回答OP的原始问题是:
Great use case for LINQs
OfType<T>
filter:If the filename in the app.config is
log.txt
this will change the log output tologs/some_name_log.txt
:To Answer the OPs original problem that would be:
在当前版本的 Log4Net (2.0.8.0) 中,您可以简单地使用
表示C:\ProgramData\ ..
和${LocalAppData}
用于C:\Users\user\AppData\Local\
In the current version of Log4Net (2.0.8.0) you could simply use
<file value="${ProgramData}\myFolder\LogFiles\" />
forC:\ProgramData\..
and${LocalAppData}
forC:\Users\user\AppData\Local\
作为以编程方式执行此操作的替代方法,您可以在配置文件中使用环境变量和可自定义模式。 查看对类似问题的回复。
请参阅Log4Net V1.2.10 发行说明<中的“基于模式的配置的PatternString” /a>.
此外,如果您正在考虑写入 Enviroment.SpecialFolder.CommonApplicationData 等目录,您需要考虑:
所有用户的应用程序的所有实例是否都具有对日志文件的写访问权限?例如,我不相信非管理员能够写入 Enviroment.SpecialFolder.CommonApplicationData。
如果应用程序的多个实例(针对相同或不同的用户)尝试访问同一文件,则会发生争用。您可以使用“最小锁定模型”(请参阅http://logging.apache.org/log4net/release/config-examples.html 允许多个进程写入同一个日志文件,但可能会对性能产生影响,或者您可以为每个进程提供不同的日志文件,例如使用可自定义的模式在文件名中包含进程 ID。
As an alternative to doing this programatically, you can use environment variables and customizable patterns in the configuration file. See this response to a similar question.
Look at "PatternString for pattern based configuration" in the Log4Net V1.2.10 release notes.
Also if you are thinking of writing to a directory such as Enviroment.SpecialFolder.CommonApplicationData you need to consider:
Will all instances of your application for all users have write access to the log file? E.g. I don't believe non-administrators will be able to write to Enviroment.SpecialFolder.CommonApplicationData.
Contention if multiple instances of your application (for the same or different users) are attempting to the same file. You can use the "minimal locking model" (see http://logging.apache.org/log4net/release/config-examples.html to allow multiple processes to write to the same log file, but there probably will be a performance impact. Or you could give each process a different log file, e.g. by including the process id in the filename using a customizable pattern.
如果您必须部署到未知系统,并且想要使用 Philipp M 的简单解决方案,即使对于不同的特殊文件夹,您也可以检索所需的特殊文件夹路径,并在加载 log4net 配置之前设置自定义环境变量。
<代码>
string localData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
Environment.SetEnvironmentVariable("MY_FOLDER_DATA", localData);
XmlConfigurator.Configure( ...
...只是为了确保 env 变量存在并且具有您想要的值。
If you have to deploy to unknown systems and you want to use the simple solution by Philipp M even with different special folders you can retrieve the special folder path you want and set a custom env variable before loading the log4net configuration.
string localData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
Environment.SetEnvironmentVariable("MY_FOLDER_DATA", localData);
XmlConfigurator.Configure( ...
... just to be sure the env variable exists and has the value you want.
那些想要将文件路径设置为项目根目录路径的人可以参考下面的代码。 .NET 5 API 项目更改中实现了此功能
我已在Log4net.config 文件的 。请记住 type="log4net.Util.PatternString" 这行非常重要
然后,在
Program.cs
文件中谢谢!
Those who are looking to set the file path to Project root dicrectory Path can refer below code. I have implemented this in .NET 5 API Project
Changes for Log4net.config file. Remember type="log4net.Util.PatternString" this line is very important
Then, in
Program.cs
fileThanks!