Joey Trang
Joey Trang

Reputation: 1173

Propagating logs in shared library to jenkins job console

I am trying to write a shared libray which combines of global variables and shared functions to perform automated task of build and deployment for our project

The project layout as below:

enter image description here

The project has two major parts:

  1. Global shared variables which are placed in vars folder

  2. Supporting groovy scripts to abstract logics which in turn will be called in the global variable.

enter image description here

Inside the groovy class, I am using println to log debugging information

enter image description here

But it never got printed out when it is invoked through jenkins pipeline job

enter image description here

The log console of jenkins job as below:

enter image description here

Can someone show me how to propage logs from groovy class to jenkins job console as I can see only log from println in the global shared script is shown in log console.

Upvotes: 6

Views: 8002

Answers (4)

ThomasMX
ThomasMX

Reputation: 1811

This answer addresses those who need to log something from deep in the call stack. It might be cumbersome to pass pipeline "steps" object all the way in the stack of the shared library especially when the call hierarchy gets complex. One might therefore create a helper class with a static Closure that holds some logic to print to the console. For example:

class JenkinsUtils {

    static Closure<Void> log = { throw new RuntimeException("Logger not configured") }

}

In the steps groovy, this needs to be initialized (ideally in a NonCPS block). For example your Jenkinsfile (or var file):

@NonCPS
def setupLogging() {
  JenkinsUtils.log = { String msg-> println msg }
}

def call() {
  ...
  setupLogging()
  ...
}

And then, from any arbitrary shared library class one can call print to console simply like:

class RestClient {

  void doStuff() {
    JenkinsUtils.log("...")
  }
  
}

I know this is still hacky for a workaround, although I could not find any better working solution even though I spent quite some time researching.

Posted this also as a gist to my github profile

Upvotes: 1

old-monk
old-monk

Reputation: 931

All the commands/DSL e.g: println, sh, bat, checkout etc can't be accessed from shared library. ref: https://jenkins.io/doc/book/pipeline/shared-libraries/.

You can access steps by passing them to shared library.

//your library
package org.foo
class Utilities implements Serializable {
  def steps
  Utilities(steps) {this.steps = steps}
  def mvn(args) {
    steps.println "Hello world"
    steps.echo "Hello echo"
    //steps.sh "${steps.tool 'Maven'}/bin/mvn -o ${args}"
  }
} 

jenkinsfile

@Library('utils') import org.foo.Utilities
def utils = new Utilities(this)
node {
  utils.mvn '!!! so this how println can be worked out or any other step!!'
}

Upvotes: 3

Steve
Steve

Reputation: 71

I am not a 100% sure if this what you are looking for, but printing things in a shared library can be achieved by passing steps and using echo. See Accessing steps in https://jenkins.io/doc/book/pipeline/shared-libraries/

Upvotes: 0

Joey Trang
Joey Trang

Reputation: 1173

I just found a way to do it by calling println step that is available in the jenkins job

Basically I create a wrapper function as below in Groovy class PhoenixEurekaService:

enter image description here

The steps is actually the jenkins job environment passed into Groovy class via constructor. By this way we can call any steps available in jenkins job in Groovy class.

enter image description here

In global groovy script PhoenixLib.groovy

enter image description here

I am not sure is there other way to do that...

Upvotes: 8

Related Questions