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

Reply via email to