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