|
12 | 12 | import org.nasdanika.cli.ShellCommand; |
13 | 13 | import org.nasdanika.cli.SubCommandRequirement; |
14 | 14 | import org.nasdanika.common.Closeable; |
15 | | -import org.nasdanika.common.NullProgressMonitor; |
| 15 | +import org.nasdanika.common.LoggerProgressMonitor; |
16 | 16 | import org.nasdanika.common.ProgressMonitor; |
| 17 | +import org.nasdanika.telemetry.GlobalOpenTelemetryCapabilityFactory; |
| 18 | +import org.nasdanika.telemetry.TelemetryUtil; |
| 19 | +import org.slf4j.Logger; |
| 20 | +import org.slf4j.LoggerFactory; |
17 | 21 |
|
| 22 | +import io.opentelemetry.api.OpenTelemetry; |
| 23 | +import io.opentelemetry.api.common.Attributes; |
| 24 | +import io.opentelemetry.api.trace.Span; |
| 25 | +import io.opentelemetry.api.trace.SpanBuilder; |
| 26 | +import io.opentelemetry.api.trace.StatusCode; |
| 27 | +import io.opentelemetry.api.trace.Tracer; |
| 28 | +import io.opentelemetry.context.Scope; |
18 | 29 | import picocli.CommandLine; |
19 | 30 |
|
20 | 31 | public class Launcher { |
21 | | - |
22 | | - public static void main(String[] args) { |
23 | | - CapabilityLoader capabilityLoader = new CapabilityLoader(Launcher.class.getModule().getLayer()); |
24 | | -// ProgressMonitor progressMonitor = new PrintStreamProgressMonitor(true); |
25 | | - ProgressMonitor progressMonitor = new NullProgressMonitor(); // TODO configurable through system properties |
26 | 32 |
|
27 | | - // Sub-commands, sorting alphabetically |
28 | | - List<CommandLine> rootCommands = new ArrayList<>(); |
29 | | - Requirement<SubCommandRequirement, CommandLine> subCommandRequirement = ServiceCapabilityFactory.createRequirement(CommandLine.class, null, new SubCommandRequirement(Collections.emptyList())); |
30 | | - for (CapabilityProvider<Object> cp: capabilityLoader.load(subCommandRequirement, progressMonitor)) { |
31 | | - cp.getPublisher().filter(Objects::nonNull).collectList().block().forEach(cmd -> rootCommands.add((CommandLine) cmd)); |
| 33 | + private static final Logger LOGGER = LoggerFactory.getLogger(Launcher.class); |
| 34 | + |
| 35 | + private static String getVersion() { |
| 36 | + Module module = Launcher.class.getModule(); |
| 37 | + if (module == null) { |
| 38 | + return "(unknown)"; |
32 | 39 | } |
33 | 40 |
|
34 | | - // Executing the first one |
35 | | - for (CommandLine rootCommand: rootCommands) { |
36 | | - rootCommand.addSubcommand(new ShellCommand(rootCommand)); |
37 | | - int exitCode; |
38 | | - try { |
39 | | - exitCode = rootCommand.execute(args); |
40 | | - } finally { |
41 | | - if (rootCommand instanceof Closeable) { |
42 | | - ((Closeable) rootCommand).close(progressMonitor.split("Closing root command", 1)); |
| 41 | + return module.getDescriptor().toNameAndVersion(); |
| 42 | + } |
| 43 | + |
| 44 | + public static void main(String[] args) { |
| 45 | + OpenTelemetry openTelemetry = GlobalOpenTelemetryCapabilityFactory.getGlobalOpenTelemetry(); |
| 46 | + Tracer tracer = openTelemetry.getTracer(Launcher.class.getName(), getVersion()); |
| 47 | + Attributes attributes = Attributes |
| 48 | + .builder() |
| 49 | + .put("arguments", args) |
| 50 | + .build(); |
| 51 | + SpanBuilder spanBuilder = tracer.spanBuilder("Launcher").setAllAttributes(attributes); |
| 52 | + Span launcherSpan = TelemetryUtil.buildSpan(spanBuilder).startSpan(); |
| 53 | + Integer exitCode = null; |
| 54 | + try (Scope scope = launcherSpan.makeCurrent()) { |
| 55 | + try (ProgressMonitor progressMonitor = new LoggerProgressMonitor(LOGGER)) { //TracerProgressMonitor(tracer, "Launcher"); |
| 56 | + CapabilityLoader capabilityLoader = new CapabilityLoader(Launcher.class.getModule().getLayer()); |
| 57 | + |
| 58 | + // Sub-commands, sorting alphabetically |
| 59 | + List<CommandLine> rootCommands = new ArrayList<>(); |
| 60 | + Requirement<SubCommandRequirement, CommandLine> subCommandRequirement = ServiceCapabilityFactory.createRequirement(CommandLine.class, null, new SubCommandRequirement(Collections.emptyList())); |
| 61 | + for (CapabilityProvider<Object> cp: capabilityLoader.load(subCommandRequirement, progressMonitor)) { |
| 62 | + cp.getPublisher().filter(Objects::nonNull).collectList().block().forEach(cmd -> rootCommands.add((CommandLine) cmd)); |
| 63 | + } |
| 64 | + |
| 65 | + // Executing the first one |
| 66 | + for (CommandLine rootCommand: rootCommands) { |
| 67 | + rootCommand.addSubcommand(new ShellCommand(rootCommand)); |
| 68 | + try { |
| 69 | + exitCode = rootCommand.execute(args); |
| 70 | + launcherSpan.setAttribute("exit-code", exitCode); |
| 71 | + } finally { |
| 72 | + if (rootCommand instanceof Closeable) { |
| 73 | + ((Closeable) rootCommand).close(progressMonitor.split("Closing root command", 1)); |
| 74 | + } |
| 75 | + capabilityLoader.close(progressMonitor.split("Closing capability loader", 1)); |
| 76 | + } |
| 77 | + } |
| 78 | + |
| 79 | + if (exitCode == null) { |
| 80 | + throw new UnsupportedOperationException("There are no root commands"); |
43 | 81 | } |
44 | | - capabilityLoader.close(progressMonitor.split("Closing capability loader", 1)); |
45 | 82 | } |
46 | | - System.exit(exitCode); |
| 83 | + } catch (Exception e) { |
| 84 | + launcherSpan.recordException(e); |
| 85 | + launcherSpan.setStatus(StatusCode.ERROR); |
| 86 | + throw e; |
| 87 | + } finally { |
| 88 | + launcherSpan.end(); |
47 | 89 | } |
48 | | - |
49 | | - throw new UnsupportedOperationException("There are no root commands"); |
50 | | - } |
| 90 | + System.exit(exitCode); |
| 91 | + } |
51 | 92 |
|
52 | 93 | } |
0 commit comments