Re: Log4j configuration in a Groovy Script

Per Nyfelt <[email protected]> Wed, 20 Aug 2025 10:22:59 +0200
Newsgroups gmane.comp.lang.groovy.user
Message-ID <CAOAt0KQVJQ-wGnEbm+uVqJ0Z0iA3c11tZjP+aj2vZ9iS64Ga8Q@mail.gmail.com>
--00000000000014383e063cc7afca
Content-Type: text/plain; charset="UTF-8"

Interesting! I did some more testing. most combinations does work 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

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 Logger log = 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)

log.info('Hello world')

This will not log anything, only the println will be shown.
The variant with LogManager.getLogger(this.class.name) does work however

The variations i tried are here in case anyone want to verify:
https://github.com/perNyfelt/groovy-issues/tree/main/logging/src

Best regards,
Per

On Tue, 19 Aug 2025 at 13:18, Jochen Theodorou <[email protected]> wrote:

>
>
> On 19.08.25 09:31, Per Nyfelt wrote:
> [...]
> > 1. Set the log level on the root logger
> > @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
> > import org.apache.logging.log4j.core.config.Configurator
> >
> > Configurator.setRootLevel(Level.INFO)
> >
> > @Field
> > final Logger log = LogManager.getLogger()
> >
> > In this case only LogManager.getLogger() works,
> > LogManager.getLogger(this.class) does not work.
>
> not the reverse? getLogger should have the problem,
> getLogger(this.class) maybe not. That is also what I can verify.
>
> [...]
> > I.e. IndyInterface instead of my script class.
>
> yeah, we have at least one bug in the indy callsite caching code, that
> is causing this. Would be nice if LOG4j had a way to ignore classes in
> that discovery phase... it does not, right?
>
> > To make log output better you need to do (the script name is
> > createExcel.groovy)
> >
> > @Field
> > final Logger log = LogManager.getLogger(this.class.name <
> http://this.class.name>)
> > Configurator.setLevel(log.getName(), Level.INFO)
> > Configurator.setRootLevel(Level.INFO)
> > LogManager.getContext(false).updateLoggers()
> >
> > 09:24:29.625 [main] INFO  createExcel - Found 2 CSV files to process.
> >
> > LogManager.getLogger(this.class) does NOT work (results in no output)
> which is curious.
>
> In my test it was for example Script1 if executed from a GroovyShell, or
> the script name as class name if executed from the command line.
>
> bye Jochen
>

--00000000000014383e063cc7afca
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Interesting! I did some more testing. most combinations do=
es work but i found two that yield surprising results:<div><br></div><div>1=
. Instantiate=C2=A0logger without specifier gives log name as IndyInterface=
</div><div><div style=3D"background-color:rgb(30,31,34);color:rgb(188,190,1=
96)"><pre style=3D"font-family:&quot;JetBrains Mono&quot;,monospace"><span =
style=3D"color:rgb(122,126,133)">#!/usr/bin/env groovy<br></span><span styl=
e=3D"color:rgb(179,174,96)">@Grab</span>(group=3D<span style=3D"color:rgb(1=
06,171,115)">&#39;org.apache.logging.log4j&#39;</span>, module=3D<span styl=
e=3D"color:rgb(106,171,115)">&#39;log4j-api&#39;</span>, version=3D<span st=
yle=3D"color:rgb(106,171,115)">&#39;2.20.0&#39;</span>)<br><span style=3D"c=
olor:rgb(179,174,96)">@Grab</span>(group=3D<span style=3D"color:rgb(106,171=
,115)">&#39;org.apache.logging.log4j&#39;</span>, module=3D<span style=3D"c=
olor:rgb(106,171,115)">&#39;log4j-core&#39;</span>, version=3D<span style=
=3D"color:rgb(106,171,115)">&#39;2.20.0&#39;</span>)<br><span style=3D"colo=
r:rgb(179,174,96)">@Grab</span>(group=3D<span style=3D"color:rgb(106,171,11=
5)">&#39;org.apache.logging.log4j&#39;</span>, module=3D<span style=3D"colo=
r:rgb(106,171,115)">&#39;log4j-slf4j-impl&#39;</span>, version=3D<span styl=
e=3D"color:rgb(106,171,115)">&#39;2.20.0&#39;</span>)<br><br><span style=3D=
"color:rgb(207,142,109)">import </span>org.apache.logging.log4j.Logger<br><=
span style=3D"color:rgb(207,142,109)">import </span>org.apache.logging.log4=
j.LogManager<br><span style=3D"color:rgb(207,142,109)">import </span>org.ap=
ache.logging.log4j.Level<br><br><span style=3D"color:rgb(207,142,109)">fina=
l </span>Logger log =3D <span style=3D"color:rgb(117,122,133)">LogManager</=
span>.getLogger()<br>log.<span style=3D"color:rgb(117,122,133)">setLevel</s=
pan>(<span style=3D"color:rgb(117,122,133)">Level</span>.INFO)<br>println <=
span style=3D"color:rgb(106,171,115)">&quot;Running script </span>$<span st=
yle=3D"color:rgb(207,142,109)">this</span><span style=3D"color:rgb(106,171,=
115)">.class&quot;<br></span>log.<span style=3D"color:rgb(117,122,133)">inf=
o</span>(<span style=3D"color:rgb(106,171,115)">&#39;Hello world&#39;</span=
>)<br><span style=3D"color:rgb(122,126,133)">// will print:<br></span><span=
 style=3D"color:rgb(122,126,133)">// Running script class noSpecifierInstan=
ceConfig<br></span><span style=3D"color:rgb(122,126,133)">// 10:12:18.256 [=
main] INFO  org.codehaus.groovy.vmplugin.v8.IndyInterface - Hello world<br>=
</span><span style=3D"color:rgb(122,126,133)"><br></span></pre></div></div>=
<div>2. Setting the root level and give the logger the script class yields =
no output:<br></div><div><div style=3D"background-color:rgb(30,31,34);color=
:rgb(188,190,196)"><pre style=3D"font-family:&quot;JetBrains Mono&quot;,mon=
ospace"><span style=3D"color:rgb(122,126,133)">#!/usr/bin/env groovy<br></s=
pan><span style=3D"color:rgb(179,174,96)">@Grab</span>(group=3D<span style=
=3D"color:rgb(106,171,115)">&#39;org.apache.logging.log4j&#39;</span>, modu=
le=3D<span style=3D"color:rgb(106,171,115)">&#39;log4j-api&#39;</span>, ver=
sion=3D<span style=3D"color:rgb(106,171,115)">&#39;2.20.0&#39;</span>)<br><=
span style=3D"color:rgb(179,174,96)">@Grab</span>(group=3D<span style=3D"co=
lor:rgb(106,171,115)">&#39;org.apache.logging.log4j&#39;</span>, module=3D<=
span style=3D"color:rgb(106,171,115)">&#39;log4j-core&#39;</span>, version=
=3D<span style=3D"color:rgb(106,171,115)">&#39;2.20.0&#39;</span>)<br><span=
 style=3D"color:rgb(179,174,96)">@Grab</span>(group=3D<span style=3D"color:=
rgb(106,171,115)">&#39;org.apache.logging.log4j&#39;</span>, module=3D<span=
 style=3D"color:rgb(106,171,115)">&#39;log4j-slf4j-impl&#39;</span>, versio=
n=3D<span style=3D"color:rgb(106,171,115)">&#39;2.20.0&#39;</span>)<br><br>=
<span style=3D"color:rgb(207,142,109)">import </span>groovy.transform.<span=
 style=3D"color:rgb(179,174,96)">Field<br></span><span style=3D"color:rgb(2=
07,142,109)">import </span>org.apache.logging.log4j.Logger<br><span style=
=3D"color:rgb(207,142,109)">import </span>org.apache.logging.log4j.LogManag=
er<br><span style=3D"color:rgb(207,142,109)">import </span>org.apache.loggi=
ng.log4j.Level<br><span style=3D"color:rgb(207,142,109)">import </span>org.=
apache.logging.log4j.core.config.Configurator<br><br><span style=3D"color:r=
gb(117,122,133)">Configurator</span>.setRootLevel(<span style=3D"color:rgb(=
117,122,133)">Level</span>.INFO)<br><br><span style=3D"color:rgb(179,174,96=
)">@Field<br></span><span style=3D"color:rgb(207,142,109)">final </span>Log=
ger <span style=3D"color:rgb(199,125,187)">log </span>=3D <span style=3D"co=
lor:rgb(117,122,133)">LogManager</span>.getLogger(<span style=3D"color:rgb(=
207,142,109)">this</span>.<span style=3D"color:rgb(199,125,187)">class</spa=
n>)<br>println <span style=3D"color:rgb(106,171,115)">&quot;Running script =
</span>$<span style=3D"color:rgb(207,142,109)">this</span><span style=3D"co=
lor:rgb(106,171,115)">.class&quot;</span><div><pre style=3D"font-family:&qu=
ot;JetBrains Mono&quot;,monospace"><span style=3D"color:rgb(122,126,133)">/=
/ This will NOT work, no log output is generated<br></span><span style=3D"c=
olor:rgb(122,126,133)">// note that LogManager.getLogger() DOES work and so=
 does LogManager.getLogger(<a href=3D"http://this.class.name">this.class.na=
me</a>)</span></pre></div></pre><pre style=3D"font-family:&quot;JetBrains M=
ono&quot;,monospace"><span style=3D"color:rgb(199,125,187)">log</span>.<spa=
n style=3D"color:rgb(117,122,133)">info</span>(<span style=3D"color:rgb(106=
,171,115)">&#39;Hello world&#39;</span>)</pre></div></div><div>This will no=
t log anything, only the println will be shown.</div><div>The variant with=
=C2=A0<span style=3D"font-family:&quot;JetBrains Mono&quot;,monospace;backg=
round-color:rgb(30,31,34);color:rgb(117,122,133)">LogManager</span><span st=
yle=3D"font-family:&quot;JetBrains Mono&quot;,monospace;background-color:rg=
b(30,31,34);color:rgb(188,190,196)">.getLogger(</span><span style=3D"font-f=
amily:&quot;JetBrains Mono&quot;,monospace;background-color:rgb(30,31,34);c=
olor:rgb(207,142,109)">this</span><span style=3D"font-family:&quot;JetBrain=
s Mono&quot;,monospace;background-color:rgb(30,31,34);color:rgb(188,190,196=
)">.</span><span style=3D"font-family:&quot;JetBrains Mono&quot;,monospace;=
background-color:rgb(30,31,34);color:rgb(199,125,187)">class</span><span st=
yle=3D"font-family:&quot;JetBrains Mono&quot;,monospace;background-color:rg=
b(30,31,34);color:rgb(188,190,196)">.</span><span style=3D"font-family:&quo=
t;JetBrains Mono&quot;,monospace;background-color:rgb(30,31,34);color:rgb(1=
99,125,187)">name</span><span style=3D"font-family:&quot;JetBrains Mono&quo=
t;,monospace;background-color:rgb(30,31,34);color:rgb(188,190,196)">)</span=
>=C2=A0does work however</div><div><br></div><div>The variations i tried ar=
e here in case anyone want to verify: <a href=3D"https://github.com/perNyfe=
lt/groovy-issues/tree/main/logging/src">https://github.com/perNyfelt/groovy=
-issues/tree/main/logging/src</a></div><div><br></div><div>Best regards,</d=
iv><div>Per</div></div><br><div class=3D"gmail_quote gmail_quote_container"=
><div dir=3D"ltr" class=3D"gmail_attr">On Tue, 19 Aug 2025 at 13:18, Jochen=
 Theodorou &lt;<a href=3D"mailto:[email protected]">[email protected]</a>&g=
t; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0p=
x 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
<br>
On 19.08.25 09:31, Per Nyfelt wrote:<br>
[...]<br>
&gt; 1. Set the log level on the root logger<br>
&gt; @Grab(group=3D&#39;org.apache.logging.log4j&#39;, module=3D&#39;log4j-=
api&#39;, <br>
&gt; version=3D&#39;2.20.0&#39;),<br>
&gt; @Grab(group=3D&#39;org.apache.logging.log4j&#39;, module=3D&#39;log4j-=
core&#39;, <br>
&gt; version=3D&#39;2.20.0&#39;),<br>
&gt; @Grab(group=3D&#39;org.apache.logging.log4j&#39;, module=3D&#39;log4j-=
slf4j-impl&#39;, <br>
&gt; version=3D&#39;2.20.0&#39;)<br>
&gt; <br>
&gt; import org.apache.logging.log4j.Logger<br>
&gt; import org.apache.logging.log4j.LogManager<br>
&gt; import org.apache.logging.log4j.Level<br>
&gt; import org.apache.logging.log4j.core.config.Configurator<br>
&gt; <br>
&gt; Configurator.setRootLevel(Level.INFO)<br>
&gt; <br>
&gt; @Field<br>
&gt; final Logger log =3D LogManager.getLogger()<br>
&gt; <br>
&gt; In this case=C2=A0only LogManager.getLogger() works, <br>
&gt; LogManager.getLogger(this.class) does not work.<br>
<br>
not the reverse? getLogger should have the problem, <br>
getLogger(this.class) maybe not. That is also what I can verify.<br>
<br>
[...]<br>
&gt; I.e. IndyInterface instead of my script class.<br>
<br>
yeah, we have at least one bug in the indy callsite caching code, that <br>
is causing this. Would be nice if LOG4j had a way to ignore classes in <br>
that discovery phase... it does not, right?<br>
<br>
&gt; To make log output better you need to do (the script name is <br>
&gt; createExcel.groovy)<br>
&gt; <br>
&gt; @Field<br>
&gt; final Logger log =3D LogManager.getLogger(<a href=3D"http://this.class=
.name" rel=3D"noreferrer" target=3D"_blank">this.class.name</a> &lt;<a href=
=3D"http://this.class.name" rel=3D"noreferrer" target=3D"_blank">http://thi=
s.class.name</a>&gt;)<br>
&gt; Configurator.setLevel(log.getName(), Level.INFO)<br>
&gt; Configurator.setRootLevel(Level.INFO)<br>
&gt; LogManager.getContext(false).updateLoggers()<br>
&gt; <br>
&gt; 09:24:29.625 [main] INFO =C2=A0createExcel - Found 2 CSV files to proc=
ess.<br>
&gt; <br>
&gt; LogManager.getLogger(this.class) does NOT work (results in no output) =
which is curious.<br>
<br>
In my test it was for example Script1 if executed from a GroovyShell, or <b=
r>
the script name as class name if executed from the command line.<br>
<br>
bye Jochen<br>
</blockquote></div>

--00000000000014383e063cc7afca--