Как показать метки времени в коротком формате в Jenkins Blue Ocean? - PullRequest
0 голосов
/ 01 апреля 2020

Используя Плагин Timestamper 1.11.2 с глобально включенными метками времени, используя формат по умолчанию, я получаю следующий вывод консоли:

00:00:41.097  Some Message

В Blue Ocean вывод выглядит как:

[2020-04-01T00:00:41.097Z] Some Message

Как сделать так, чтобы Blue Ocean использовал формат короткой метки времени? Длинный формат несколько не читается и загромождает подробное представление шагов.

Я также рассмотрел Параметры конвейера , но есть только опция timestamps, которая не есть параметр для указания формата.

Примечание: Этот вопрос не является обманом, поскольку он запрашивает различия только в часовом поясе.

1 Ответ

0 голосов
/ 01 апреля 2020

Редактировать:

⚠️ К сожалению, этот обходной путь не работает в контексте node, см. JENKINS-59575 . Похоже, мне нужно, наконец, испачкать руки при разработке плагинов, чтобы делать подобные вещи поддерживаемым способом.

В любом случае, я не буду удалять этот ответ, так как код все еще может быть полезен в других сценариях ios.


Оригинальный ответ:

В качестве обходного пути я создал пользовательский ConsoleLogFilter. Это может быть применено как опция конвейера, опция стадии или на уровне шагов. Если у вас установлен плагин timestamp, вы должны отключить глобальную опцию timestamp, чтобы предотвратить дублирование меток времени.

Обычно вы определяете низкоуровневый код в общей библиотеке. Вот пример, который можно скопировать прямо в редактор сценариев конвейера (возможно, вам придется отключить Groovy песочница):

import hudson.console.LineTransformationOutputStream
import hudson.console.ConsoleLogFilter
import java.nio.charset.Charset
import java.nio.charset.StandardCharsets

pipeline{
    agent any
    /*
    options{
        // Enable timestamps for the whole pipeline, using default format
        //withContext( myTimestamps() )

        // Enable timestamps for the whole pipeline, using custom format
        //withContext( myTimestamps( dateFormat: 'HH:mm:ss', prefix: '', suffix: ' - ' ) )
    }
    */

    stages {
        stage('A') {
            options {
                // Enable timestamps for this stage only
                withContext( myTimestamps() )
            }
            steps {
                echo 'Hello World'
            }
        }
        stage('B') {
            steps {
                echo 'Hello World'

                // Enable timestamps for some steps only
                withMyTimestamps( dateFormat: 'HH:mm:ss') {
                    echo 'Hello World'
                }
            }
        }
    }
}

//----- Code below should be moved into a shared library -----

// For use as option at pipeline or stage level, e. g.: withContext( myTimestamps() )    
def myTimestamps( Map args = [:] ) {
    return new MyTimestampedLogFilter( args )
}

// For use as block wrapper at steps level 
void withMyTimestamps( Map args = [:], Closure block ) {
    withContext( new MyTimestampedLogFilter( args ), block )
}

class MyTimestampedLogFilter extends ConsoleLogFilter {
    String dateFormat
    String prefix
    String suffix

    MyTimestampedLogFilter( Map args = [:] ) {
        this.dateFormat = args.dateFormat ?: 'YY-MM-dd HH:mm:ss'
        this.prefix     = args.prefix ?: '['
        this.suffix     = args.suffix ?: '] '
    }

    @NonCPS
    OutputStream decorateLogger( AbstractBuild build, OutputStream logger )
            throws IOException, InterruptedException {

        return new MyTimestampedOutputStream( logger, StandardCharsets.UTF_8, this.dateFormat, this.prefix, this.suffix )
    }
}

class MyTimestampedOutputStream extends LineTransformationOutputStream {
    OutputStream logger
    Charset charset
    String dateFormat
    String prefix
    String suffix

    MyTimestampedOutputStream( OutputStream logger, Charset charset, String dateFormat, String prefix, String suffix ) {
        this.logger = logger
        this.charset = charset
        this.dateFormat = dateFormat
        this.prefix = prefix
        this.suffix = suffix
    }

    @NonCPS
    void close() throws IOException {
        super.close();
        logger.close();
    }

    @NonCPS
    void eol( byte[] bytes, int len ) throws IOException {
        def lineIn = charset.decode( java.nio.ByteBuffer.wrap( bytes, 0, len ) ).toString()
        def dateFormatted = new Date().format( this.dateFormat )
        def lineOut = "${this.prefix}${dateFormatted}${this.suffix}${lineIn}\n" 
        logger.write( lineOut.getBytes( charset ) )
    }
}

Пример вывода для этапа "B":

Blue Ocean Output

Кредиты:

Я получил идею от этого ответа .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...