我有这个詹金斯管道脚本(您应该可以将其直接粘贴到空白管道版本中)
import hudson.console.LineTransformationOutputStream
import hudson.console.ConsoleLogFilter
import java.nio.charset.Charset
import java.nio.charset.StandardCharsets
class MyConsoleLogFilter extends ConsoleLogFilter {
OutputStream decorateLogger(AbstractBuild build, OutputStream logger)
throws IOException, InterruptedException {
return new MyOutputStream(logger, StandardCharsets.UTF_8)
}
}
class MyOutputStream extends LineTransformationOutputStream {
def logger
def charset
MyOutputStream(OutputStream logger, Charset charset) {
this.logger = logger
this.charset = charset
}
void close() throws IOException {
super.close();
logger.close();
}
void eol(byte[] bytes, int len) throws IOException {
String line = charset.decode(ByteBuffer.wrap(bytes, 0, len)).toString();
logger.write("xxx ".getBytes(charset))
logger.write(line.getBytes(charset));
}
}
node {
withContext(new MyConsoleLogFilter()) {
echo 'Hello World'
}
echo 'Hello World'
}
由于Hello World
的换行,我希望看到第一个xxx
前缀为MyConsoleLogFilter
。
但是我所看到的只是控制台输出为灰色,如下所示:
Started by user Admin
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/mike-learning
[Pipeline] {
[Pipeline] withContext
[Pipeline] {
[Pipeline] echo
[Pipeline] }
[Pipeline] // withContext
[Pipeline] echo
Hello World
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
为什么withContext()
块中的控制台输出被隐藏?
答案 0 :(得分:1)
一个同事(Hibri Marzook)为我解决了这个问题。他将我指向https://issues.jenkins-ci.org/browse/JENKINS-53151,这促使我这样做:
import hudson.console.LineTransformationOutputStream
import hudson.console.ConsoleLogFilter
import java.nio.charset.Charset
import java.nio.charset.StandardCharsets
class MyConsoleLogFilter extends ConsoleLogFilter {
@NonCPS
OutputStream decorateLogger(AbstractBuild build, OutputStream logger)
throws IOException, InterruptedException {
return new MyOutputStream(logger, StandardCharsets.UTF_8)
}
}
class MyOutputStream extends LineTransformationOutputStream {
def logger
def charset
MyOutputStream(OutputStream logger, Charset charset) {
this.logger = logger
this.charset = charset
}
@NonCPS
void close() throws IOException {
super.close();
logger.close();
}
@NonCPS
void eol(byte[] bytes, int len) throws IOException {
def line = charset.decode(java.nio.ByteBuffer.wrap(bytes, 0, len)).toString();
logger.write("xxx ".getBytes(charset))
logger.write(line.getBytes(charset));
}
}
node {
withContext(new MyConsoleLogFilter()) {
echo 'Hello World'
}
echo 'Hello World'
}
现在可以使用了。
答案 1 :(得分:1)
另一种方法是使用Java插件来实现,您不需要NonCPS注释,而是实现Serializable接口:
@Extension
public class MyConsoleLogFilter extends ConsoleLogFilter implements Serializable {
private static final long serialVersionUID = 1;
@Override
public OutputStream decorateLogger(Run build, final OutputStream logger) {
return new MyOutputStream(logger, StandardCharsets.UTF_8);
}
private class MyOutputStream extends LineTransformationOutputStream {
private OutputStream logger;
private Charset charset;
MyOutputStream(OutputStream logger, Charset charset) {
this.logger = logger;
this.charset = charset;
}
public void close() throws IOException {
super.close();
logger.close();
}
public void eol(byte[] bytes, int len) throws IOException {
String line = charset.decode(java.nio.ByteBuffer.wrap(bytes, 0, len)).toString();
logger.write("xxx ".getBytes(charset));
logger.write(line.getBytes(charset));
}
}
}