log4j2 to configure logging level to all for particular class and restrict the rest of the classes to "error" level - log4j2

I have a requirement to write all logs from specific package (com.kat.util) and restrict the rest of the classes should only log "error". how can i achieve that ?
I tried the below snippet, but its not working
<Loggers>
<Logger name="com.kat.util">
<AppenderRef ref="writer" level="all"/>
</Logger>
<Root level="error">
<AppenderRef ref="writer"/>
</Root>
</Loggers>

I have managed to solve, by adding the below
<Loggers>
<Logger name="com.kat.util" level="debug">
<AppenderRef ref="writer" />
</Logger>
<Root level="error">
<AppenderRef ref="writer"/>
</Root>
</Loggers>

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 JsonTemplateLayout - log message field as json

I have this log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="JsonAppender" target="SYSTEM_OUT">
<JsonTemplateLayout eventTemplateUri="classpath:EcsLayout.json" />
</Console>
</Appenders>
<Loggers>
<Logger name="JsonLogger" level="INFO" additivity="false">
<AppenderRef ref="JsonAppender"/>
</Logger>
<Root level="info">
<AppenderRef ref="JsonAppender"/>
</Root>
</Loggers>
</Configuration>
In my code I have a logging statement like:
HashMap logMap = new HashMap<>();
logMap.put("appId", "123456789");
logMap.put("action", "Received request");
logger.info(new ObjectMessage(logMap));
In my log I get this:
{
"#timestamp": "2022-02-02T10:52:56.100Z",
"ecs.version": "1.2.0",
"log.level": "INFO",
"message": "{appId=123456789, action=Received request}",
"process.thread.name": "main",
"log.logger": "org.xxxx.App"
}
That's ok but I want the message to be in json, so would like:
"message": {
"appId": "123456789",
"action": "Received request"
}
I know using JsonLayout you had to specify objectMessageAsJsonObject="true", but suspect it's a bit more nuanced when using JsonTemplateLayout.
TIA.
Upon reading the JSON Template Layout docs further, you can modify the event template fields by leveraging the eventTemplateAdditionalField param.
There seems to be a few ways to approach this but the option I went with is to modify the log4j2.xml:
<Appenders>
<Console name="JsonAppender" target="SYSTEM_OUT">
<JsonTemplateLayout eventTemplateUri="classpath:LambdaEcsLayout.json">
<EventTemplateAdditionalField
key="message"
format="JSON"
value='{"$resolver": "message", "field": "name"}'/>/>
</JsonTemplateLayout>
</Console>
</Appenders>
And when logging, have something like this:
var logMap = new HashMap<>();
logMap.put("id", "123456789");
logMap.put("action", "Received request");
var om = new ObjectMessage(logMap);
log.info(om);
There is probably a much neater way to deal with the latter, some kind of wrapper etc - but you get the idea.
I was able to get #Hurricane's method to work, but in trying to simplify it, I found that you can omit the <EventTemplateAdditionalField> element and add
"message": {
"$resolver": "message",
"stringified": false
}
to the template layout instead. You can also omit the 'stringified' attribute as it defaults to 'false'. The OP didn't include the layout, but I suspect he had 'stringified' set to 'true'

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.

log4j2 level inheritance not working

<Loggers>
<Logger name="X.Y.Z">
<AppenderRef ref="Console" />
</Logger>
<Logger name="X.Y">
<AppenderRef ref="Console" />
</Logger>
<Logger name="X">
<AppenderRef ref="Console" />
</Logger>
<Root level="trace" additivity="false">
<AppenderRef ref="Console" />
</Root>
</Loggers>
This is my log4j.xml file.
The below details are what I am getting if I use Configuration object in Java code.
X.Y.Z --- ERROR ----Parent : X.Y
X.Y --- ERROR ----Parent : X
X --- ERROR ----Parent : root
root --- TRACE ----Parent : null
The above details tell us the proper Parent name but it's not inheriting levels from parent logger "root".
It is more common to use the additivity="false" attribute on the named Loggers, instead of on the Root logger.
The final part of your question is unclear to me. What do you mean exactly by "... if I use Configuration object..."? Are you configuring log4j2 with Java source code in addition to the log4j2.xml configuration file? Or are you simply calling Logger.trace? Can you show the source code?
Also, can you show your complete log4j2.xml configuration?
When you say "The below details are what I am getting...", do you mean that this is the output generated by Log4j on the console?
In the docs it says that you can't put the additivity attribute on the Root logger because it doesn't make sense. There is no logger above it to add to.
Additivity basically means "pass on log entries to the parent logger in the hierarchy"
It doesn't inherit levels from the parent. A log entry has a level. Whether it is printed depends on whether there is a logger to catch such an entry (one that accepts that level).
So X.Y.Z will pass logs to X.Y unless additivity=false is set on the X.Y.Z logger config. And so on

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

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/>

Resources