Skip to content

Commit

Permalink
Merge pull request #41281 from melloware/lgtm-41241
Browse files Browse the repository at this point in the history
Observability Dev UI Card and Log Console
  • Loading branch information
geoand authored Sep 16, 2024
2 parents 2b814d3 + ef8d3fc commit cbb7331
Show file tree
Hide file tree
Showing 12 changed files with 336 additions and 1 deletion.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions docs/src/main/asciidoc/observability-devservices-lgtm.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ If you miss the message you can always check the port with this Docker command:
docker ps | grep grafana
----

Another option is to use the Dev UI as the Grafana URL link will be available and if selected will open a new browser tab directly to the running Grafana instance:

image::dev-ui-observability-card.png[alt=Dev UI LGTM, align=center,width=80%]

=== Additional configuration

This extension will configure your `quarkus-opentelemetry` and `quarkus-micrometer-registry-otlp` extensions to send data to the OTel Collector bundled with the Grafana OTel LGTM image.
Expand Down
9 changes: 9 additions & 0 deletions extensions/observability-devservices/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-observability-devservices</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-http-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-http-dev-ui-spi</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import io.quarkus.observability.common.config.ContainerConfig;
import io.quarkus.observability.common.config.ContainerConfigUtil;
import io.quarkus.observability.common.config.ModulesConfiguration;
import io.quarkus.observability.deployment.devui.ObservabilityDevServicesConfigBuildItem;
import io.quarkus.observability.devresource.Container;
import io.quarkus.observability.devresource.DevResourceLifecycleManager;
import io.quarkus.observability.devresource.DevResources;
Expand Down Expand Up @@ -86,7 +87,8 @@ public void startContainers(LaunchModeBuildItem launchMode,
BuildProducer<DevServicesResultBuildItem> services,
BeanArchiveIndexBuildItem indexBuildItem,
Capabilities capabilities,
Optional<MetricsCapabilityBuildItem> metricsConfiguration) {
Optional<MetricsCapabilityBuildItem> metricsConfiguration,
BuildProducer<ObservabilityDevServicesConfigBuildItem> configBuildProducer) {

if (!configuration.enabled()) {
log.infof("Observability dev services are disabled in config");
Expand Down Expand Up @@ -162,6 +164,7 @@ public void startContainers(LaunchModeBuildItem launchMode,

devService = newDevService;
devServices.put(devId, newDevService);
configBuildProducer.produce(new ObservabilityDevServicesConfigBuildItem(newDevService.getConfig()));
} catch (Throwable t) {
compressor.closeAndDumpCaptured();
throw new RuntimeException(t);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.quarkus.observability.deployment.devui;

import java.util.Map;

import io.quarkus.builder.item.SimpleBuildItem;

/**
* Build item used to carry running DevService values to Dev UI.
*/
public final class ObservabilityDevServicesConfigBuildItem extends SimpleBuildItem {

private final Map<String, String> config;

public ObservabilityDevServicesConfigBuildItem(Map<String, String> config) {
this.config = config;
}

public Map<String, String> getConfig() {
return config;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package io.quarkus.observability.deployment.devui;

import java.util.Map;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;

import io.quarkus.deployment.IsDevelopment;
import io.quarkus.deployment.IsNormal;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.BuildSteps;
import io.quarkus.deployment.dev.devservices.GlobalDevServicesConfig;
import io.quarkus.devui.spi.page.CardPageBuildItem;
import io.quarkus.devui.spi.page.ExternalPageBuilder;
import io.quarkus.devui.spi.page.FooterPageBuildItem;
import io.quarkus.devui.spi.page.Page;
import io.quarkus.devui.spi.page.WebComponentPageBuilder;

/**
* Dev UI card for displaying important details such LGTM embedded UI.
*/
@BuildSteps(onlyIfNot = IsNormal.class, onlyIf = { GlobalDevServicesConfig.Enabled.class })
public class ObservabilityDevUIProcessor {

@BuildStep(onlyIf = IsDevelopment.class)
void createVersion(BuildProducer<CardPageBuildItem> cardPageBuildItemBuildProducer,
BuildProducer<FooterPageBuildItem> footerProducer,
Optional<ObservabilityDevServicesConfigBuildItem> configProps) {

// LGTM
if (configProps.isPresent()) {
Map<String, String> runtimeConfig = configProps.get().getConfig();
String grafanaUrl = runtimeConfig.getOrDefault("grafana.endpoint", "");

if (StringUtils.isNotEmpty(grafanaUrl)) {
final CardPageBuildItem card = new CardPageBuildItem();

// Grafana
grafanaUrl = StringUtils.prependIfMissing(grafanaUrl, "http://");
card.addPage(Page.externalPageBuilder("Grafana UI")
.url(grafanaUrl, grafanaUrl)
.doNotEmbed()
.isHtmlContent()
.icon("font-awesome-solid:chart-line"));

// Open Telemetry
final ExternalPageBuilder otelPage = Page.externalPageBuilder("OpenTelemetry Port")
.icon("font-awesome-solid:binoculars")
.doNotEmbed()
.url("https://opentelemetry.io/")
.staticLabel(StringUtils
.substringAfterLast(runtimeConfig.getOrDefault("otel-collector.url", "0"), ":"));
card.addPage(otelPage);

card.setCustomCard("qwc-lgtm-card.js");
cardPageBuildItemBuildProducer.produce(card);

// LGTM Container Log Console
WebComponentPageBuilder mailLogPageBuilder = Page.webComponentPageBuilder()
.icon("font-awesome-solid:chart-line")
.title("LGTM")
.componentLink("qwc-lgtm-log.js");

footerProducer.produce(new FooterPageBuildItem(mailLogPageBuilder));
}
}

}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { QwcServerLog } from "qwc-server-log";

/**
* This component filter the log to only show LGTM related entries.
*/
export class QwcLgtmLog extends QwcServerLog {
doLogEntry(entry) {
if (entry.loggerName && entry.loggerName.includes("LgtmContainer")) {
return true;
}
return false;
}
}

customElements.define("qwc-lgtm-log", QwcLgtmLog);
4 changes: 4 additions & 0 deletions extensions/observability-devservices/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-core</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-http</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: "Observability"
artifact: ${project.groupId}:${project.artifactId}:${project.version}
metadata:
keywords:
- "lgtm"
- "grafana"
- "prometheus"
- "tempo"
- "opentelemetry"
- "tracing"
- "distributed-tracing"
- "monitoring"
- "micrometer"
- "metrics"
categories:
- "observability"
config:
- "quarkus.observability."
status: "experimental"
guide: "https://quarkus.io/guides/observability-devservices-lgtm"
icon-url: "https://upload.wikimedia.org/wikipedia/commons/3/3b/Grafana_icon.svg"
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@
import java.util.Optional;
import java.util.Set;

import org.jboss.logging.Logger;

import io.quarkus.observability.common.ContainerConstants;
import io.quarkus.observability.common.config.AbstractGrafanaConfig;
import io.quarkus.observability.common.config.LgtmConfig;

public class LgtmContainer extends GrafanaContainer<LgtmContainer, LgtmConfig> {
/**
* Logger which will be used to capture container STDOUT and STDERR.
*/
private static final Logger log = Logger.getLogger(LgtmContainer.class);

protected static final String LGTM_NETWORK_ALIAS = "ltgm.testcontainer.docker";

public LgtmContainer() {
Expand All @@ -17,6 +24,7 @@ public LgtmContainer() {
public LgtmContainer(LgtmConfig config) {
super(config);
addExposedPorts(config.otlpPort());
withLogConsumer(new LgtmContainerLogConsumer(log).withPrefix("LGTM"));
}

public int getOtlpPort() {
Expand Down
Loading

0 comments on commit cbb7331

Please sign in to comment.