What is a (the?) minimal logger.properties that turns off all logging? - log4cxx

I have an application that uses log4cxx internally, with dozens of loggers. What is a minimal logger.properties that I can setup to turn off all logging output?
In particular I'm getting a warning like (no properties file present):
log4cxx: No appender could be found for logger (FileSource).
log4cxx: Please initialize the log4cxx system properly.
FileSource is a class that uses log4cxx.
My goal is to preclude all log4cxx output at runtime.

This should do it:
<?xml version="1.0" encoding="UTF-8" ?>
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<root>
<priority value="OFF" />
</root>
</log4j:configuration>
A simple logger.properties that logs to standard out could look like below:
<?xml version="1.0" encoding="UTF-8" ?>
<!-- add attribute debug="true" to log4j:configuration tag to see how logger reads it's configuration. -->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p %c (%F:%M:%L) - %m%n" />
</layout>
</appender>
<root>
<priority value="DEBUG" />
<appender-ref ref="ConsoleAppender"/>
</root>
</log4j:configuration>

Related

Web.config transformation locator condition or xpath not working with multiple attributes

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.

Writing different levels to different files in log4cxx

I want to have log messages from each log level go to a different file. From the name, LevelMatchFilter seems like what I want, except it seems to not filter anything from a different level.
I think the following properties should do that using LevelRangeFilter. However, anything sent to the global logger ends up in INFO.log, regardless of the level.
log4j.rootLogger = OFF
# Global level based logs
log4j.logger.global = ALL, Info
log4j.appender.Info=org.apache.log4j.FileAppender
log4j.appender.Info.File=Logs/INFO.log
log4j.appender.Info.layout=org.apache.log4j.PatternLayout
log4j.appender.Info.layout.ConversionPattern=%d [%p] %m%n
log4j.appender.Info.filter.a=org.apache.log4j.filter.LevelRangeFilter
log4j.appender.Info.filter.a.LevelMin=info
log4j.appender.Info.filter.a.LevelMax=info
log4j.appender.Info.filter.a.AcceptOnMatch=true
I also tried using INFO for the values of LevelMin and LevelMax but that had the same results.
What am I doing wrong?
As a side question, is there a way to turn on debugging of the log4cxx configuration when using a property file? I found an option when using an xml file, but none of the obvious translations to properties (debug=true, log4j.debug=true) and any effect.
As of log4cxx 0.10 (and probably earlier), the properties format does not support filters. So the XML configuration (or programmatic configuration) is required.
<?xml version="1.0" encoding="UTF-8" ?>
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">
<appender name="Info" class="org.apache.log4j.FileAppender">
<param name="file" value="Logs/INFO.log" />
<param name="append" value="false" />
<!-- If this filter accepts the message, it will be printed. That happens if this is an info message -->
<filter class="org.apache.log4j.filter.LevelMatchFilter">
<param name="levelToMatch" value="INFO" />
<param name="acceptOnMatch" value="true" />
</filter>
<!-- If it is not an info message, this filter will reject it -->
<filter class="org.apache.log4j.filter.DenyAllFilter"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%p] %m%n" />
</layout>
</appender>
<root>
<priority value="off" />
</root>
<logger name="global">
<priority value="all" />
<appender-ref ref="Info" />
</logger>
</log4j:configuration>

Flyway logging with log4j?

hy guys,
is there a best practice of how to get flyway output into log4j logs?
I'm currently running with following log4j.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<appender name="CA" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-p - %m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="levelMin" value="INFO"/>
<param name="levelMax" value="ERROR"/>
</filter>
</appender>
<appender name="fileAppender" class="org.apache.log4j.RollingFileAppender">
<param name="append" value="false"/>
<param name="file" value="log.out"/>
<param name="immediateFlush" value="true"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
</layout>
</appender>
<logger name="com.googlecode.flyway.core.migration" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="fileAppender"/>
</logger>
<root>
<priority value="all"/>
<appender-ref ref="CA"/>
<appender-ref ref="fileAppender"/>
</root>
</log4j:configuration>
I have already searched for an answer online but could not figure it out.
Flyway will automatically use Log4J if it is available on the classpath.

log4cxx: time based rolling doesn't work

I'd like to configure log4cxx via xml in order to roll my log file every minute. I tried with the following log4j.xml file but it seems to work only sometimes, randomly. I tried also with another xml file using TimeBasedRollingPolicy but it doesn't work.
Any help would be appreciated.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="appxRollingAppenderDaily" class="org.apache.log4j.rolling.RollingFileAppender">
<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
<param name="FileNamePattern" value="TimeBasedLog.%d{yyyy-MM-dd-HH-mm}.log"/>
<param name="activeFileName" value="appxDailyLog.log"/>
</rollingPolicy>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss,SSS} %x [%p] (%F:%L) %m%n"/>
</layout>
<param name="file" value="appxDailyLog.log"/>
<param name="append" value="true"/>
</appender>
<root>
<priority value="all" />
<appender-ref ref="appxRollingAppenderDaily"/>
</root>
</log4j:configuration>
Try this:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="appxRollingAppenderDaily" class="org.apache.log4j.DailyRollingFileAppender">
<param name="Threshold" value="ALL"/>
<param name="file" value="./appxDailyLog.log"/>
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<!-- <param name="ConversionPattern" value="%p %t %c - %m%n"/> -->
<!-- <param name="ConversionPattern" value="%d{ISO8601} [%15.15t] %-5p %l - %m%n"/> -->
<!-- <param name="ConversionPattern" value="%d{ISO8601} [%-8.8t] %-5p (%t) - %m%n"/> -->
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss,SSS} %x [%p] (%F:%L) %m%n"/>
</layout>
</appender>
<root>
<priority value="ALL" />
<appender-ref ref="appxRollingAppenderDaily"/>
</root>
</log4j:configuration>

Can't get Log4Net to work in my ASP.NET website :(

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();

Resources