diff --git a/jvm-runtime/ftl-runtime/common/deployment/pom.xml b/jvm-runtime/ftl-runtime/common/deployment/pom.xml
index 0ba449822e..72d4d26f41 100644
--- a/jvm-runtime/ftl-runtime/common/deployment/pom.xml
+++ b/jvm-runtime/ftl-runtime/common/deployment/pom.xml
@@ -23,6 +23,10 @@
io.quarkus
quarkus-rest-jackson-deployment
+
+ io.quarkus
+ quarkus-opentelemetry-deployment
+
io.quarkus
quarkus-agroal-spi
diff --git a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/BannerConfigSource.java b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/BannerConfigSource.java
deleted file mode 100644
index 0ce5fff4e4..0000000000
--- a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/BannerConfigSource.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package xyz.block.ftl.deployment;
-
-import java.util.Set;
-
-import org.eclipse.microprofile.config.spi.ConfigSource;
-
-public class BannerConfigSource implements ConfigSource {
-
- public static final String QUARKUS_BANNER_ENABLED = "quarkus.banner.enabled";
-
- @Override
- public Set getPropertyNames() {
- return Set.of(QUARKUS_BANNER_ENABLED);
- }
-
- @Override
- public String getValue(String propertyName) {
- if (propertyName.equals(QUARKUS_BANNER_ENABLED)) {
- return "false";
- }
- return null;
- }
-
- @Override
- public String getName() {
- return "Quarkus Banner";
- }
-}
diff --git a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/StaticConfigSource.java b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/StaticConfigSource.java
new file mode 100644
index 0000000000..d00e7ef877
--- /dev/null
+++ b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/StaticConfigSource.java
@@ -0,0 +1,41 @@
+package xyz.block.ftl.deployment;
+
+import java.util.Set;
+
+import org.eclipse.microprofile.config.spi.ConfigSource;
+
+public class StaticConfigSource implements ConfigSource {
+
+ public static final String QUARKUS_BANNER_ENABLED = "quarkus.banner.enabled";
+ final static String OTEL_ENDPOINT = "quarkus.otel.exporter.otlp.endpoint";
+ final static String OTEL_METRICS_ENABLED = "quarkus.otel.metrics.enabled";
+
+ @Override
+ public Set getPropertyNames() {
+ return Set.of(QUARKUS_BANNER_ENABLED);
+ }
+
+ @Override
+ public String getValue(String propertyName) {
+ switch (propertyName) {
+ case (QUARKUS_BANNER_ENABLED) -> {
+ return "false";
+ }
+ case OTEL_ENDPOINT -> {
+ if (System.getenv("QUARKUS_OTEL_EXPORTER_OTLP_ENDPOINT") != null) {
+ return System.getenv("QUARKUS_OTEL_EXPORTER_OTLP_ENDPOINT");
+ }
+ return null;
+ }
+ case OTEL_METRICS_ENABLED -> {
+ return "true";
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String getName() {
+ return "Quarkus Static Config Source";
+ }
+}
diff --git a/jvm-runtime/ftl-runtime/common/deployment/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource b/jvm-runtime/ftl-runtime/common/deployment/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource
index d8995dc83b..3560bbbc3a 100644
--- a/jvm-runtime/ftl-runtime/common/deployment/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource
+++ b/jvm-runtime/ftl-runtime/common/deployment/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource
@@ -1 +1 @@
-xyz.block.ftl.deployment.BannerConfigSource
\ No newline at end of file
+xyz.block.ftl.deployment.StaticConfigSource
\ No newline at end of file
diff --git a/jvm-runtime/ftl-runtime/common/runtime/pom.xml b/jvm-runtime/ftl-runtime/common/runtime/pom.xml
index d8b58c7940..1f0ac4cce3 100644
--- a/jvm-runtime/ftl-runtime/common/runtime/pom.xml
+++ b/jvm-runtime/ftl-runtime/common/runtime/pom.xml
@@ -24,6 +24,14 @@
io.quarkus
quarkus-rest-jackson
+
+ io.quarkus
+ quarkus-opentelemetry
+
+
+ io.opentelemetry.instrumentation
+ opentelemetry-jdbc
+
com.fasterxml.jackson.module
jackson-module-kotlin
diff --git a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/runtime/VerbHandler.java b/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/runtime/VerbHandler.java
index 50f6fac6f1..86c77aab87 100644
--- a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/runtime/VerbHandler.java
+++ b/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/runtime/VerbHandler.java
@@ -1,8 +1,11 @@
package xyz.block.ftl.runtime;
+import io.opentelemetry.api.metrics.DoubleGauge;
import jakarta.inject.Singleton;
import io.grpc.stub.StreamObserver;
+import io.opentelemetry.api.metrics.LongCounter;
+import io.opentelemetry.api.metrics.Meter;
import io.quarkus.grpc.GrpcService;
import xyz.block.ftl.v1.*;
@@ -11,14 +14,21 @@
public class VerbHandler extends VerbServiceGrpc.VerbServiceImplBase {
final VerbRegistry registry;
+ final LongCounter counter;
- public VerbHandler(VerbRegistry registry) {
+ public VerbHandler(VerbRegistry registry, Meter meter) {
this.registry = registry;
+ counter = meter.counterBuilder("ftl-jvm-runtime/verb_invocations")
+ .setDescription("The number of verb invocations")
+ .setUnit("invocations")
+ .build();
}
@Override
public void call(CallRequest request, StreamObserver responseObserver) {
try {
+ counter.add(1);
+
var response = registry.invoke(request);
responseObserver.onNext(response);
responseObserver.onCompleted();