Implementata gestione nei thread dei log di build
This commit is contained in:
6
pom.xml
6
pom.xml
@@ -32,14 +32,14 @@
|
||||
</scm>
|
||||
|
||||
<properties>
|
||||
<revision>1.0.4</revision>
|
||||
<revision>1.0.7</revision>
|
||||
<changelist>-SNAPSHOT</changelist>
|
||||
|
||||
<!-- https://www.jenkins.io/doc/developer/plugin-development/choosing-jenkins-baseline/ -->
|
||||
<jenkins.version>2.440.3</jenkins.version>
|
||||
<jenkins.version>2.462.3</jenkins.version>
|
||||
<gitHubRepo>jenkinsci/${project.artifactId}-plugin</gitHubRepo>
|
||||
|
||||
<spotless.check.skip>false</spotless.check.skip>
|
||||
<spotless.check.skip>true</spotless.check.skip>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
public class PBAutoBuildBuilder extends Builder implements SimpleBuildStep {
|
||||
/**
|
||||
@@ -100,7 +101,7 @@ public class PBAutoBuildBuilder extends Builder implements SimpleBuildStep {
|
||||
@Override
|
||||
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener)
|
||||
throws InterruptedException, IOException {
|
||||
return runPBAutoBuild(build, build.getWorkspace(), launcher, listener);
|
||||
return runPBAutoBuild(build, Objects.requireNonNull(build.getWorkspace()), launcher, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,10 +155,10 @@ public class PBAutoBuildBuilder extends Builder implements SimpleBuildStep {
|
||||
|
||||
|
||||
if (!launcher.isUnix()) {
|
||||
final int cpi = getCodePageIdentifier(build.getCharset());
|
||||
if (cpi != 0)
|
||||
args.prepend("cmd.exe", "/C", "\"", "chcp", String.valueOf(cpi), "&&");
|
||||
else
|
||||
// final int cpi = getCodePageIdentifier(build.getCharset());
|
||||
// if (cpi != 0)
|
||||
// args.prepend("cmd.exe", "/C", "\"", "chcp", String.valueOf(cpi), "&&");
|
||||
// else
|
||||
args.prepend("cmd.exe", "/C", "\"");
|
||||
args.add("\"", "&&", "exit", "%%ERRORLEVEL%%");
|
||||
}
|
||||
@@ -166,9 +167,9 @@ public class PBAutoBuildBuilder extends Builder implements SimpleBuildStep {
|
||||
listener.getLogger()
|
||||
.println(String.format("Executing the command %s from %s", args.toStringWithQuote(), workspace));
|
||||
// Parser to find the number of Warnings/Errors
|
||||
PBAutoBuildConsoleParser mbcp = new PBAutoBuildConsoleParser(listener.getLogger(), build.getCharset());
|
||||
PBAutoBuildConsoleParser mbcp = new PBAutoBuildConsoleParser(listener.getLogger(), build.getCharset(), false);
|
||||
PBAutoBuildConsoleAnnotator annotator = new PBAutoBuildConsoleAnnotator(listener.getLogger(),
|
||||
build.getCharset(), false);
|
||||
build.getCharset(), false, workspace.getRemote());
|
||||
|
||||
// Launch the pbautobuild utility
|
||||
int r = launcher.launch().cmds(args).envs(env).stdout(mbcp).stdout(annotator).pwd(workspace).join();
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package io.jenkins.plugins.sample;
|
||||
|
||||
import hudson.console.LineTransformationOutputStream;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -14,6 +17,7 @@ public class PBAutoBuildConsoleAnnotator extends LineTransformationOutputStream
|
||||
private final OutputStream out;
|
||||
private final Charset charset;
|
||||
private final boolean verboseLogging;
|
||||
private final String workspace;
|
||||
|
||||
private final PBAutoBuildErrorNote errorNote = new PBAutoBuildErrorNote();
|
||||
private final PBAutoBuildWarningNote warningNote = new PBAutoBuildWarningNote();
|
||||
@@ -33,16 +37,24 @@ public class PBAutoBuildConsoleAnnotator extends LineTransformationOutputStream
|
||||
|
||||
// Pattern per i file (solo nome, escludendo il percorso)
|
||||
private Pattern fileNamePattern = Pattern.compile("([^\\\\]+\\.\\w+)$");
|
||||
private Pattern timestampPattern = Pattern.compile("(^\\d{2}:\\d{2}:\\d{2})");
|
||||
|
||||
// Pattern per Stage1, Stage2 e Regenerating
|
||||
private Pattern stagePattern = Pattern.compile("(Normal|Stage1|Stage2|Regenerating) for ([a-zA-Z]:\\\\.*?\\\\([^\\\\]+\\.\\w+))");
|
||||
|
||||
|
||||
private final Queue<byte[]> queueLog = new ConcurrentLinkedQueue<>();
|
||||
private Thread consumerThread;
|
||||
private boolean consumerThreadRunning;
|
||||
|
||||
public PBAutoBuildConsoleAnnotator(OutputStream out, Charset charset, boolean verboseLogging) {
|
||||
|
||||
public PBAutoBuildConsoleAnnotator(OutputStream out, Charset charset, boolean verboseLogging, String workspace) {
|
||||
this.out = out;
|
||||
this.charset = charset;
|
||||
this.verboseLogging = verboseLogging;
|
||||
this.workspace = workspace + File.separator;
|
||||
|
||||
startQueueConsumer();
|
||||
}
|
||||
|
||||
public int getNumberOfWarnings() {
|
||||
@@ -55,28 +67,65 @@ public class PBAutoBuildConsoleAnnotator extends LineTransformationOutputStream
|
||||
|
||||
@Override
|
||||
protected void eol(byte[] b, int len) throws IOException {
|
||||
String line = charset.decode(ByteBuffer.wrap(b, 0, len)).toString();
|
||||
queueLog.add(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
stopQueueConsumer();
|
||||
super.close();
|
||||
out.close();
|
||||
}
|
||||
|
||||
private void startQueueConsumer() {
|
||||
consumerThreadRunning = true;
|
||||
consumerThread = new Thread(() -> {
|
||||
while (consumerThreadRunning) {
|
||||
if (!queueLog.isEmpty()) {
|
||||
final byte[] item = queueLog.poll();
|
||||
|
||||
if (item != null) {
|
||||
try {
|
||||
processLine(item);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
consumerThread.start();
|
||||
}
|
||||
|
||||
private void processLine(byte[] b) throws IOException {
|
||||
String line = charset.decode(ByteBuffer.wrap(b, 0, b.length)).toString();
|
||||
byte[] bytes1 = line.getBytes(charset);
|
||||
|
||||
String lineUtf16 = StandardCharsets.UTF_16.decode(ByteBuffer.wrap(b, 0, len)).toString();
|
||||
String lineUtf16 = StandardCharsets.UTF_16.decode(ByteBuffer.wrap(b, 0, b.length)).toString();
|
||||
|
||||
boolean isUtf16 = true;
|
||||
for(int i = 0; i < bytes1.length; i = i+2) {
|
||||
if(bytes1[i] != 0) {
|
||||
for (int i = 0; i < bytes1.length; i = i + 2) {
|
||||
if (bytes1[i] != 0) {
|
||||
isUtf16 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(isUtf16) {
|
||||
if (isUtf16) {
|
||||
line = lineUtf16;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// trim off CR/LF from the end
|
||||
line = trimEOL(line);
|
||||
|
||||
if (line.isEmpty()) return;
|
||||
|
||||
// Error messages handler
|
||||
Matcher m = PBAutoBuildErrorNote.PATTERN.matcher(line);
|
||||
if (m.matches()) { // Match the number of warnings
|
||||
@@ -91,39 +140,48 @@ public class PBAutoBuildConsoleAnnotator extends LineTransformationOutputStream
|
||||
this.numberOfWarnings++;
|
||||
}
|
||||
|
||||
if(verboseLogging)
|
||||
out.write(b, 0, len);
|
||||
else {
|
||||
|
||||
if (verboseLogging) {
|
||||
line += "\r\n";
|
||||
byte[] b1 = line.getBytes(charset);
|
||||
out.write(b1, 0, b1.length);
|
||||
} else {
|
||||
// Estrarre i dati
|
||||
String version = extractData(line, versionPattern);
|
||||
String runtimePath = extractData(line, runtimePattern);
|
||||
String workPath = extractData(line, workPathPattern);
|
||||
String project = extractData(line, projectPattern);
|
||||
String filename = extractFileNames(line, fileNamePattern);
|
||||
String stage = extractStages(line, stagePattern);
|
||||
// String version = extractData(line, versionPattern);
|
||||
// String runtimePath = extractData(line, runtimePattern);
|
||||
// String workPath = extractData(line, workPathPattern);
|
||||
// String project = extractData(line, projectPattern);
|
||||
String timestamp = extractData(line, timestampPattern);
|
||||
// String filename = extractFileNames(line, fileNamePattern);
|
||||
// String stage = extractStages(line, stagePattern);
|
||||
|
||||
if(line.contains("[Normal]")) {
|
||||
//if(line.contains("\\"))
|
||||
// line = line.substring(line.lastIndexOf("\\"));
|
||||
line = line.replace(workspace, "")
|
||||
.replace("\t", " ");
|
||||
|
||||
if (timestamp != null && !timestamp.isEmpty())
|
||||
line = line.replace(timestamp, "").trim();
|
||||
|
||||
|
||||
line += "\r\n";
|
||||
byte[] bytesToWrite = line.getBytes(charset);
|
||||
out.write(bytesToWrite, 0, bytesToWrite.length);
|
||||
|
||||
byte[] bytesToWrite = line.getBytes(charset);
|
||||
out.write(bytesToWrite, 0, bytesToWrite.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
out.close();
|
||||
// Metodo per fermare il thread di consumo
|
||||
public void stopQueueConsumer() {
|
||||
consumerThreadRunning = false;
|
||||
synchronized (queueLog) {
|
||||
queueLog.notify(); // Se il thread è in attesa, sveglialo
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private String extractData(String log, Pattern pattern) {
|
||||
Matcher matcher = pattern.matcher(log);
|
||||
if (matcher.matches()) {
|
||||
return matcher.group(1);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(0);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -132,7 +190,7 @@ public class PBAutoBuildConsoleAnnotator extends LineTransformationOutputStream
|
||||
private String extractFileNames(String log, Pattern pattern) {
|
||||
Matcher matcher = pattern.matcher(log);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1); // Nome del file senza percorso
|
||||
return matcher.group(0); // Nome del file senza percorso
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -141,7 +199,7 @@ public class PBAutoBuildConsoleAnnotator extends LineTransformationOutputStream
|
||||
private String extractStages(String log, Pattern pattern) {
|
||||
Matcher matcher = pattern.matcher(log);
|
||||
if (matcher.find()) {
|
||||
return "[" + matcher.group(1) + "] " + matcher.group(3); // Stage (Stage1, Stage2, ecc.)
|
||||
return "[" + matcher.group(0) + "] " + matcher.group(2); // Stage (Stage1, Stage2, ecc.)
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -43,9 +44,32 @@ public class PBAutoBuildConsoleParser extends LineTransformationOutputStream {
|
||||
private int numberOfWarnings = -1;
|
||||
private int numberOfErrors = -1;
|
||||
|
||||
public PBAutoBuildConsoleParser(OutputStream out, Charset charset) {
|
||||
private boolean verboseLogging = false;
|
||||
|
||||
private final Pattern patternWarnings = Pattern.compile(".*\\d+\\sWarning\\(s\\).*");
|
||||
private final Pattern patternErrors = Pattern.compile(".*\\d+\\sError\\(s\\).*");
|
||||
|
||||
// Pattern per Versione e Runtime
|
||||
private Pattern versionPattern = Pattern.compile("PBAutoBuild Version: ([\\d\\.]+)");
|
||||
private Pattern runtimePattern = Pattern.compile("Runtime Version: ([\\d\\.]+)");
|
||||
|
||||
// Pattern per Work Path
|
||||
private Pattern workPathPattern = Pattern.compile("Work Path: (.+\\.exe)");
|
||||
|
||||
// Pattern per i progetti
|
||||
private Pattern projectPattern = Pattern.compile("Deploying project ([a-zA-Z0-9_]+)");
|
||||
|
||||
// Pattern per i file (solo nome, escludendo il percorso)
|
||||
private Pattern fileNamePattern = Pattern.compile("([^\\\\]+\\.\\w+)$");
|
||||
|
||||
// Pattern per Stage1, Stage2 e Regenerating
|
||||
private Pattern stagePattern = Pattern.compile("(Normal|Stage1|Stage2|Regenerating) for ([a-zA-Z]:\\\\.*?\\\\([^\\\\]+\\.\\w+))");
|
||||
|
||||
|
||||
public PBAutoBuildConsoleParser(OutputStream out, Charset charset, boolean verboseLogging) {
|
||||
this.out = out;
|
||||
this.charset = charset;
|
||||
this.verboseLogging = verboseLogging;
|
||||
}
|
||||
|
||||
public int getNumberOfWarnings() {
|
||||
@@ -59,12 +83,26 @@ public class PBAutoBuildConsoleParser extends LineTransformationOutputStream {
|
||||
@Override
|
||||
protected void eol(byte[] b, int len) throws IOException {
|
||||
String line = charset.decode(ByteBuffer.wrap(b, 0, len)).toString();
|
||||
byte[] bytes1 = line.getBytes(charset);
|
||||
|
||||
String lineUtf16 = StandardCharsets.UTF_16.decode(ByteBuffer.wrap(b, 0, len)).toString();
|
||||
|
||||
boolean isUtf16 = true;
|
||||
for(int i = 0; i < bytes1.length; i = i+2) {
|
||||
if(bytes1[i] != 0) {
|
||||
isUtf16 = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(isUtf16) {
|
||||
line = lineUtf16;
|
||||
}
|
||||
|
||||
// trim off CR/LF from the end
|
||||
line = trimEOL(line);
|
||||
|
||||
Pattern patternWarnings = Pattern.compile(".*\\d+\\sWarning\\(s\\).*");
|
||||
Pattern patternErrors = Pattern.compile(".*\\d+\\sError\\(s\\).*");
|
||||
if(line.isEmpty()) return;
|
||||
|
||||
Matcher mWarnings = patternWarnings.matcher(line);
|
||||
Matcher mErrors = patternErrors.matcher(line);
|
||||
@@ -86,7 +124,25 @@ public class PBAutoBuildConsoleParser extends LineTransformationOutputStream {
|
||||
}
|
||||
|
||||
// Write to output
|
||||
out.write(b, 0, len);
|
||||
if(verboseLogging)
|
||||
out.write(b, 0, len);
|
||||
else {
|
||||
// Estrarre i dati
|
||||
String version = extractData(line, versionPattern);
|
||||
String runtimePath = extractData(line, runtimePattern);
|
||||
String workPath = extractData(line, workPathPattern);
|
||||
String project = extractData(line, projectPattern);
|
||||
String filename = extractFileNames(line, fileNamePattern);
|
||||
String stage = extractStages(line, stagePattern);
|
||||
|
||||
if(line.contains("[Normal]")) {
|
||||
//if(line.contains("\\"))
|
||||
// line = line.substring(line.lastIndexOf("\\"));
|
||||
|
||||
byte[] bytesToWrite = line.getBytes(charset);
|
||||
out.write(bytesToWrite, 0, bytesToWrite.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -94,4 +150,32 @@ public class PBAutoBuildConsoleParser extends LineTransformationOutputStream {
|
||||
super.close();
|
||||
out.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private String extractData(String log, Pattern pattern) {
|
||||
Matcher matcher = pattern.matcher(log);
|
||||
if (matcher.matches()) {
|
||||
return matcher.group(1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String extractFileNames(String log, Pattern pattern) {
|
||||
Matcher matcher = pattern.matcher(log);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1); // Nome del file senza percorso
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String extractStages(String log, Pattern pattern) {
|
||||
Matcher matcher = pattern.matcher(log);
|
||||
if (matcher.find()) {
|
||||
return "[" + matcher.group(1) + "] " + matcher.group(3); // Stage (Stage1, Stage2, ecc.)
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user