Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get console Logger (or TaskListener) from Pipeline script method

If I have a Pipeline script method in Pipeline script (Jenkinsfile), my Global Pipeline Library's vars/ or in a src/ class, how can obtain the OutputStream for the console log? I want to write directly to the console log.

I know I can echo or println, but for this purpose I need to write without the extra output that yields. I also need to be able to pass the OutputStream to something else.

I know I can call TaskListener.getLogger() if I can get the TaskListener (really hudson.util.StreamTaskListener) instance, but how?

I tried:

  • I've looked into manager.listener.logger (from the groovy postbuild plugin) and in the early-build context I'm calling from it doesn't yield an OutputStream that writes to the job's Console Log.

    echo "listener is a ${manager.listener} - ${manager.listener.getClass().getName()} from ${manager} and has a ${manager.listener.logger} of class ${manager.listener.logger.getClass().getName()}"
    

    prints

    listener is a hudson.util.LogTaskListener@420c55c4 - hudson.util.LogTaskListener from org.jvnet.hudson.plugins.groovypostbuild.GroovyPostbuildRecorder$BadgeManager@58ac0c55 and has a java.io.PrintStream@715b9f99 of class java.io.PrintStream
    
  • I know you can get it from a StepContext via context.get(TaskListener.class) but I'm not in a Step, I'm in a CpsScript (i.e. WorkflowScript i.e. Jenkinsfile).

  • Finding it from a CpsFlowExecution obtained from the DSL instance registered as the steps script-property, but I couldn't work out how to discover the TaskListener that's passed to it when it's created

How is it this hard? What am I missing? There's so much indirect magic I find it incredibly hard to navigate the system.

BTW, I'm aware direct access is blocked by Script Security, but I can create @Whitelisted methods, and anything in a global library's vars/ is always whitelisted anyway.

like image 745
Craig Ringer Avatar asked Mar 05 '23 03:03

Craig Ringer


1 Answers

You can access the build object from the Jenkins root object:

def listener = Jenkins.get()
    .getItemByFullName(env.JOB_NAME)
    .getBuildByNumber(Integer.parseInt(env.BUILD_NUMBER))
    .getListener()

def logger = listener.getLogger() as PrintStream

logger.println("Listener: ${listener} Logger: ${logger}")

Result:

Listener: CloseableTaskListener[org.jenkinsci.plugins.workflow.log.BufferedBuildListener@6e9e6a16 / org.jenkinsci.plugins.workflow.log.BufferedBuildListener@6e9e6a16] Logger: java.io.PrintStream@423efc01
like image 177
Mzzl Avatar answered Apr 24 '23 09:04

Mzzl