Log4j2 (beta9) How to configure custom layout for FileAppender? - log4j2

Can someone tell me, How to configure custom layout for FileAppender?
Can anyone tell me, how to configure custom layout for FileAppender?
I'm created copy of HTMLLayout and made some changes there (it's cannot be extends because it's final class) and now I want use this layout, but I don't know how :(
This error is showed with bellow listed configuration:
ERROR File contains an invalid element or attribute "ibtrader.log4j2.MYHTMLLayout"
Here is my log4j2.xml configuration file
<?xml version="1.0" encoding="UTF-8"?>
<configuration strict="true" monitorInterval="30">
<appenders>
<appender name="Console" type="Console" target="SYSTEM_OUT">
<layout type="PatternLayout" pattern="%highlight{%d{ISO8601} [%t] %-5level %logger{36} - %msg%n}" />
</appender>
<appender name="DEBUG_FILE" type="File" fileName="logs/errors.txt" >
<layout type="PatternLayout" pattern="%d{ISO8601} [%t] %-5level %logger{36} - %msg%n}" />
</appender>
<appender name="HTMLAppender" type="File" fileName="logs/mainlog.html">
<layout type="ibtrader.log4j2.MYHTMLLayout" charset="UTF-8" title="IBTRader logs" locationInfo="true" />
</appender>
</appenders>
<loggers>
<root level="trace">
<appender-ref ref="Console"/>
<appender-ref ref="DEBUG_FILE" level="WARN" />
<appender-ref ref="HTMLAppender" />
</root>
</loggers>
</configuration>
Thanks for help!

The comments mention this is already fixed but just for completeness, a (simplified) configuration with a custom MYHTMLLayout plugin could look like this:
<?xml version="1.0" encoding="UTF-8"?>
<!-- the packages attribute contains a comma-separated list
of the packages that Log4J2 will scan for custom plugins. -->
<configuration packages="ibtrader.log4j2">
<appenders>
<appender name="HTMLAppender" type="File" fileName="logs/mainlog.html">
<!-- Each plugin has a *name*, declared with annotation on the
plugin implementation class.
The plugin name does not need to match the class name.
The plugin name needs to match the *type* attribute in the config.
For example:
package ibtrader.log4j2;
import ...;
#Plugin(name="MYHTMLLayout", category="Core",
elementType="layout", printObject=true)
public class MyHTMLLayoutImpl extends AbstractStringLayout {...
-->
<layout type="MYHTMLLayout" charset="UTF-8" title="IBTRader logs" locationInfo="true" />
</appender>
</appenders>
<loggers>
<root level="trace">
<appender-ref ref="HTMLAppender" />
</root>
</loggers>
</configuration>

You have to extend AbstractStringLayout, setting the #Plugin properties with category = "Core", elementType = "layout" and name="The name of the class itself that should be refered from the configuration file" (i.e.: "ExtHtmlLayout")
You could just copy the whole class HtmlLayout from the sources and change whatever you want, for example, the time in millis column to the time in hours.
Define the package property in "Configuration" tag to use the package to the extended class you have created.
Finally, just call the new layout from the configuration file:
<ExtHtmlLayout/>

Related

pass file name from logger to appender

i want to log out to different files because there are too many and hard to fallow. For example i have hospital application and i want separate log file for every different action like appointment, reports and patient
public org.apache.logging.log4j.Logger logManager = LogManager.getLogger("appointment-log");
public org.apache.logging.log4j.Logger logManager = LogManager.getLogger("reports-log");
public org.apache.logging.log4j.Logger logManager = LogManager.getLogger("patient-log");
i can do reports log like below
<appender name="FILE-REPORTS" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS_HOME}${REPORTS_LOG}</file>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss};%msg%n
</Pattern>
</encoder>
<param name="Append" value="False" />
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${LOGS_HOME}REPORTS.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<logger name="reports-log" level="info" additivity="false">
<appender-ref ref="FILE-REPORTS"/>
<appender-ref ref="STDOUT"/>
</logger>
Everything is ok till here but i dont want to write appender for appointment and patient and many more, i want to use only 1 appender then i will pass file name from , psudo like below
<logger name="patient-log" level="info" additivity="false">
<appender-ref ref="PATIENT-AUDIT" **fileName="patient.log"**/>
<appender-ref ref="STDOUT"/>
</logger>

log4j2 - duplicating logs in Console & RollingFile

hey I was wondering if it possible to have the same output in Console as in the file output.
Here is my XML config.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" name="log4j2 Logs">
<Properties>
<Property name="basePath">./logs</Property>
</Properties>
<Appenders>
<RollingFile name="file" fileName="${basePath}/ActivateMaintenancePage.logs"
filePattern="${basePath}/ActivateMaintenancePage-%d{yyyy-MM-dd}">
<PatternLayout header="LOGGING START%n%n" footer="%n%nLOGGING END"
pattern="%3sn %30d{DEFAULT} [%M] %-7level %c{30} - %m%n" />
<Policies>
<OnStartupTriggeringPolicy minSize="0"/>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="500 MB"/>
</Policies>
</RollingFile>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout header="LOGGING START%n%n" footer="%n%nLOGGING END"
pattern="%3sn %30d{DEFAULT} [%M] %-7level %c{30} - %m%n" />
</Console>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="console" level="error"/>
<AppenderRef ref="file" level="trace"/>
</Root>
</Loggers>
</Configuration>
Output in RollingFile
1 2017-07-25 11:16:36,762 [initializeChrome] INFO class testNG.SimSettings - Web Chrome driver is now initilized.
2 2017-07-25 11:16:36,762 [lambda$0] INFO class testNG.SimSettings - Opening... http://msrvaq11vm.technomedia.ca/sigal_60/2017sp1/sp_polymont/_sim/PROD Sp2 2016 Sim...
3 2017-07-25 11:16:47,926 [initilizeAllElements] INFO class testNG.SimSettings - All #FindBy elements have been initilized.
4 2017-07-25 11:16:48,006 [change1stLevelFrame] INFO class testNG.SimSettings - Changing target to 1st level frame.
5 2017-07-25 11:16:49,719 [enterCredentials] INFO class testNG.SimSettings - UserName & Password: Success!
and empty in Console. But now if I change
<AppenderRef ref="console" level="error"/>
to "trace"
It will be 2,4,6....in console and in my file it will be 1,3,5,7... which is easily understandable.
But my question is how can we have both the same log-level (trace) output in Console and File?
(adding tag with package name and level did not work)
Related to this question: log4j2 xml configuration - Log to file and console (with different levels)
I'm not sure if I read your question correctly but it seems that you want to render some unique value in the log output, such that the same log event has the same unique value in the Console log and the File log output.
The sequence number pattern converter will increment every time a log event is rendered. The same log event is rendered separately for each Appender, so different Appenders will never have the same sequence number.
There are a number of alternatives. One idea is to include %nano nanotime in the pattern layout. This value is captured when the application makes the logging call and will be the same for all appenders. An alternative is to create a custom Log4j2 pattern converter or lookup.

Convert log4j 1.x to log4j 2.x custom layout appender

<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.base}/logs/server.log" />
<param name="Append" value="true" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<layout class="com.mayank.base.logging.CustomPatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE}#%X{requestId} %R %-5p [%c{1}] - %m%n" />
</layout>
</appender>
I am facing trouble converting it to log4j 2. How i can addmy custom pattern layout.
You should implement your CustomPatternLayout as a Layout plugin. You have a code example on (layout plugins manual).
In very general you should :
Implement the plugin class with proper annotations on the constructor
Implement the plugin factory method
Implement the desired formatting
Mention in log4j configuration your plugins package:
<Configuration packages="com.mayank.base.logging">
Use in the configuration the name of your plugin class
You can see explanations and examples of plugins implementation on this blog post1, post2, post3. There is no layout plugin example, but the technique is very similar.
The <RollingFile> tag should be present.
Here are couple of samples -
<RollingFile name="ROLLING"
fileName="f:/my_dir/logsroll.log"
filePattern="f:/my_dir/logsroll-%i.log">
OR
<RollingFile name="MyFile" fileName="d:/log/bsi/admin/total/totalLog.log"
filePattern="d:/log/totalLog-%d{MM-dd-yyyy}-%i.log">
<PatternLayout>
<Pattern>%d %p %c [%t] %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="1 MB"/>
</Policies>
<DefaultRolloverStrategy max="2000"/>
</RollingFile>
Referthis for more.

how to change htmllayout in log4j2

When I use log4j, I can create a new class extends org.apache.log4j.HTMLLayout and override it to make a new format of the log. When using log4j2, I can only use the layout but not override it. In my log4j2.xml writing
<Appenders>
<File name="log" fileName="D:\log.html" append="false">
<HTMLLayout/>
</File>
</Appenders>
in log4j I may use layout class="log.FormatHTMLLayout" (log.FormatHTMLLayout is my new class which extends the HTMLLayout), but now I can only use HTMLLayout.
Is there any way to override the HTMLayout? I need to do a lot of things, like changing the output table, the title and so on.
Here is what i did,
I needed to add <img> HTML tags in logs generated by log4j2 and by default HTML elements like <, >, " are replaced by escape characters like lt; , gt; , quot;.
(Ref:https://issues.apache.org/jira/browse/LOG4J2-439)
So i just copied whole HTMLLayout class from source, which is available at
log4j-core / src / main / java / org / apache / logging / log4j / core / layout
and changed its name to "CustomHTMLLayout" and updated it wherever required (you can choose any name), now your custom layout class is as good as HTMLLayout class.
there is method called toSerializable which contains actual formatting of each record, so you can manipulate it as per your need.
once class is modified, you need to provide the new layout in your log4j2.html
as following:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration packages="com.redknee.bssauto.helpers">
<Appenders>
<RollingFile name="Rolling-default" fileName="logs/bssauto.html" filePattern="logs/$${date:yyyy-MM}/bssauto-%d{MM-dd-yyyy}-%i.log.gz">
<CustomHTMLLayout charset="UTF-8" title="BSSAuto Logs" locationInfo="true" />
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="10 MB" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="Rolling-default"/>
</Root>
</Loggers>
</Configuration>
Notice following
<Configuration packages="com.bssauto.helpers">
here packages should have all packages containing custom class for layouts. so here com.bssauto.helpers is package under which i have CustomHTMLLayout class.
<CustomHTMLLayout charset="UTF-8" title="BSSAuto Logs" locationInfo="true" />
and CustomHTMLLayout is custom layout class created by extending AbstractStringLayout
Make sure you are using latest log4j2 version, I used log4j 2.2

Log4j2 Appender attributes with strict xml config

I'm using log4j2-beta9 and want to configure it using a log4j2.xml in strict mode.
My issue is: how do I specify attributes that are not in the shipped schema file?
An Example:
<?xml version="1.0" encoding="UTF-8" ?>
<Configuration
status="DEBUG"
strict="true"
monitorInterval="5"
name="TestingAttributes"
verbose="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="Log4j-config.xsd">
<Properties>
</Properties>
<Appenders>
<Appender
type="Console"
name="SYSERR"
target="SYSTEM_ERR"> <!-- cvc-complex-type.3.2.2: Attribute 'target' is not allowed to appear in element 'Appender'. -->
<Layout Type="PatternLayout">
<Pattern>%date{dd.MM.yyyy HH:mm:ss,SSS} %5p %logger %m%n</Pattern>
</Layout>
<Filters>
<Filter
type="MarkerFilter"
marker="FLOW"
onMatch="DENY"
onMismatch="NEUTRAL" />
<Filter
type="MarkerFilter"
marker="EXCEPTION"
onMatch="DENY"
onMismatch="NEUTRAL" />
</Filters>
</Appender>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="SYSERR" />
</Root>
</Loggers>
</Configuration>
Notice that I want to set the appender to have the target SYSTEM_ERR but the attribute is not allowed in strict mode.
target="SYSTEM_ERR"> <!-- cvc-complex-type.3.2.2: Attribute 'target' is not allowed to appear in element 'Appender'. -->
I could always edit the Log4j-config.xsd and allow that attribute there but that would be kind of wrong also because not all appenders have a target attribute.
As searching the web didn't help me so far, I'm asking you:
Is there anything I'm missing in configuring Log4j2 in strict XML mode?
Do I have to "patch" the XMLConfiguration and the schema file and commit a change to log4j or is there another way besides not using strict mode?
Thanks in advance.
Can you ask this on the log4j-user mailing list? It could be a bug in the schema, but I suspect the schema can do with more improvements and your feedback would be valuable.

Resources