【问题标题】:How to show timestamps in short format in Jenkins Blue Ocean?如何在 Jenkins Blue Ocean 中以短格式显示时间戳?
【发布时间】:2020-04-01 13:51:17
【问题描述】:

使用Timestamper plugin 1.11.2 和全局启用的时间戳,使用默认格式,我得到以下控制台输出:

00:00:41.097  Some Message

在 Blue Ocean 中,输出显示如下:

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

如何使 Blue Ocean 使用短时间戳格式?长格式有点不可读,并且使步骤的详细信息视图混乱。

我也看过Pipeline Options,但只有timestamps 选项没有指定格式的参数。

注意:This question 不是骗子,因为它只要求时区差异。

【问题讨论】:

    标签: jenkins jenkins-pipeline jenkins-plugins jenkins-blueocean


    【解决方案1】:

    编辑:

    ⚠️ 不幸的是,这种解决方法在 node 的上下文中不起作用,请参阅 JENKINS-59575。看起来我必须最终弄脏插件开发,才能以受支持的方式做类似的事情。

    无论如何,我不会删除这个答案,因为代码在其他场景中可能仍然有用。


    原答案:

    作为一种解决方法,我创建了一个自定义ConsoleLogFilter。它可以作为管道选项、阶段选项或步骤级别应用。如果您安装了时间戳插件,则应禁用全局时间戳选项以防止重复时间戳。

    通常您会在共享库中定义低级代码。这是一个可以直接复制粘贴到管道脚本编辑器中的示例(您可能必须禁用 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”的示例输出:

    致谢:

    我的想法来自this answer

    【讨论】:

      猜你喜欢
      • 2019-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-21
      • 2019-02-27
      • 1970-01-01
      • 2022-12-27
      相关资源
      最近更新 更多