Log4j2: How to define multiple loggers - log4j

I have defined the multiple loggers as seen below(com.xyz and org.xyz). Log4j2 is ignoring the first logger definition and loads only the second one. In the example, the org.xyz is not loaded.
{
"configuration": {
"name": "Default",
"appenders": {
"Console": {
"name": "Console-Appender",
"target": "SYSTEM_OUT",
"PatternLayout": {"pattern": "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"}
}
},
"loggers": {
"logger": {
"name": "org.xyz",
"level": "info",
"appender-ref": [{"ref": "Console-Appender","level": "info"}]
},
"logger": {
"name": "com.xyz",
"level": "debug",
"appender-ref": [{"ref": "Console-Appender", "level": "debug"}]
},
"root": {
"level": "warn",
"appender-ref": {"ref": "Console-Appender","level": "warn"}
}
}
}
}
Find below the log4j2 debug messages.
DEBUG StatusLogger Processing node for object loggers
DEBUG StatusLogger Processing node for object logger
DEBUG StatusLogger Node name is of type STRING
DEBUG StatusLogger Node level is of type STRING
DEBUG StatusLogger Node additivity is of type STRING
DEBUG StatusLogger Processing node for array appender-ref
DEBUG StatusLogger Processing appender-ref[0]
DEBUG StatusLogger Returning logger with parent loggers of type logger:class org.apache.logging.log4j.core.config.LoggerConfig
DEBUG StatusLogger Processing node for object root
DEBUG StatusLogger Node level is of type STRING
DEBUG StatusLogger Processing node for object appender-ref
DEBUG StatusLogger Node ref is of type STRING
DEBUG StatusLogger Node level is of type STRING
DEBUG StatusLogger Returning appender-ref with parent root of type appender-ref:class org.apache.logging.log4j.core.config.AppenderRef
DEBUG StatusLogger Returning root with parent loggers of type root:class org.apache.logging.log4j.core.config.LoggerConfig$RootLogger
DEBUG StatusLogger Returning loggers with parent root of type loggers:class org.apache.logging.log4j.core.config.LoggersPlugin
DEBUG StatusLogger Completed parsing configuration
DEBUG StatusLogger Building Plugin[name=logger, class=org.apache.logging.log4j.core.config.LoggerConfig].
DEBUG StatusLogger createLogger(additivity="false", level="DEBUG", name="com.xyz", includeLocation="null", ={Console-Appender}, ={}, Configuration(Default), Filter=null)
DEBUG StatusLogger Building Plugin[name=appender-ref, class=org.apache.logging.log4j.core.config.AppenderRef].
DEBUG StatusLogger createAppenderRef(ref="Console-Appender", level="WARN", Filter=null)
DEBUG StatusLogger Building Plugin[name=root, class=org.apache.logging.log4j.core.config.LoggerConfig$RootLogger].
DEBUG StatusLogger createLogger(additivity="null", level="WARN", includeLocation="null", ={Console-Appender}, ={}, Configuration(Default), Filter=null)
DEBUG StatusLogger Building Plugin[name=loggers, class=org.apache.logging.log4j.core.config.LoggersPlugin].
DEBUG StatusLogger createLoggers(={com.xyz, root})
Is my configuration correct?

For defining multiple loggers in log4j2 JSON configuration file, you should declare logger as array.
With logger array, your configuration file would change to below -
{
"configuration": {
"name": "Default",
"appenders": {
"Console": {
"name": "Console-Appender",
"target": "SYSTEM_OUT",
"PatternLayout": {"pattern": "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"}
}
},
"loggers": {
"logger": [
{
"name": "org.xyz",
"level": "info",
"appender-ref": [{"ref": "Console-Appender","level": "info"}]
},
{
"name": "com.xyz",
"level": "debug",
"appender-ref": [{"ref": "Console-Appender", "level": "debug"}]
}
],
"root": {
"level": "warn",
"appender-ref": {"ref": "Console-Appender","level": "warn"}
}
}
}
}

Related

How to create second, separate log4j2 logger?

I am trying to create a completely separate second Context/Configuration/Logger - not a logger within an existing config/context.
Log messages are going to STDOUT.
Current code
ConfigurationBuilder<BuiltConfiguration> _configurationBuilder = ConfigurationBuilderFactory.newConfigurationBuilder();
_configurationBuilder.setConfigurationName("SMDR_DEBUG_" + pName);
LoggerContext _loggerContext = new LoggerContext("SMDR_DEBUG_" + pName);
_configurationBuilder.setLoggerContext(_loggerContext);
_configurationBuilder.setStatusLevel(Level.TRACE);
// Create the appender
AppenderComponentBuilder log4jFileAppenderBuilder = _configurationBuilder.
newAppender(pName + "_SmdrDailyRollingFileAppender", "RollingFile");
log4jFileAppenderBuilder.addAttribute("filename", pLogFilename);
log4jFileAppenderBuilder.addAttribute("filePattern", pLogFilenamePattern);
// Setup roll-over
ComponentBuilder triggeringPolicy = _configurationBuilder.newComponent("Policies")
.addComponent(_configurationBuilder.newComponent("TimeBasedTriggeringPolicy").
addAttribute("interval", "1"));
log4jFileAppenderBuilder.addComponent(triggeringPolicy);
// Configure the PatternLayout
LayoutComponentBuilder layoutComponentBuilder = _configurationBuilder.newLayout("PatternLayout").
addAttribute("pattern", DEBUG_PATTERN_LAYOUT_STRING);
log4jFileAppenderBuilder.add(layoutComponentBuilder);
// Add it back into configuration
_configurationBuilder.add(log4jFileAppenderBuilder);
// https://logging.apache.org/log4j/2.x/manual/customconfig.html
RootLoggerComponentBuilder loggerBuilder = _configurationBuilder.newRootLogger(Level.DEBUG);
loggerBuilder.add(_configurationBuilder.newAppenderRef(pName + "_SmdrDailyRollingFileAppender"));
loggerBuilder.addAttribute("additivity", false);
_configurationBuilder.add(loggerBuilder);
LoggerContext _lc = Configurator.initialize(_configurationBuilder.build());
System.out.println("***** SRJ SRJ SMDR context from initialize is " + _lc);
Logger _g = _loggerContext.getRootLogger();
System.out.println("***** SRJ SRJ SMDR rootlogger from context is " + _g);
_g.error("***** SRJ SRJ ROOT LOGGER IN SMDR_DEBUG.txt");
Logger _gg = _loggerContext.getLogger(pName);
System.out.println("***** SRJ SRJ SMDR logger "+pName+" from context is " + _gg);
_gg.error("***** SRJ SRJ "+pName+" LOGGER IN SMDR_DEBUG.txt");
The .error() calls above go to STDOUT. Note that I have tried using reconfigure() instead of initialize(), but that messes up my original configuration.
The loggers seem wrong, as I print them out and they seem like the name and the context are right, but at error level. And things to go stdout and not the appender.
***** SRJ SRJ SMDR rootlogger from context is :ERROR in SMDR_DEBUG_Global
16:23:59.989 [main] ERROR - ***** SRJ SRJ ROOT LOGGER IN SMDR_DEBUG.txt <-- should be in log file
***** SRJ SRJ SMDR logger Global from context is Global:ERROR in SMDR_DEBUG_Global
16:23:59.990 [main] ERROR Global - ***** SRJ SRJ Global LOGGER IN SMDR_DEBUG.txt <-- should be in log file
XML generated from builder:
<?xml version="1.0" ?>
<Configuration name="SMDR_DEBUG_Global" status="TRACE">
<Appenders>
<RollingFile name="Global_SmdrDailyRollingFileAppender" filename="ps/debug/SMDR_DEBUG.txt"
filePattern="ps/debug/SMDR_DEBUG_%d{yyyyMMdd}.txt.gz">
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<PatternLayout pattern="%d{MM.DD.yy-HH:mm:ss} %m%n"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="DEBUG" additivity="false">
<AppenderRef ref="Global_SmdrDailyRollingFileAppender"/>
</Root>
</Loggers>
</Configuration>
Trace from builder:
2022-05-19 16:23:59,921 main DEBUG PluginManager 'Converter' found 45 plugins
2022-05-19 16:23:59,922 main DEBUG Starting OutputStreamManager SYSTEM_OUT.false.false-3
2022-05-19 16:23:59,940 main INFO Log4j appears to be running in a Servlet environment, but there's no log4j-web module available. If you want better web container support, please add the log4j-web JAR to your web archive or server lib directory.
2022-05-19 16:23:59,941 main DEBUG Apache Log4j Core 2.17.1 initializing configuration org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration#3a3e78f
2022-05-19 16:23:59,942 main DEBUG Installed 1 script engine
2022-05-19 16:23:59,963 Thread Context Data Task DEBUG Initializing Thread Context Data Service Providers
2022-05-19 16:23:59,964 Thread Context Data Task DEBUG Thread Context Data Service Provider initialization complete
2022-05-19 16:23:59,969 main DEBUG Oracle Nashorn version: 1.8.0_252, language: ECMAScript, threading: Not Thread Safe, compile: true, names: [nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript], factory class: jdk.nashorn.api.scripting.NashornScriptEngineFactory
2022-05-19 16:23:59,969 main DEBUG PluginManager 'Core' found 127 plugins
2022-05-19 16:23:59,969 main DEBUG PluginManager 'Level' found 0 plugins
2022-05-19 16:23:59,970 main DEBUG PluginManager 'Lookup' found 16 plugins
2022-05-19 16:23:59,970 main DEBUG Building Plugin[name=AppenderRef, class=org.apache.logging.log4j.core.config.AppenderRef].
2022-05-19 16:23:59,971 main DEBUG createAppenderRef(ref="Global_SmdrDailyRollingFileAppender", level="null", Filter=null)
2022-05-19 16:23:59,971 main DEBUG Building Plugin[name=root, class=org.apache.logging.log4j.core.config.LoggerConfig$RootLogger].
2022-05-19 16:23:59,972 main DEBUG createLogger(additivity="false", level="DEBUG", includeLocation="null", ={Global_SmdrDailyRollingFileAppender}, ={}, Configuration(SMDR_DEBUG_Global), Filter=null)
2022-05-19 16:23:59,972 main DEBUG Building Plugin[name=loggers, class=org.apache.logging.log4j.core.config.LoggersPlugin].
2022-05-19 16:23:59,973 main DEBUG createLoggers(={root})
2022-05-19 16:23:59,973 main DEBUG Building Plugin[name=TimeBasedTriggeringPolicy, class=org.apache.logging.log4j.core.appender.rolling.TimeBasedTriggeringPolicy].
2022-05-19 16:23:59,975 main DEBUG TimeBasedTriggeringPolicy$Builder(interval="1", modulate="null", maxRandomDelay="null")
2022-05-19 16:23:59,975 main DEBUG Building Plugin[name=Policies, class=org.apache.logging.log4j.core.appender.rolling.CompositeTriggeringPolicy].
2022-05-19 16:23:59,975 main DEBUG createPolicy(={TimeBasedTriggeringPolicy(nextRolloverMillis=0, interval=1, modulate=false)})
2022-05-19 16:23:59,975 main DEBUG Building Plugin[name=layout, class=org.apache.logging.log4j.core.layout.PatternLayout].
2022-05-19 16:23:59,976 main DEBUG PatternLayout$Builder(pattern="%d{MM.DD.yy-HH:mm:ss} %m%n", PatternSelector=null, Configuration(SMDR_DEBUG_Global), Replace=null, charset="null", alwaysWriteExceptions="null", disableAnsi="null", noConsoleNoAnsi="null", header="null", footer="null")
2022-05-19 16:23:59,976 main DEBUG PluginManager 'Converter' found 45 plugins
2022-05-19 16:23:59,982 main DEBUG Building Plugin[name=appender, class=org.apache.logging.log4j.core.appender.RollingFileAppender].
2022-05-19 16:23:59,983 main DEBUG RollingFileAppender$Builder(fileName="ps/debug/SMDR_DEBUG.txt", filePattern="ps/debug/SMDR_DEBUG_%d{yyyyMMdd}.txt.gz", append="null", locking="null", Policies(CompositeTriggeringPolicy(policies=[TimeBasedTriggeringPolicy(nextRolloverMillis=0, interval=1, modulate=false)])), Strategy=null, advertise="null", advertiseUri="null", createOnDemand="null", filePermissions="null", fileOwner="null", fileGroup="null", bufferedIo="null", bufferSize="null", immediateFlush="null", ignoreExceptions="null", PatternLayout(%d{MM.DD.yy-HH:mm:ss} %m%n), name="Global_SmdrDailyRollingFileAppender", Configuration(SMDR_DEBUG_Global), Filter=null, ={})
2022-05-19 16:23:59,984 main TRACE New file 'ps/debug/SMDR_DEBUG.txt' created = true
2022-05-19 16:23:59,984 main DEBUG Returning file creation time for /opt/SecureLogix/ETM/ps/debug/SMDR_DEBUG.txt
2022-05-19 16:23:59,984 main DEBUG Starting RollingFileManager ps/debug/SMDR_DEBUG.txt
2022-05-19 16:23:59,985 main DEBUG PluginManager 'FileConverter' found 2 plugins
2022-05-19 16:23:59,985 main DEBUG Setting prev file time to 2022-05-19T16:23:59.000+0100
2022-05-19 16:23:59,985 main DEBUG Initializing triggering policy CompositeTriggeringPolicy(policies=[TimeBasedTriggeringPolicy(nextRolloverMillis=0, interval=1, modulate=false)])
2022-05-19 16:23:59,986 main DEBUG Initializing triggering policy TimeBasedTriggeringPolicy(nextRolloverMillis=0, interval=1, modulate=false)
2022-05-19 16:23:59,987 main TRACE PatternProcessor.getNextTime returning 2022/05/20-00:00:00.000, nextFileTime=2022/05/19-00:00:00.000, prevFileTime=1970/01/01-01:00:00.000, current=2022/05/19-16:23:59.986, freq=DAILY
2022-05-19 16:23:59,988 main TRACE PatternProcessor.getNextTime returning 2022/05/20-00:00:00.000, nextFileTime=2022/05/19-00:00:00.000, prevFileTime=2022/05/19-00:00:00.000, current=2022/05/19-16:23:59.988, freq=DAILY
2022-05-19 16:23:59,988 main DEBUG Building Plugin[name=appenders, class=org.apache.logging.log4j.core.config.AppendersPlugin].
2022-05-19 16:23:59,988 main DEBUG createAppenders(={Global_SmdrDailyRollingFileAppender})
2022-05-19 16:23:59,989 main DEBUG Configuration org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration#3a3e78f initialized
Your problem comes from this line:
LoggerContext _lc = Configurator.initialize(_configurationBuilder.build());
The Configurator.initialize method retrieves the logger context associated to the current code (see ContextSelector) and configures it with the given configuration. This is not the same context as _loggerContext, which remains uninitialized and uses the default configuration (ERRORs on the console).
To configure _loggerContext use:
_loggerContext.setConfiguration(_configurationBuilder.build());

Using eslint causes my string to fail with no-irregular-whitespace error

I've started to use eslint (migrated from tslint) but this is throwing an error, not sure why!
Code snippet
const url = `${this.url}​/members​/${memberId}​/profile`;
It's super strange as other similar lines of code are not causing a problem! I'm not sure how to resolve this problem.
Full error message
Irregular whitespace not allowed.
eslint version = ^7.31.0
Thanks!!
Update
I have the following config but it produces an error when running lint
plugins: ["#typescript-eslint", "react"],
extends: [
"eslint:recommended",
"plugin:#typescript-eslint/recommended",
"plugin:react/recommended"
],
rules: {},
Error message
ESLint couldn't find the plugin "eslint-plugin-react".
Solution
Add this to the eslint config file:
rules: {
"no-irregular-whitespace": [
"error",
{ skipRegExps: true, skipTemplates: true },
],
},
Make sure your eslint config has:
"extends": [
"plugin:react/recommended"
]
...
"plugins": [
"react"
]

Logging in Python Using Config Json file

I am trying to log from python using a json config file which controls the configuration of the logger , below is sample config I am using
{
"version": 1,
"disable_existing_loggers": true,
"formatters": {
"json": {
"format": "%(asctime)s %(levelname)s %(filename)s %(lineno)s %(message)s"
}
},
"handlers": {
"json": {
"class": "logging.StreamHandler",
"formatter": "json"
}
},
"loggers": {
"": {
"handlers": ["json"],
"level": 20
}
}
}
This works fine but is there any Doc which would point to different formatters that are available to be used or similarly different handlers that can be used ?
Handlers
The different handlers you can choose from are listed in the docs. Among the different handlers, there are:
StreamHandler that "sends logging output to streams such as sys.stdout, sys.stderr or any file-like object"
FileHandler that "sends logging output to a disk file"
SocketHandler that "sends logging output to a network socket"
SysLogHandler that "supports sending logging messages to a remote or local Unix syslog".
...
Formatters
logging.Formatters can use any of the following LogRecord attributes inside the fmt string.
For example,
"%(asctime)s %(levelname)s %(name)s %(message)s"
# gives
2023-02-07 17:24:07,981 INFO foobar This is a message.
----
"%(name)s - %(levelname)s - %(pathname)s - %(filename)s - %(funcName)s - %(asctime)s - %(process)d - %(message)s"
# gives
loggername - INFO - default_formatter.py - default_formatter.py - my_func_name - 2023-02-07 17:25:02,734 - 380334 - This is an info message.

How can I make log4js on cygwin write exactly what I want to file?

I have a node.js project on cygwin, which I test with mocha.
My logger is log4js.
I have an appender to get log4js to write to file, but I don't know how to get it to write it exactly as I want.
Must-haves:
A different file for each time mocha runs (it's OK if mocha clobbers the old log files)
Unix line endings
Nice-to-have:
No color encodings in the file (I can get around this when mocha is run with -C, but ideally there would be something in log4js-config.js.)
How do I do this?
My current setup is as follows.
My log4js-config.js:
var log4js = require('log4js');
var log4js_config = {
"appenders": [{
"type": "console",
"layout": {
"type": "pattern",
"pattern": "%[%d{yyyy-MM-ddThh:mm:ss.SSS} [pid=%x{pid}] %p %c -%] %m",
"tokens": {pid: function(){return process.pid;}}
}
},{
"type": "file",
"filename": "jxg_log.log",
"layout": {
"type": "pattern",
"pattern": "%d{yyyy-MM-ddThh:mm:ss.SSS} [pid=%x{pid}] %p %c - %m",
"tokens": {pid: function(){return process.pid;}}
}
}],
replaceConsole: true
};
log4js.configure(log4js_config, {});
exports.logging = log4js;
My test file is:
var assert = require("assert");
var logger = require('../src/log4js-config').logging.getLogger('Mocha-Test');
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present', function(){
logger.debug("logger debug line 1");
assert.equal(-1, [1,2,3].indexOf(5));
assert.equal(-1, [1,2,3].indexOf(0));
logger.debug("logger debug last line");
})
})
})
(For the purposes of this question, there is no code under test. I run mocha with ./node_modules/mocha/bin/mocha.)
The log file that is output is this:
2014-11-24T13:45:00.012 [pid=90652] INFO console - %m
2014-11-24T13:45:00.018 [pid=90652] INFO console - %m
2014-11-24T13:45:00.019 [pid=90652] INFO console - Array
2014-11-24T13:45:00.020 [pid=90652] INFO console - #indexOf()
2014-11-24T13:45:00.021 [pid=90652] DEBUG Mocha-Test - logger debug line 1
2014-11-24T13:45:00.021 [pid=90652] DEBUG Mocha-Test - logger debug last line
2014-11-24T13:45:19.090 [pid=90180] INFO console - %m
2014-11-24T13:45:19.093 [pid=90180] INFO console - %m
2014-11-24T13:45:19.095 [pid=90180] INFO console - Array
2014-11-24T13:45:19.095 [pid=90180] INFO console - #indexOf()
2014-11-24T13:45:19.096 [pid=90180] DEBUG Mocha-Test - logger debug line 1
2014-11-24T13:45:19.096 [pid=90180] DEBUG Mocha-Test - logger debug last line
2014-11-24T13:50:13.716 [pid=88476] INFO console - %m
2014-11-24T13:50:13.720 [pid=88476] INFO console - [0m[0m
2014-11-24T13:50:13.721 [pid=88476] INFO console - [0m Array[0m
2014-11-24T13:50:13.722 [pid=88476] INFO console - [0m #indexOf()[0m
2014-11-24T13:50:13.722 [pid=88476] DEBUG Mocha-Test - logger debug line 1
2014-11-24T13:50:13.723 [pid=88476] DEBUG Mocha-Test - logger debug last line
Note three mocha runs here; the third time, I left out the -C to show the color encoding.
I can't show the line endings directly in the question, but there's this:
$ file jxg_log.log
jxg_log.log: ASCII text, with CRLF line terminators, with escape sequences
So, again: how can I overwrite the log file on subsequent runs, output unix newlines, and suppress the color codes?

How to log to different appenders from one Controller w/Grails & log4j

I have a controller where I would like to log to different appenders based on the level. So for examaple general usage would be written to a INFO usage.log. Certain events I determine should go to a WARN warning.log.
Here's a portion of my log4j config…
appenders {
file name: "usageAppender",
file: " /usr/local/logs/cs-wst/usage.log"
file name: "warningAppender",
file: " /usr/local/logs/cs-wst/warning.log"
}
info usageAppender: 'grails.app'
When I do this and run a statement like this in my controller log.info("request method fired") the line does show up in usage.log, but I'm having trouble getting other levels to work. I would like to run these two statements in the controller
log.info("request method fired")
…
log.warn("invalid credentials")
And have them logged to the appropriate file. Can anyone help?
Reference the code below;
appenders {
appender new DailyRollingFileAppender(
name: 'dailyerrorAppender',
threshold: org.apache.log4j.Level.DEBUG,
datePattern: "'.'yyyy-MM-dd", // See the API for all patterns.
fileName: "./error",
layout: pattern(conversionPattern:'%d [%t] %-5p %c{2} %x - %m%n')
)
appender new DailyRollingFileAppender(
name: 'dailywarnAppender',
threshold: org.apache.log4j.Level.WARN,
datePattern: "'.'yyyy-MM-dd", // See the API for all patterns.
fileName: "./warn",
layout: pattern(conversionPattern:'%d [%t] %-5p %c{2} %x - %m%n')
)
}
environments {
development{
debug dailyerrorAppender:"errors", additivity: false
warn dailywarnAppender:"warns", additivity: false
}
qa{
debug dailyerrorAppender:"errors", additivity: false
warn dailywarnAppender:"warns", additivity: false
}
production{
debug dailyerrorAppender:"errors", additivity: false
warn dailywarnAppender:"warns", additivity: false
}
}
def errorLog = Logger.getLogger("errors")
errorLog.debug("your error messages")
def warnLog = Logger.getLogger("warns")
warnLog.warn("your warn messages")

Resources