On 20.08.25 10:22, Per Nyfelt wrote:
Interesting! I did some more testing. most combinations does work
good
but i found two that yield surprising results:
1. Instantiate logger without specifier gives log name as IndyInterface
#!/usr/bin/env groovy
@Grab(group='org.apache.logging.log4j', module='log4j-api', version='2.20.0')
@Grab(group='org.apache.logging.log4j', module='log4j-core', version='2.20.0')
@Grab(group='org.apache.logging.log4j', module='log4j-slf4j-impl',
version='2.20.0')
import org.apache.logging.log4j.Logger
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Level
final Logger log =LogManager.getLogger()
log.setLevel(Level.INFO)
println"Running script $this.class"
log.info('Hello world')
// will print:
// Running script class noSpecifierInstanceConfig
// 10:12:18.256 [main] INFO
org.codehaus.groovy.vmplugin.v8.IndyInterface - Hello world
What Log4j does is getting a stack trace in the getLogger method to then
go back by a bit and take that as class:
https://github.com/apache/logging-log4j2/blob/44ab0131718fc8d1fcb45604b0f1a8187765910d/log4j-api/src/main/java/org/apache/logging/log4j/LogManager.java#L584
leading to
https://github.com/apache/logging-log4j2/blob/44ab0131718fc8d1fcb45604b0f1a8187765910d/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/StackLocator.java#L81:
return WALKER.walk(s ->
s.skip(depth).findFirst()).map(StackWalker.StackFrame::getDeclaringClass).orElse(null);
Now this will just go back in the trace and use whatever it finds
ignoring frames from reflection. This here
getLogger(StackLocatorUtil.getCallerClass(3))
maybe this here also works:
getLogger((Class) null)
would probably work for you too. both not so nice of course
2. Setting the root level and give the logger the script class yields no
output:
#!/usr/bin/env groovy
@Grab(group='org.apache.logging.log4j', module='log4j-api', version='2.20.0')
@Grab(group='org.apache.logging.log4j', module='log4j-core', version='2.20.0')
@Grab(group='org.apache.logging.log4j', module='log4j-slf4j-impl',
version='2.20.0')
import groovy.transform.Field
import org.apache.logging.log4j.Logger
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Level
import org.apache.logging.log4j.core.config.Configurator
Configurator.setRootLevel(Level.INFO)
@Field
final Loggerlog =LogManager.getLogger(this.class)
println"Running script $this.class"
// This will NOT work, no log output is generated
// note that LogManager.getLogger() DOES work and so does
LogManager.getLogger(this.class.name <http://this.class.name>)
log.info('Hello world')
This will not log anything, only the println will be shown.
With "this.class" normally works for me.
The variant with LogManager.getLogger(this.class.name) does work however
strange. I mean it is doing class loading then, ok... but that should be
no other class.
The variations i tried are here in case anyone want to verify: https://
github.com/perNyfelt/groovy-issues/tree/main/logging/src <https://
github.com/perNyfelt/groovy-issues/tree/main/logging/src>
bye Jochen