I'm trying to use log4net to log errors on my MVC 4 website. It works fine offline, but when we publish the website, log4net doesn't even create the log file.
Here is the Web.config code:
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<file value="mylog.txt"/>
<appendToFile value="true"/>
<layout type="log4net.Layout.PatternLayout">
<header value="**"/>
<footer value="**"/>
<conversionPattern value="%newline%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<root>
<level value="ALL"/>
<appender-ref ref="LogFileAppender"/>
</root>
</log4net>
I added this to the Assembly:
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
Here is my code to call the logger:
public void logInfo(string message)
{
log4net.Config.XmlConfigurator.Configure();
logger.Info(message);
}
This is bcoz,the root folder doesn't have write permissions where you are trying to create the log file.
steps to provide write permissions:
1) right click on "folder"
2) go to properties
3) click on security
4) Click on add-> add everyone-> check on full control.
it will work fine now.
Related
I'm using Microsoft's XDT library to transform my web.config files and discovered that Locator is not working as expected. Using the example below, I would expect that both the attributes are set and the converter node is inserted in all three appenders, but only the attributes are updated in all three. The converter node is only inserted into the first appender. How do I get it to insert into all three log4net appender nodes?
I've tried switching to XPath, but it only throws errors. A working example would be nice, because every example I've followed so far seems to fail with an error.
Test site: https://webconfigtransformationtester.apphb.com/
For example:
Web.config
<?xml version="1.0"?>
<configuration>
<log4net>
<appender name="App1">
<layout>
<conversionPattern value="foo"/>
</layout>
</appender>
<appender name="App2">
<layout>
<conversionPattern value="foo"/>
</layout>
</appender>
<appender name="App3">
<layout>
<conversionPattern value="foo"/>
</layout>
</appender>
</log4net>
</configuration>
Web.Debug.config
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<log4net>
<appender xdt:Locator="Condition(#name='App1' or #name='App2' or #name='App3')">
<layout>
<conversionPattern value="bar" xdt:Transform="SetAttributes" />
<converter xdt:Transform="Insert">
<name value="Default" />
<type value="Common.DefaultConverter, Common" />
</converter>
</layout>
</appender>
</log4net>
</configuration>
Results:
<?xml version="1.0"?>
<configuration>
<log4net>
<appender name="App1">
<layout>
<conversionPattern value="bar" />
<converter><name value="Default" /><type value="Common.DefaultConverter, Common" /></converter></layout>
</appender>
<appender name="App2">
<layout>
<conversionPattern value="bar" />
</layout>
</appender>
<appender name="App3">
<layout>
<conversionPattern value="bar" />
</layout>
</appender>
</log4net>
</configuration>
It turns out that it was designed this way. Only attributes are applied to all target nodes. To work around the issue, download the code from here and add the following lines:
In XmlElementContext, add the property:
internal bool HasLocator
{
get
{
return this.LocatorAttribute != null || (this.parentContext != null && this.parentContext.HasLocator);
}
}
In XmlTransform modify this line, adding the call to HasLocator:
if (ApplyTransformToAllTargetNodes || context.HasLocator) {
This code will determine if a "Locator" has been set within the current context or any parent context (like in my example) and apply all transforms to all target nodes.
I'm having trouble getting log4net to create the log file when errors are recorded.
I'm using ninject to inject dependancies for my objects related to log4net, as ive created a wrapper:-
public interface ILogManager
{
ILog GetLog(Type typeAssociatedWithRequestLog);
}
public class LogManagerAdapter : ILogManager
{
public ILog GetLog(Type typeAssociatedWithRequestLog)
{
var log = LogManager.GetLogger(typeAssociatedWithRequestLog);
return log;
}
}
In NinjectConfigurator.cs :-
private void ConfigureLog4net(IKernel container)
{
XmlConfigurator.Configure();
var logManager = new LogManagerAdapter();
container.Bind<ILogManager>().ToConstant(logManager);
}
private void AddBindings(IKernel container)
{
ConfigureLog4net(container);
}
In my webconfig i have the following :-
<configSections>
<section name ="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value="..\\..\\logs\\WebApi2Book.Api.Log"/>
<appendToFile value="true"/>
<maxSizeRollBackups value="-1"/>
<countDirection value="1"/>
<maximumFileSize value="5MB"/>
<rollingStyle value="Composite"/>
<preserveLogFileNameExtension value="true"/>
<staticLogFileName value="false"/>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level [%thread] %logger - %message%newline%exception"/>
</layout>
<logger name="NHibernate">
<level value="ERROR"/>
</logger>
<logger name="NHibernate.SQL">
<level value="ERROR"/>
</logger>
<root>
<level value="ALL"/>
<appender-ref ref="LogFileAppender"/>
</root>
</appender>
</log4net>
In the Global.asax class, Im testing the logger is actually being injected correctly and then testing logging an error in the Application_Start() method.
protected void Application_Start()
{
var log = WebContainerManager.Get<ILogManager>().GetLog(typeof(WebApiApplication));
log.Error("Yey!!!! works!");
log.Debug("Yey!!!! works!! Debug");
}
I cant find any problems when i debug the program, i've checked that IsDebugEnabled is set as TRUE, and the logger in injected correctly as expected.
The only issue is that the log file isn't generated.
Your problem is that in your root logger you are referencing an appender called "LogFileAppender" but in fact your appender is called "RollingFileAppender" - the appender name must be the same on both places:
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
…
<root>
<level value="ALL"/>
<appender-ref ref="RollingFileAppender "/>
</root>
I basically have the same question as
log4net only works when XmlConfigurator.Configure() is called
However, I couldn't comment there as I don't have any reputation (just signed up).
Thanks for any helpful comments.
If I do anything wrong here, please advise.
Thank you very much. Bernd
Update:
Thanks for constructive hints. I've have made some progress and therefore will explain in more detail:
I use log4net within a (VS generated C# web service). I do get the debug information in the debug file, however within VS (2012) I do get the message for every logging call:
log4net:ERROR An exception ocurred while retreiving stack frame information.
System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
bei log4net.Core.StackFrameItem..ctor(StackFrame frame)
I configured it via XML:
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="Logs/debug.log" />
<encoding value="utf-8" />
<appendToFile value="true" />
<maximumFileSize value="10MB" />
<maxSizeRollBackups value="2" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level (%class#%method:%line):%message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingFile" />
</root>
</log4net>
My web service looks like this:
public class ObjectInfo : IObjectInfo
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public void DoWork() {
Logging.LoggingUtil.InitializeLogging();
log.Debug("Some message");
}
}
Hope this is quite sufficient. The LoggingUtil- class basically looks like this:
private const String Log4NetConfigurationFilePath = "log4net-config.xml"; //real path looks somewhat different
public static void InitializeLogging()
{
XmlConfigurator.Configure(new FileInfo(Log4NetConfigurationFilePath));
}
I wonder, if the problem is that the stack trace cannot be found out within Cassine as Microsoft doesn't allow this in order to protect their implementation of the web service?
As explained in LOG4NET-393, this error occurs when there is a dynamic method in the call chain.
There they claim to have this error fixed in versions > 1.2.12.
Now I've a web application and 3 background application in AppHarbor .
I want to use logentries to log each app in different location.
based on logentries docs for AppHarbor https://logentries.com/doc/appharbor/ the token keys are read from web.config and app.config [configuration vars] enforced by appharbor.
How can I configure each application to log in different log location (eg. Appharbor/Website, AppHarbor/Console1, AppHarbor/Console2)?
You can override the config vars injected by AppHarbor by specifying the Token in the appender/target definition. Not sure which framework you're using but if its NLog then
where you have this line in your web/app.config
<target name="logentries" type="Logentries" debug="true"
layout="${date:format=ddd MMM dd} ${time:format=HH:mm:ss} ${date:format=zzz yyyy} ${logger} : ${LEVEL}, ${message}"/>
Add token="abc" so that you have this:
<target name="logentries" type="Logentries" debug="true" token="abc"
layout="${date:format=ddd MMM dd} ${time:format=HH:mm:ss} ${date:format=zzz yyyy} ${logger} : ${LEVEL}, ${message}"/>
And then if you're using the log4net plugin, where you have this section:
<appender name="LeAppender" type="log4net.Appender.LogentriesAppender, LogentriesLog4net">
<Debug value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d{ddd MMM dd HH:mm:ss zzz yyyy} %logger %: %level%, %m" />
</layout>
</appender>
Add so that you have this:
<appender name="LeAppender" type="log4net.Appender.LogentriesAppender, LogentriesLog4net">
<Debug value="true" />
<Token value="abc" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d{ddd MMM dd HH:mm:ss zzz yyyy} %logger %: %level%, %m" />
</layout>
</appender>
Token values set here will take precedence over those injected by Appharbor, so for each app that has its own web/app.config you can enter your own token using this method.
I Found that I can set the token in runtime by below lines :
private static readonly ILog log = log4net.LogManager.GetLogger(typeof(Program));
appender = (LogentriesAppender)log.Logger.Repository.GetAppenders()[0];
appender.Token = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
//now log method will use my token
log.Info("Hello World");
really simple question -> i can't seem to get any data from Log4Net in my ASP.NET application. I've got a simple ASP.NET website, which references a class library. In this class library, I have some lines that call the logger.
I'm trying to read the log4net output data in my Visual Studio 2008 debugging Output window.
Here's my code and my configuration...
//Class Library project
//File: Foo.cs
public class FooService
{
private static readonly ILog log = LogManager.GetLogger(typeof(FooService));
public FooService()
{
// NOTE: To play with my L4N settings, I'll call Debug once, then Info once.
log.Info("Starting Constructor");
// ... snip ...
log.Debug("Leaving Constructor");
}
}
// ASP.NET Website project
// File: global.asax
void Application_Start(object sender, EventArgs eventArgs)
{
log4net.Config.XmlConfigurator.Configure();
}
// File: Whatever.aspx.cs
// A delegate method (when a user clicks a button) creates the FooService() instance.
// File: web.config
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler" requirePermission="false" />
// ....
</configSections>
<log4net>
<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<mapping>
<level value="ERROR" />
<foreColor value="White" />
<backColor value="Red, HighIntensity" />
</mapping>
<mapping>
<level value="DEBUG" />
<backColor value="Green" />
</mapping>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout" value="%date [%thread] %-5level %logger - %message%newline" />
</appender>
<appender name="OutputDebugStringAppender" type="log4net.Appender.OutputDebugStringAppender">
<mapping>
<level value="ERROR" />
<foreColor value="White" />
<backColor value="Red, HighIntensity" />
</mapping>
<mapping>
<level value="DEBUG" />
<backColor value="Blue" />
</mapping>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="App_Data\logging\log-append.txt"/>
</appender>
<!-- Setup the root category, add the appenders and set the default level -->
<root>
<level value="ALL" />
<appender-ref ref="OutputDebugStringAppender" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="ColoredConsoleAppender" />
</root>
<!-- Specify the level for some specific categories -->
<logger name="DotNetOpenAuth">
<level value="ALL" />
</logger>
</log4net>
Cheers for any help or suggestions...
EDIT: Added the RollingLogFileAppender.
I had this same problem and I think it was looking at the wrong web.config or something. I finally separated out log4net.config from web.config and put a path to it \inetpub\Logs\log4net.config and all is well.
UDPATED ON REQUEST: edited from a slightly more complicated version.
<?xml version="1.0" encoding="utf-8"?>
<log4net>
<appender name="TraceAppender" type="log4net.Appender.TraceAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level (%logger:%line) - %message%newline" />
</layout>
</appender>\
<root>
<!--ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF-->
<level value="ALL" />
<appender-ref ref="TraceAppender" />
</root>
</log4net>
And it is configured in code as follows:
var logpath = WebConfigurationManager.AppSettings["LogConfigPath"] ?? #"\Inetpub\Logs\log4net.config";
var finfo = new System.IO.FileInfo ( logpath );
XmlConfigurator.Configure( finfo );
ASP.Net has restriction on usage of filesystem access, so try to explicitly point directory under App_Data (were it is allowed)
Here my working sample:
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="App_Data\logging\log-file.txt"/>
Or with rollover
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="App_Data\logging\log-append.txt"/>
Ok, found the answer. I needed to use a TraceAppender.
The application configuration file
can be used to control what listeners
are actually used. See the MSDN
documentation for the Trace class for
details on configuring the trace
system.
Events are written using the
System.Diagnostics.Trace.Write(string,string)
method. The event's logger name is
passed as the value for the category
name to the Write method.
Here's my config file data...
<log4net>
<appender name="TraceAppender" type="log4net.Appender.TraceAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<!-- Setup the root category, add the appenders and set the default level -->
<root>
<level value="ALL" />
<appender-ref ref="TraceAppender" />
</root>
</log4net>
There are atleast 2 possible problems:
The way the address to the file is specified, try using an absolute path instead.
The process making the call needs rights to modify the file. Check that the user account making writing to the log file has rights to do so.
To debug it I would create and empty directory, give everyone full control, configure to log to that directory. Then test it, see that it works, then gradually tighten the security to an acceptable level.
I added the following line Global.asax file, and it works..!!
log4net.Config.XmlConfigurator.Configure();