rss

How to Jenkins : chain jobs with parameters

This post describes How To chain jobs with parameter(s).
- Choose optionA if you're using pipeline plugin.
- OptionB is a little bit deprecated, but usefull if you would like to script your build execution or trigger it remotely.

(option A) Define a post action in first job

First recommended and simple way if your are using "Build Pipeline". Go to the first job configuration to append a post-action :

(option B) Chain it using shell scripts


NB: this option will make loosing your pipeline chain.
I recommend to use 2 small dedicated temp jobs to test it first. That would avoid to run unnecessarely long build...

Steps :
  • Install Build Token Root Plugin
  • Define first job with parameter
  • Define second job ("follower") with parameter
  • Define a trigger for the follower
  • Append a shell script to chain the two jobs
  • Try!

Install Build Token Root Plugin

Ask to your Jenkins administrator to install this plugin : Build Token Root Plugin
Wait that Jenkins reboot (required).

Define first job with parameter

Add "branch" parameter to your first job.

Add a shell script to echo the variable.

Define follower job with parameter

Add "branch" parameter to your second job (same as previously).
Add a shell script to echo the variable(same as previously).

Define a trigger for the follower

Add a trigger for the second job. Set a secret token here.

Append a shell script to chain the two jobs

Open the first job configuration to add the following shell script.
You will need to adapt the jenkins host value corresponding to your environment.

# show job parameter
echo branch=${branch}

#  resources
#  https://wiki.jenkins-ci.org/display/JENKINS/Parameterized+Build
#  https://wiki.jenkins-ci.org/display/JENKINS/Build+Token+Root+Plugin
#  http://curiositedevie.blogspot.nl/2016/02/how-to-jenkins-chain-jobs-with.html
export JENKINS_HOST=https://myjenkins.domain.net
export JOB_TOKEN=THISISWONDERFULL
export JOB_NAME=git_config_follower
export JOB_PARAM1=branch=${branch}
export JOB_CAUSE=Launching_follower_with_branch_set_to_${branch}
export JOB_PING="$JENKINS_HOST/buildByToken/buildWithParameters?job=$JOB_NAME&token=$JOB_TOKEN&$JOB_PARAM1&cause=$JOB_CAUSE"
echo $JOB_PING
curl --verbose --insecure $JOB_PING

Try!

Launch the first job with a parameter.

Go to the Job console to check curl http status.
Go to the follower (second) job logs.
Check the follower result!

Log4j 1.x with maven: minimal howto

This post is a minimal howto for log4j version 1.

What a simple task ! but who never search a simple sample on the web send a little stone to me ;)
Feel free to copy paste anyway ;))

What are the dependencies

You will need to add log4j, slf4j and lombok (to use @Slf4j) :

 <properties>
  <!--General project configuration -->
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

  <lombok.version>1.16.6</lombok.version>
  <log4j.version>1.2.17</log4j.version>
  <slf4j.version>1.7.10</slf4j.version>
  <junit.version>4.12</junit.version>
 </properties>
 <dependencyManagement>
  <dependencies>
   <!-- @Slf4j annotation -->
   <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${lombok.version}</version>
    <scope>provided</scope>
   </dependency>
   <!-- ## LOGS ## -->
   <dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>${log4j.version}</version>
   </dependency>
   <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${slf4j.version}</version>
   </dependency>
   <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>${slf4j.version}</version>
   </dependency>

How to use it

Simply add "@Slf4j" to your class, and then you could use "log" as logger.

import java.security.InvalidParameterException;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MyClass {
    public MyClass() {
        log.debug("constructor YEP");
    }
    
    public void doIt(long value) {
        log.info("doIt {}", value);
        try {
            throw new InvalidParameterException("Zobby");
        } catch (Exception ee) {
            log.error("I'm so stupid: {} => {}", ee.getClass().getSimpleName(), ee.getMessage(), ee);
            log.warn("same without stack trace !: {} => {}", ee.getClass().getSimpleName(), ee.getMessage());
        }
    }
}

How to configure appenders

To configure log4j, add a log4j.properties file to your resources. Start by defining a console appender. This appender should appear in the rootLogger definition too. You could define the following content to start:

log4j.rootLogger=DEBUG, console

## Console appender 
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.threshold=DEBUG
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d %5p [%c{1}] %m%n

# package log levels
#
# Log4j bootstrap
#
log4j.logger.org.apache.http = INFO
log4j.logger.com.myapp = DEBUG
#

How to configure file appender

Update your rootLoger to refer to the logfile appender, and add a logfile appender definition:

log4j.rootLogger=DEBUG, console, logfile

## File appender
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.threshold=DEBUG
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{ISO8601} - %-5.5p - %t - %c - %m%n
log4j.appender.logfile.file=MY_CUSTOMFILEHERE.log
log4j.appender.logfile.maxBackupIndex=5
log4j.appender.logfile.maxFileSize=2048KB
log4j.appender.logfile.append=true

How to configure graylog (splunk-like) appender

Update your rootLoger to refer to the graylog appender, and add a gelf appender definition:

### Graylog appender
log4j.appender.graylog2=org.graylog2.log.GelfAppender
log4j.appender.graylog2.graylogHost=tcp:mygraylogserver.net
log4j.appender.graylog2.graylogPort = 12201
#log4j.appender.graylog2.originHost=(default to the local hostname)
log4j.appender.graylog2.facility=gelf-java
log4j.appender.graylog2.layout=org.apache.log4j.PatternLayout
log4j.appender.graylog2.extractStacktrace=true
log4j.appender.graylog2.addExtendedInformation=true
log4j.appender.graylog2.additionalFields={'environment': '${projectEnvironment}', 'application': 'MyPoc','version': '${buildVersion}_${buildTimestamp}'}

How to configure NT event appender

Pre-requisites : add NTEventLogAppender.dll and NTEventLogAppender.amd64.dll to the current directory or to the java ld library path. You could append "-Djava.library.path=PATH" to your application if needed. Get this dll files from log4j zip distribution  doc : https://wiki.apache.org/logging-log4j/NTEventLogAppender

Update your rootLoger to refer to the ntappender appender, and add a new ntappender definition:

# NTEventLogAppender
log4j.appender.ntappender=org.apache.log4j.nt.NTEventLogAppender
log4j.appender.ntappender.Source=MyKillerApp
log4j.appender.ntappender.layout=org.apache.log4j.PatternLayout
log4j.appender.ntappender.layout.ConversionPattern=%d{ISO8601} - %-5.5p - %t - %c - %m%n

For this last usecase you will be able to see the app logs into Windows Event Log service :

Swagger UI + Auth0 Bearer

When you would like to integrate Swagger UI with a token based authentication (like Auth0), this is the way you need to update Swagger index.html :


      function addApiKeyAuthorization(){
        var key = encodeURIComponent($('#input_apiKey')[0].value);
        if(key && key.trim() != "") {
            var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("Authorization", "Bearer " + key, "header");
            window.swaggerUi.api.clientAuthorizations.add("key", apiKeyAuth);
            log("added key " + key);
        }
      }

Instead of adding api_key as part of the query, this code is adding your token in an "Authorization" header and with "Bearer " as prefix.

enjoy