log4j2 configuration using system properties - java

Hi I have recently migrated the logging from log4j to log4j2 in my spring project.
Everything is working fine as expected but I wish to know how I can set the properties
<SizedBasedTriggeringPolicy size="10MB" /> and <DefaultRolloverPolicy max="80" /> in my log4j2 config file by directly picking up the value from the given system argument for Rolling File Appender.
In log4j I used to use <param name="MaxFileSize" value="10MB" />
and <param name="MaxBackupIndex" value="80" /> in my RollingFileAppender default configuration and could override the parameter value by passing myAppenderLoggerName.MaxBackupIndex = my-value and myAppenderLoggerName.MaxFileSize = my-value as system properties args.
I'm aware I can use $(sys:my-parameter-name:-default-value) in log4j2 for substitution but is there a direct approach through which I can override the parameter by referencing it's property name directly in log4j2 like it was there is log4j like say myAppender.paramterNameForRolloverSizeInLog4j2 = my-value ?

No, Log4j2 doesn't automatically associate every attribute with a system property.
I'm not sure why you would want to either as that would be quite cumbersome. For example, to set the max file size you would need
-DmyAppender.policies.sizeBasedTriggeringPolicy.max=10MB
How is that better?
But if you really want that you are free to do
<property name="myAppenderMax">${sys:myAppender.policies.sizeBasedTriggeringPolicy.max:=10MB}</property>
and then specify ${myAppenderMax} as the value in the appender configuration.

Related

What does mean sys:ls.logs in log4j?

I am reading log4j docs and logstash log4j config , i don't know ${sys:ls.logs} mean.
What mean ${sys:ls.logs}?
How can i change this valuable in runtime or in OS environment.
I use Ubuntu OS.
sys is System properties in Log4j 2. Log4j supports the syntax ${prefix:name} where the prefix identifies tells Log4j that variable name should be evaluated in a specific context. See Log4j 2 documents
sys : System properties. The formats are ${sys:some.property} and ${sys:some.property:-default_value}.
Property Support
You can reference properties in a configuration, Log4j will directly replace them, or Log4j will pass them to an underlying component that will dynamically resolve them. Properties come from values defined in the configuration file, system properties, environment variables, the ThreadContext Map, and data present in the event.
System properties are often defined outside the application and you can access them via a Lookup. You can further customize the property providers by adding their own Lookup Plugin. Default properties may also be specified in the Lookup by using the syntax ${lookupName:key:-defaultValue}.
<Appenders>
<File name="ApplicationLog" fileName="${sys:logPath:-/var/logs}/app.log"/>
</Appenders>
Furthermore, using a lookup for the system property named ls.logs, in Log4j 1.x, the syntax would be ${ls.logs}. In Log4j 2, the syntax would be ${sys:ls.logs}.
This property may be set in app source or as an argument when start the service. For example, in a DefaultDeprecationLoggerTest for logstash in logstash source it is set to build/logs as below:
#Before
public void setUp() throws IOException {
System.setProperty("log4j.configurationFile", CONFIG);
System.setProperty("ls.log.format", "plain");
System.setProperty("ls.logs", "build/logs");
LogTestUtils.deleteLogFile("logstash-deprecation.log");
}

Apache Camel file component with dynamic path

I am trying to set dynamic path in camel file component to avoid platform specific paths. But camel is not allowing this as it doesn't expect $ in directory path.
What I am trying to do is to set a VM param say file.home and then use this into my file component like
file:\${file.home}\type1
This will allow me to eliminate the platform specific path directly.
I tried externalizing this into property file but then Spring doesn't understand the camel specific dynamic language for e.g. ${in.header.abc}
Can someone help me out in achieving this.
Those answers are not correct. If you use a BridgePropertyPlaceholderConfigurer and a PropertiesComponent, you can use dynamic values everywhere.
<bean id="bridgePropertyPlaceholder" class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer">
<property name="properties">
<value>
...normal property syntax name=value - use this in test definitions
</value>
</property>
</bean>
Or use something like this in real application
<bean id="dummyPropertyPlaceholder" class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer">
<property name="location" value="classpath:/dummy.properties" />
</bean>
e.g.
<route id="DummyRoute">
<from uri="file:{{dummy.int.dir}}?delay={{poll.delay}}&initialDelay={{initial.delay}}&{{readlockChanged}}&move={{root}}/{{dummy.arch.dir}}/{{archive.dir}}&moveFailed={{error.dir}}&scheduledExecutorService=#scheduledExecutorService" />
<to uri="file:{{root}}/{{dummy.int.destination.dir}}" />
</route>
There is a trick with later versions of Camel: use $simple{file.path} instead of ${file.path} so Spring won't strip your ${} and pass the bare file.path to Camel. E.g. a move on an input 'from' uri might be like this:
move=archive/$simple{date:now:yyyyMMdd}/$simple{file:name}
http://camel.apache.org/how-do-i-use-spring-property-placeholder-with-camel-xml.html
http://camel.apache.org/using-propertyplaceholder.html
You can use dynamic uri but only in to endpoints (using specific components). You can't use it as from.
There you can find explanation how to use toD (from Camel 2.16) or recipientList: How to use dynamic URI in to
But as I said - there is only possibility to use it in to. It's not possible to use it in from. As a workaround, you have to write a route for each location you are expecting to be in use. You can also use autoCreate=false option to not creating other directories automatically, because for example Linux path without autoCreate=false option: /home/user/test will create directory structure in Windows c:\home\user\test
Since Camel 2.16
We can use
.from("file://folder")
.toD("file://folder/${file:onlyname}")
Here are some details about using properties within camel and/or spring xml: http://camel.apache.org/using-propertyplaceholder.html
According to Camel File Component:
Camel supports only endpoints configured with a starting directory. So
the directoryName must be a directory. If you want to consume a single
file only, you can use the fileName option e.g., by setting
fileName=thefilename. Also, the starting directory must not contain
dynamic expressions with ${} placeholders. Again use the fileName
option to specify the dynamic part of the filename.
So, you could do somethings like:
from(...).to("file://?fileName=${somePathAndSomeFile}").to(...)
Some of the comments/answers in this thread are misleading, as it's possible to set the value of "from" endpoint URI to have a value of a directory taken from a properties file as asked.
Place propertyPlaceholder element under camelContext, and ensure that the properties file could be found in the classpath
<propertyPlaceholder location="dir.properties" />
<from id="_fromInputFolder" uri="file:{{fromDir}}?"/>

Setting up connection time out using configuration

I realized that I haven't set the time out for the JDBCTemplate using the setQueryTimeOut method. My code is in production as I would ideally want a solution to set the timeout from some configuration instead of recompiling the code. Is there a way to set the query time out via say the data source configuration or any other property outside the Java.
I tried via the accepted solution to this post. Didn't work for me. I get org.springframework.beans.NotWritablePropertyException: Invalid property 'connectionProperties' of bean class
You can use the queryTimeout field with configuration:
In your JDBCTempalte xml - <property name="queryTimeout" value="${query.timeout} />
Use a PropertyPlaceholderConfigurer to load properties from a .properties file on the classpath. The easiest way is through <context:property-placeholder location=".." />
Add the query.timeout=x in your .properties files

Disable Axis log4j logging in jboss

I have small application that is uploading pictures to another website via webservice.
My current problem is, that Axis is logging the whole xml message (including the binary data of the picture!) via STDOUT and I can't seem to figure out, how to disable it.
My log4j settings for jboss (jboss-log4j.xml) includes an appender for normal STDOUT Info loggings, and I tried to disable axis with different category settings:
<appender name="STDLOG" class="org.jboss.logging.appender.RollingFileAppender">
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
<param name="File" value="${jboss.server.log.dir}/myapplication.log"/>
<param name="Append" value="true"/>
<param name="MaxFileSize" value="5MB"/>
<param name="MaxBackupIndex" value="10"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
</layout>
</appender>
using this setting for STDOUT:
<category name="STDOUT">
<priority value="DEBUG"/>
<appender-ref ref="STDLOG"/>
</category>
I tried these category settings without any change in the result:
<category name="log4j.logger.org.apache.axis" additivity="false">
<priority value="ERROR"/>
</category>
<category name="org.apache.axis">
<priority value="ERROR"/>
</category>
Some sample log output looks like this:
2009-08-07 10:29:43,911 INFO [STDOUT] (http-127.0.0.1-8080-1) =======================================================
= Elapsed: 2190 milliseconds
= In message: <?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<addVehicleImage xmlns="urn:VMgrWebService">
<id xmlns="">APP-T4QKR3U</id>
<idType xmlns="">chiffre</idType>
<data xmlns="">9j4AAQSkZJRgABAQAAAQABAAD2wBDAAUDBAQEAwUEBAQFB
QUGBww0TDMnrXAfKlLjnNJZcciiAOtqk9NG99qhZJKuyYq5k3G
8P2bVSOpT7rVddRP2Z/yqidRuMMKaO2CXRQNWP2jfOo4S4Bo3W
removed rest of image data...
IBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGe1UqaZJJy0jSHPGQ
2009-08-07 10:29:43,927 INFO [STDOUT] (http-127.0.0.1-8080-1) Upload result: true for image mypicture.JPG
Update
I checked the axis-1.4.jar and there is a file called simplelog.properties:
# Logging detail level,
# Must be one of ("trace", "debug", "info", "warn", "error", or "fatal").
org.apache.commons.logging.simplelog.defaultlog=info
Setting this to error within the jar, or as a category in jboss-log4j.xml didn't help at all.
Anyone any idea how I can turn off the Axis logging or at least set it to ERROR level?
Cheers
Frank
This might be a bit late in the day, but the problem does not seem to be that logging itself is done in Axis (via System.out and Commons Logging), but rather that the LogHandler is present in the handler chain. That is how the elapsed time is getting logged.
You can disable this handler from the Axis configuration file(s) - server-config.wsdd and/or client-config.wsdd, depending on whether you are using Axis as a server or a client.
The reason why you are seeing messages in your console is probably due to the LogHandler.writeToConsole property being set to true. If you set LogHandler.writeToConsole to false, it should write into a file as defined by the LogHandler.fileName property. By default, the file name is axis.log.
Ok, after trying to find a better solution, the only real way was to check the old legacy code and turn all System.out calls into real logging statements (much better anyway), and then simply filter the remaining STDOUT messages into a different log file.
One of the main reasons seems to be Jboss itself. This discussion from the axis2 mailing list explains why:
Ahh, but you didn't mention you are using jboss! It pretty much forces
you to use their parent log4 config . Ignore the axis2 logging in this
case, and see:
~/jboss/server/default/conf/log4j.xml
There you have to limit the categories. For example, you have:
<category name="org.apache">
<priority value="INFO"/>
</category>
You could leave that as is and just get your logs out of server.log .
I tried setting the category, without success. I assume this is because of differences between axis and axis2. So the only solution left was to go the good coding way and just don't use STDOUT in your own code ;-)
First off, you'll want to check that your log4j configuration is actually the one being read - I recall that in the past, at least one axis jar (I think it may have been axis-ant.jar) was guilty of bundling their own log4j.properties. It may be that log4j is reading a different configuration file than yours, making your efforts at tweaking the configuration pointless!
You can enable the system properties -Dlog4j.debug to have log4j print to standard out which configuration file is being read. If necessary, you can use -Dlog4j.configuration=<file> to point to your own file.
Also, I don't think this is causing your issues, but why are you setting additivity to false?
The problem is that Axis is not using Log4j to log that message, so attempting to change the log4j logging level on that class isn't relevant. Axis is using a System.out.println.
The only thing I can think of (which is really not nice given the side effects) is to turn the STDOUT logging off altogether. Probably setting the priority to off will do.
The only real solution is to fix Axis and patch the code to not pump the xml to System.out but rather use the logging mechanism instead - then you could control it.
It is very important to know which log4j.properties file or log4j.xml is being read. and as Matt pointed out, this is crucial in knowing why your tweaking efforts are not working.

How to configure Tomcat JULI logging to roll log files?

I have a several webapps which use java.util.logging. Tomcat 5.5 is configured to use the Juli logger so that each webapp has its own log file. The problem is that Juli does not have properties for maximum file size and file count. Using Juli the files will grow unbounded and only roll at the end of the day. Also, an unlimited number of log files are retained.
You can see the FileHandler properties on this page - Apache Tomcat 5.5 Documentation
There is no limit or count property (the following lines do nothing)
org.apache.juli.FileHandler.limit=102400
org.apache.juli.FileHandler.count=5
Without changing the webapps is there a way to get unique log files for each application with some type of bounds on the log file sizes?
UPDATE:
The solution I found was not use the Juli logger at all!
java.util.logging.FileHandler.limit=102400
java.util.logging.FileHandler.count=5
Thanks,
Greg
Update: I see your point now after reading more. "Tomcat's JULI implementation is not intended to be a fully-featured logging libary, only a simple bridge to those libraries. However, JULI does provide several properties for configuring the its handlers. These are listed below." Funny that they say that the default java.util.Logging implementation is too limited then they work around it by providing an even more limiting implementation.
FileHandler javadocs
java.util.logging.FileHandler.limit specifies an approximate maximum amount to write (in bytes) to any one file. If this is zero, then there is no limit. (Defaults to no limit).
java.util.logging.FileHandler.count specifies how many output files to cycle through (defaults to 1).
for the one file per web app, you probably want to separate it by the name of the logger and it depends on how the loggers are created for each app. If they're based off the package or class name then you can filter the logs based on that. It looks like the sample on the link you provided tells how to do this
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = \
2localhost.org.apache.juli.FileHandler
EDIT: Just realized you wanted per webapp logging which might not be possible with this setup...
My suggestion, assuming your are using Tomcat 6.0, is to compile the extra component for full commons-logging and use Log4j to configure rolling logs.
Building instructions here
http://tomcat.apache.org/tomcat-6.0-doc/building.html
Then replace the tomcat-juli.jar in the /bin directory of Tomcat and place the tomcat-juli-adapters.jar in the /lib directory along with log4j.jar and log4j.properties.
Then using something like:
<appender name="file" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="logfile.log"/>
<param name="Threshold" value="INFO"/>
<param name="MaxFileSize" value="10MB"/>
<param name="MaxBackupIndex" value="3"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %p %m%n"/>
</layout>
</appender>

Categories

Resources