diff --git a/_data/versioned/main/index/quarkus.yaml b/_data/versioned/main/index/quarkus.yaml
index 0a7035974f..b36785856e 100644
--- a/_data/versioned/main/index/quarkus.yaml
+++ b/_data/versioned/main/index/quarkus.yaml
@@ -1845,6 +1845,28 @@ types:
- io.quarkus:quarkus-narayana-lra
type: guide
url: /guides/lra
+ - title: Observability Dev Services
+ filename: observability-devservices.adoc
+ summary: Entry point for Observability DevServices
+ categories: observability
+ topics:
+ - observability
+ - grafana
+ - lgtm
+ - prometheus
+ - victoriametrics
+ - jaeger
+ - otel
+ - otlp
+ extensions:
+ - io.quarkus:quarkus-observability-devservices
+ type: guide
+ url: /guides/observability-devservices
+ - title: Observability Dev Services with Grafana OTel LGTM
+ filename: observability-devservices-lgtm.adoc
+ summary: "OTel-LGTM is all-in-one Docker image containing OpenTelemetry’s OTLP as the protocol to transport metrics, tracing and logging data to an OpenTelemetry Collector which then stores signals data into Prometheus (metrics), Tempo (traces) and Loki (logs), only to have it visualized by Grafana."
+ type: guide
+ url: /guides/observability-devservices-lgtm
- title: Packaging And Releasing With JReleaser
filename: jreleaser.adoc
summary: This guide covers packaging and releasing CLI applications using the JReleaser tool.
diff --git a/_data/versioned/main/index/relations.yaml b/_data/versioned/main/index/relations.yaml
index 0d55bf3faa..ebb9437409 100644
--- a/_data/versioned/main/index/relations.yaml
+++ b/_data/versioned/main/index/relations.yaml
@@ -1561,6 +1561,10 @@
url: /guides/telemetry-opentracing-to-otel-tutorial
type: tutorial
matches: 1
+ - title: Observability Dev Services
+ url: /guides/observability-devservices
+ type: guide
+ matches: 1
- title: SmallRye Health
url: /guides/smallrye-health
type: guide
@@ -9005,6 +9009,10 @@
url: /guides/telemetry-opentracing-to-otel-tutorial
type: tutorial
matches: 1
+ - title: Observability Dev Services
+ url: /guides/observability-devservices
+ type: guide
+ matches: 1
- title: SmallRye Health
url: /guides/smallrye-health
type: guide
@@ -9179,6 +9187,10 @@
url: /guides/telemetry-opentracing-to-otel-tutorial
type: tutorial
matches: 1
+ - title: Observability Dev Services
+ url: /guides/observability-devservices
+ type: guide
+ matches: 1
- title: SmallRye Health
url: /guides/smallrye-health
type: guide
@@ -9840,6 +9852,44 @@
url: /guides/native-and-ssl
type: guide
matches: 1
+/guides/observability-devservices:
+ sameTopics:
+ - title: Collect metrics using Micrometer
+ url: /guides/telemetry-micrometer-tutorial
+ type: tutorial
+ matches: 2
+ - title: "Centralized log management (Graylog, Logstash, Fluentd)"
+ url: /guides/centralized-log-management
+ type: guide
+ matches: 1
+ - title: Logging configuration
+ url: /guides/logging
+ type: reference
+ matches: 1
+ - title: Management interface reference
+ url: /guides/management-interface-reference
+ type: reference
+ matches: 1
+ - title: Micrometer Metrics
+ url: /guides/telemetry-micrometer
+ type: reference
+ matches: 1
+ - title: Migrate from OpenTracing to OpenTelemetry tracing
+ url: /guides/telemetry-opentracing-to-otel-tutorial
+ type: tutorial
+ matches: 1
+ - title: SmallRye Health
+ url: /guides/smallrye-health
+ type: guide
+ matches: 1
+ - title: SmallRye Metrics
+ url: /guides/smallrye-metrics
+ type: guide
+ matches: 1
+ - title: Using OpenTelemetry
+ url: /guides/opentelemetry
+ type: guide
+ matches: 1
/guides/openapi-swaggerui:
sameTopics:
- title: Authorization of web endpoints
@@ -9920,6 +9970,10 @@
url: /guides/telemetry-micrometer
type: reference
matches: 1
+ - title: Observability Dev Services
+ url: /guides/observability-devservices
+ type: guide
+ matches: 1
- title: SmallRye Health
url: /guides/smallrye-health
type: guide
@@ -17797,6 +17851,10 @@
url: /guides/telemetry-opentracing-to-otel-tutorial
type: tutorial
matches: 1
+ - title: Observability Dev Services
+ url: /guides/observability-devservices
+ type: guide
+ matches: 1
- title: SmallRye Metrics
url: /guides/smallrye-metrics
type: guide
@@ -17831,6 +17889,10 @@
url: /guides/telemetry-opentracing-to-otel-tutorial
type: tutorial
matches: 1
+ - title: Observability Dev Services
+ url: /guides/observability-devservices
+ type: guide
+ matches: 1
- title: SmallRye Health
url: /guides/smallrye-health
type: guide
@@ -18906,6 +18968,10 @@
url: /guides/telemetry-opentracing-to-otel-tutorial
type: tutorial
matches: 1
+ - title: Observability Dev Services
+ url: /guides/observability-devservices
+ type: guide
+ matches: 1
- title: SmallRye Health
url: /guides/smallrye-health
type: guide
@@ -18929,6 +18995,10 @@
url: /guides/telemetry-micrometer
type: reference
matches: 2
+ - title: Observability Dev Services
+ url: /guides/observability-devservices
+ type: guide
+ matches: 2
- title: "Centralized log management (Graylog, Logstash, Fluentd)"
url: /guides/centralized-log-management
type: guide
@@ -18988,6 +19058,10 @@
url: /guides/telemetry-micrometer
type: reference
matches: 1
+ - title: Observability Dev Services
+ url: /guides/observability-devservices
+ type: guide
+ matches: 1
- title: SmallRye Health
url: /guides/smallrye-health
type: guide
diff --git a/_generated-doc/main/config/all-configuration-roots-generated-doc/io.quarkus.observability.runtime.config.ObservabilityConfiguration b/_generated-doc/main/config/all-configuration-roots-generated-doc/io.quarkus.observability.runtime.config.ObservabilityConfiguration
new file mode 100644
index 0000000000..c8707bbecf
--- /dev/null
+++ b/_generated-doc/main/config/all-configuration-roots-generated-doc/io.quarkus.observability.runtime.config.ObservabilityConfiguration
@@ -0,0 +1 @@
+[{"configDocKey":{"type":"io.quarkus.observability.common.config.LgtmConfig","key":"quarkus.observability.lgtm","additionalKeys":[],"configDoc":"","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"lgtm","configPhase":"BUILD_TIME","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.observability","since":null,"environmentVariable":"QUARKUS_OBSERVABILITY_LGTM","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.observability.enabled","additionalKeys":[],"configDoc":"If DevServices has been explicitly enabled or disabled. DevServices is generally enabled by default, unless there is an existing configuration present.\n\nWhen DevServices is enabled Quarkus will attempt to automatically configure and start a containers when running in Dev or Test mode and when Docker is running.","withinAMap":false,"defaultValue":"true","javaDocSiteLink":"","docMapKey":"enabled","configPhase":"BUILD_TIME","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.observability","since":null,"environmentVariable":"QUARKUS_OBSERVABILITY_ENABLED","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.observability.dev-resources","additionalKeys":[],"configDoc":"Enable simplified usage of dev resources, instead of full observability processing. Make sure @code++{++enabled++}++ is set to false.","withinAMap":false,"defaultValue":"false","javaDocSiteLink":"","docMapKey":"dev-resources","configPhase":"BUILD_TIME","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.observability","since":null,"environmentVariable":"QUARKUS_OBSERVABILITY_DEV_RESOURCES","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.observability.parallel","additionalKeys":[],"configDoc":"Do we start the dev services in parallel.","withinAMap":false,"defaultValue":"false","javaDocSiteLink":"","docMapKey":"parallel","configPhase":"BUILD_TIME","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.observability","since":null,"environmentVariable":"QUARKUS_OBSERVABILITY_PARALLEL","enum":false}}]
\ No newline at end of file
diff --git a/_generated-doc/main/config/all-configuration-roots-generated-doc/io.quarkus.websockets.next.WebSocketsRuntimeConfig b/_generated-doc/main/config/all-configuration-roots-generated-doc/io.quarkus.websockets.next.WebSocketsRuntimeConfig
index e8d1699bee..386d8aab1b 100644
--- a/_generated-doc/main/config/all-configuration-roots-generated-doc/io.quarkus.websockets.next.WebSocketsRuntimeConfig
+++ b/_generated-doc/main/config/all-configuration-roots-generated-doc/io.quarkus.websockets.next.WebSocketsRuntimeConfig
@@ -1 +1 @@
-[{"configDocKey":{"type":"string","key":"quarkus.websockets-next.supported-subprotocols","additionalKeys":[],"configDoc":"See link:https://datatracker.ietf.org/doc/html/rfc6455#page-12[The WebSocket Protocol]","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"supported-subprotocols","configPhase":"RUN_TIME","acceptedValues":null,"optional":true,"list":true,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.websockets-next","since":null,"environmentVariable":"QUARKUS_WEBSOCKETS_NEXT_SUPPORTED_SUBPROTOCOLS","enum":false}},{"configDocKey":{"type":"java.time.Duration","key":"quarkus.websockets-next.timeout","additionalKeys":[],"configDoc":"TODO Not implemented yet. The default timeout to complete processing of a message.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html","docMapKey":"timeout","configPhase":"RUN_TIME","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.websockets-next","since":null,"environmentVariable":"QUARKUS_WEBSOCKETS_NEXT_TIMEOUT","enum":false}}]
\ No newline at end of file
+[{"configDocKey":{"type":"string","key":"quarkus.websockets-next.supported-subprotocols","additionalKeys":[],"configDoc":"See link:https://datatracker.ietf.org/doc/html/rfc6455#page-12[The WebSocket Protocol]","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"supported-subprotocols","configPhase":"RUN_TIME","acceptedValues":null,"optional":true,"list":true,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.websockets-next","since":null,"environmentVariable":"QUARKUS_WEBSOCKETS_NEXT_SUPPORTED_SUBPROTOCOLS","enum":false}},{"configDocKey":{"type":"boolean","key":"quarkus.websockets-next.per-message-compression-supported","additionalKeys":[],"configDoc":"Compression Extensions for WebSocket are supported by default.\n\nSee also link:https://datatracker.ietf.org/doc/html/rfc7692[RFC 7692]","withinAMap":false,"defaultValue":"true","javaDocSiteLink":"","docMapKey":"per-message-compression-supported","configPhase":"RUN_TIME","acceptedValues":null,"optional":false,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.websockets-next","since":null,"environmentVariable":"QUARKUS_WEBSOCKETS_NEXT_PER_MESSAGE_COMPRESSION_SUPPORTED","enum":false}},{"configDocKey":{"type":"java.lang.Integer","key":"quarkus.websockets-next.compression-level","additionalKeys":[],"configDoc":"The compression level must be a value between 0 and 9. The default value is `HttpServerOptions++#++DEFAULT_WEBSOCKET_COMPRESSION_LEVEL`.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"compression-level","configPhase":"RUN_TIME","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.websockets-next","since":null,"environmentVariable":"QUARKUS_WEBSOCKETS_NEXT_COMPRESSION_LEVEL","enum":false}},{"configDocKey":{"type":"java.lang.Integer","key":"quarkus.websockets-next.max-message-size","additionalKeys":[],"configDoc":"The maximum size of a message in bytes. The default values is `HttpServerOptions++#++DEFAULT_MAX_WEBSOCKET_MESSAGE_SIZE`.","withinAMap":false,"defaultValue":"","javaDocSiteLink":"","docMapKey":"max-message-size","configPhase":"RUN_TIME","acceptedValues":null,"optional":true,"list":false,"passThroughMap":false,"withinAConfigGroup":false,"topLevelGrouping":"quarkus.websockets-next","since":null,"environmentVariable":"QUARKUS_WEBSOCKETS_NEXT_MAX_MESSAGE_SIZE","enum":false}}]
\ No newline at end of file
diff --git a/_generated-doc/main/config/extensions-configuration-roots-list/quarkus-observability.adoc/io.quarkus.observability.runtime.config.ObservabilityConfiguration b/_generated-doc/main/config/extensions-configuration-roots-list/quarkus-observability.adoc/io.quarkus.observability.runtime.config.ObservabilityConfiguration
new file mode 100644
index 0000000000..b6828a2294
--- /dev/null
+++ b/_generated-doc/main/config/extensions-configuration-roots-list/quarkus-observability.adoc/io.quarkus.observability.runtime.config.ObservabilityConfiguration
@@ -0,0 +1 @@
+io.quarkus.observability.runtime.config.ObservabilityConfiguration
\ No newline at end of file
diff --git a/_generated-doc/main/config/quarkus-all-config.adoc b/_generated-doc/main/config/quarkus-all-config.adoc
index 30d42c948f..3c88682ecd 100644
--- a/_generated-doc/main/config/quarkus-all-config.adoc
+++ b/_generated-doc/main/config/quarkus-all-config.adoc
@@ -58067,6 +58067,79 @@ endif::add-copy-button-to-env-var[]
|`DEBUG`
+h|[[quarkus-observability-devservices_quarkus-observability-devservices-quarkus-observability-dev-services-runtime]]link:#quarkus-observability-devservices_quarkus-observability-devservices-quarkus-observability-dev-services-runtime[Quarkus - Observability Dev Services - Runtime]
+
+h|Type
+h|Default
+
+a|icon:lock[title=Fixed at build time] [[quarkus-observability-devservices_quarkus-observability-lgtm]]`link:#quarkus-observability-devservices_quarkus-observability-lgtm[quarkus.observability.lgtm]`
+
+
+[.description]
+--
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_OBSERVABILITY_LGTM+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_OBSERVABILITY_LGTM+++`
+endif::add-copy-button-to-env-var[]
+--|LgtmConfig
+|required icon:exclamation-circle[title=Configuration property is required]
+
+
+a|icon:lock[title=Fixed at build time] [[quarkus-observability-devservices_quarkus-observability-enabled]]`link:#quarkus-observability-devservices_quarkus-observability-enabled[quarkus.observability.enabled]`
+
+
+[.description]
+--
+If DevServices has been explicitly enabled or disabled. DevServices is generally enabled by default, unless there is an existing configuration present.
+
+When DevServices is enabled Quarkus will attempt to automatically configure and start a containers when running in Dev or Test mode and when Docker is running.
+
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_OBSERVABILITY_ENABLED+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_OBSERVABILITY_ENABLED+++`
+endif::add-copy-button-to-env-var[]
+--|boolean
+|`true`
+
+
+a|icon:lock[title=Fixed at build time] [[quarkus-observability-devservices_quarkus-observability-dev-resources]]`link:#quarkus-observability-devservices_quarkus-observability-dev-resources[quarkus.observability.dev-resources]`
+
+
+[.description]
+--
+Enable simplified usage of dev resources, instead of full observability processing. Make sure @code++{++enabled++}++ is set to false.
+
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_OBSERVABILITY_DEV_RESOURCES+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_OBSERVABILITY_DEV_RESOURCES+++`
+endif::add-copy-button-to-env-var[]
+--|boolean
+|`false`
+
+
+a|icon:lock[title=Fixed at build time] [[quarkus-observability-devservices_quarkus-observability-parallel]]`link:#quarkus-observability-devservices_quarkus-observability-parallel[quarkus.observability.parallel]`
+
+
+[.description]
+--
+Do we start the dev services in parallel.
+
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_OBSERVABILITY_PARALLEL+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_OBSERVABILITY_PARALLEL+++`
+endif::add-copy-button-to-env-var[]
+--|boolean
+|`false`
+
+
h|[[quarkus-spring-boot-properties_quarkus-spring-boot-properties-quarkus-extension-for-spring-boot-properties]]link:#quarkus-spring-boot-properties_quarkus-spring-boot-properties-quarkus-extension-for-spring-boot-properties[Quarkus Extension for Spring Boot properties]
h|Type
@@ -69941,21 +70014,56 @@ endif::add-copy-button-to-env-var[]
|
-a| [[quarkus-websockets-next_quarkus-websockets-next-timeout]]`link:#quarkus-websockets-next_quarkus-websockets-next-timeout[quarkus.websockets-next.timeout]`
+a| [[quarkus-websockets-next_quarkus-websockets-next-per-message-compression-supported]]`link:#quarkus-websockets-next_quarkus-websockets-next-per-message-compression-supported[quarkus.websockets-next.per-message-compression-supported]`
[.description]
--
-TODO Not implemented yet. The default timeout to complete processing of a message.
+Compression Extensions for WebSocket are supported by default.
+
+See also link:https://datatracker.ietf.org/doc/html/rfc7692[RFC 7692]
ifdef::add-copy-button-to-env-var[]
-Environment variable: env_var_with_copy_button:+++QUARKUS_WEBSOCKETS_NEXT_TIMEOUT+++[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_WEBSOCKETS_NEXT_PER_MESSAGE_COMPRESSION_SUPPORTED+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
-Environment variable: `+++QUARKUS_WEBSOCKETS_NEXT_TIMEOUT+++`
+Environment variable: `+++QUARKUS_WEBSOCKETS_NEXT_PER_MESSAGE_COMPRESSION_SUPPORTED+++`
endif::add-copy-button-to-env-var[]
---|link:https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html[Duration]
- link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
+--|boolean
+|`true`
+
+
+a| [[quarkus-websockets-next_quarkus-websockets-next-compression-level]]`link:#quarkus-websockets-next_quarkus-websockets-next-compression-level[quarkus.websockets-next.compression-level]`
+
+
+[.description]
+--
+The compression level must be a value between 0 and 9. The default value is `HttpServerOptions++#++DEFAULT_WEBSOCKET_COMPRESSION_LEVEL`.
+
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_WEBSOCKETS_NEXT_COMPRESSION_LEVEL+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_WEBSOCKETS_NEXT_COMPRESSION_LEVEL+++`
+endif::add-copy-button-to-env-var[]
+--|int
+|
+
+
+a| [[quarkus-websockets-next_quarkus-websockets-next-max-message-size]]`link:#quarkus-websockets-next_quarkus-websockets-next-max-message-size[quarkus.websockets-next.max-message-size]`
+
+
+[.description]
+--
+The maximum size of a message in bytes. The default values is `HttpServerOptions++#++DEFAULT_MAX_WEBSOCKET_MESSAGE_SIZE`.
+
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_WEBSOCKETS_NEXT_MAX_MESSAGE_SIZE+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_WEBSOCKETS_NEXT_MAX_MESSAGE_SIZE+++`
+endif::add-copy-button-to-env-var[]
+--|int
|
diff --git a/_generated-doc/main/config/quarkus-observability-config-observability-configuration.adoc b/_generated-doc/main/config/quarkus-observability-config-observability-configuration.adoc
new file mode 100644
index 0000000000..5ec45bd17c
--- /dev/null
+++ b/_generated-doc/main/config/quarkus-observability-config-observability-configuration.adoc
@@ -0,0 +1,80 @@
+
+:summaryTableId: quarkus-observability-config-observability-configuration
+[.configuration-legend]
+icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime
+[.configuration-reference, cols="80,.^10,.^10"]
+|===
+
+h|[[quarkus-observability-config-observability-configuration_configuration]]link:#quarkus-observability-config-observability-configuration_configuration[Configuration property]
+
+h|Type
+h|Default
+
+a|icon:lock[title=Fixed at build time] [[quarkus-observability-config-observability-configuration_quarkus-observability-lgtm]]`link:#quarkus-observability-config-observability-configuration_quarkus-observability-lgtm[quarkus.observability.lgtm]`
+
+
+[.description]
+--
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_OBSERVABILITY_LGTM+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_OBSERVABILITY_LGTM+++`
+endif::add-copy-button-to-env-var[]
+--|LgtmConfig
+|required icon:exclamation-circle[title=Configuration property is required]
+
+
+a|icon:lock[title=Fixed at build time] [[quarkus-observability-config-observability-configuration_quarkus-observability-enabled]]`link:#quarkus-observability-config-observability-configuration_quarkus-observability-enabled[quarkus.observability.enabled]`
+
+
+[.description]
+--
+If DevServices has been explicitly enabled or disabled. DevServices is generally enabled by default, unless there is an existing configuration present.
+
+When DevServices is enabled Quarkus will attempt to automatically configure and start a containers when running in Dev or Test mode and when Docker is running.
+
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_OBSERVABILITY_ENABLED+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_OBSERVABILITY_ENABLED+++`
+endif::add-copy-button-to-env-var[]
+--|boolean
+|`true`
+
+
+a|icon:lock[title=Fixed at build time] [[quarkus-observability-config-observability-configuration_quarkus-observability-dev-resources]]`link:#quarkus-observability-config-observability-configuration_quarkus-observability-dev-resources[quarkus.observability.dev-resources]`
+
+
+[.description]
+--
+Enable simplified usage of dev resources, instead of full observability processing. Make sure @code++{++enabled++}++ is set to false.
+
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_OBSERVABILITY_DEV_RESOURCES+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_OBSERVABILITY_DEV_RESOURCES+++`
+endif::add-copy-button-to-env-var[]
+--|boolean
+|`false`
+
+
+a|icon:lock[title=Fixed at build time] [[quarkus-observability-config-observability-configuration_quarkus-observability-parallel]]`link:#quarkus-observability-config-observability-configuration_quarkus-observability-parallel[quarkus.observability.parallel]`
+
+
+[.description]
+--
+Do we start the dev services in parallel.
+
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_OBSERVABILITY_PARALLEL+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_OBSERVABILITY_PARALLEL+++`
+endif::add-copy-button-to-env-var[]
+--|boolean
+|`false`
+
+|===
\ No newline at end of file
diff --git a/_generated-doc/main/config/quarkus-observability.adoc b/_generated-doc/main/config/quarkus-observability.adoc
new file mode 100644
index 0000000000..01fcad6f17
--- /dev/null
+++ b/_generated-doc/main/config/quarkus-observability.adoc
@@ -0,0 +1,80 @@
+
+:summaryTableId: quarkus-observability
+[.configuration-legend]
+icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime
+[.configuration-reference.searchable, cols="80,.^10,.^10"]
+|===
+
+h|[[quarkus-observability_configuration]]link:#quarkus-observability_configuration[Configuration property]
+
+h|Type
+h|Default
+
+a|icon:lock[title=Fixed at build time] [[quarkus-observability_quarkus-observability-lgtm]]`link:#quarkus-observability_quarkus-observability-lgtm[quarkus.observability.lgtm]`
+
+
+[.description]
+--
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_OBSERVABILITY_LGTM+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_OBSERVABILITY_LGTM+++`
+endif::add-copy-button-to-env-var[]
+--|LgtmConfig
+|required icon:exclamation-circle[title=Configuration property is required]
+
+
+a|icon:lock[title=Fixed at build time] [[quarkus-observability_quarkus-observability-enabled]]`link:#quarkus-observability_quarkus-observability-enabled[quarkus.observability.enabled]`
+
+
+[.description]
+--
+If DevServices has been explicitly enabled or disabled. DevServices is generally enabled by default, unless there is an existing configuration present.
+
+When DevServices is enabled Quarkus will attempt to automatically configure and start a containers when running in Dev or Test mode and when Docker is running.
+
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_OBSERVABILITY_ENABLED+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_OBSERVABILITY_ENABLED+++`
+endif::add-copy-button-to-env-var[]
+--|boolean
+|`true`
+
+
+a|icon:lock[title=Fixed at build time] [[quarkus-observability_quarkus-observability-dev-resources]]`link:#quarkus-observability_quarkus-observability-dev-resources[quarkus.observability.dev-resources]`
+
+
+[.description]
+--
+Enable simplified usage of dev resources, instead of full observability processing. Make sure @code++{++enabled++}++ is set to false.
+
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_OBSERVABILITY_DEV_RESOURCES+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_OBSERVABILITY_DEV_RESOURCES+++`
+endif::add-copy-button-to-env-var[]
+--|boolean
+|`false`
+
+
+a|icon:lock[title=Fixed at build time] [[quarkus-observability_quarkus-observability-parallel]]`link:#quarkus-observability_quarkus-observability-parallel[quarkus.observability.parallel]`
+
+
+[.description]
+--
+Do we start the dev services in parallel.
+
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_OBSERVABILITY_PARALLEL+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_OBSERVABILITY_PARALLEL+++`
+endif::add-copy-button-to-env-var[]
+--|boolean
+|`false`
+
+|===
\ No newline at end of file
diff --git a/_generated-doc/main/config/quarkus-websockets-next-websockets-next-web-sockets-runtime-config.adoc b/_generated-doc/main/config/quarkus-websockets-next-websockets-next-web-sockets-runtime-config.adoc
index 52b34aadad..a95eb01989 100644
--- a/_generated-doc/main/config/quarkus-websockets-next-websockets-next-web-sockets-runtime-config.adoc
+++ b/_generated-doc/main/config/quarkus-websockets-next-websockets-next-web-sockets-runtime-config.adoc
@@ -27,40 +27,56 @@ endif::add-copy-button-to-env-var[]
|
-a| [[quarkus-websockets-next-websockets-next-web-sockets-runtime-config_quarkus-websockets-next-timeout]]`link:#quarkus-websockets-next-websockets-next-web-sockets-runtime-config_quarkus-websockets-next-timeout[quarkus.websockets-next.timeout]`
+a| [[quarkus-websockets-next-websockets-next-web-sockets-runtime-config_quarkus-websockets-next-per-message-compression-supported]]`link:#quarkus-websockets-next-websockets-next-web-sockets-runtime-config_quarkus-websockets-next-per-message-compression-supported[quarkus.websockets-next.per-message-compression-supported]`
[.description]
--
-TODO Not implemented yet. The default timeout to complete processing of a message.
+Compression Extensions for WebSocket are supported by default.
+
+See also link:https://datatracker.ietf.org/doc/html/rfc7692[RFC 7692]
ifdef::add-copy-button-to-env-var[]
-Environment variable: env_var_with_copy_button:+++QUARKUS_WEBSOCKETS_NEXT_TIMEOUT+++[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_WEBSOCKETS_NEXT_PER_MESSAGE_COMPRESSION_SUPPORTED+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
-Environment variable: `+++QUARKUS_WEBSOCKETS_NEXT_TIMEOUT+++`
+Environment variable: `+++QUARKUS_WEBSOCKETS_NEXT_PER_MESSAGE_COMPRESSION_SUPPORTED+++`
endif::add-copy-button-to-env-var[]
---|link:https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html[Duration]
- link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
+--|boolean
+|`true`
+
+
+a| [[quarkus-websockets-next-websockets-next-web-sockets-runtime-config_quarkus-websockets-next-compression-level]]`link:#quarkus-websockets-next-websockets-next-web-sockets-runtime-config_quarkus-websockets-next-compression-level[quarkus.websockets-next.compression-level]`
+
+
+[.description]
+--
+The compression level must be a value between 0 and 9. The default value is `HttpServerOptions++#++DEFAULT_WEBSOCKET_COMPRESSION_LEVEL`.
+
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_WEBSOCKETS_NEXT_COMPRESSION_LEVEL+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_WEBSOCKETS_NEXT_COMPRESSION_LEVEL+++`
+endif::add-copy-button-to-env-var[]
+--|int
|
-|===
-ifndef::no-duration-note[]
-[NOTE]
-[id='duration-note-anchor-{summaryTableId}']
-.About the Duration format
-====
-To write duration values, use the standard `java.time.Duration` format.
-See the link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html#parse(java.lang.CharSequence)[Duration#parse() Java API documentation] for more information.
-You can also use a simplified format, starting with a number:
+a| [[quarkus-websockets-next-websockets-next-web-sockets-runtime-config_quarkus-websockets-next-max-message-size]]`link:#quarkus-websockets-next-websockets-next-web-sockets-runtime-config_quarkus-websockets-next-max-message-size[quarkus.websockets-next.max-message-size]`
+
-* If the value is only a number, it represents time in seconds.
-* If the value is a number followed by `ms`, it represents time in milliseconds.
+[.description]
+--
+The maximum size of a message in bytes. The default values is `HttpServerOptions++#++DEFAULT_MAX_WEBSOCKET_MESSAGE_SIZE`.
-In other cases, the simplified format is translated to the `java.time.Duration` format for parsing:
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_WEBSOCKETS_NEXT_MAX_MESSAGE_SIZE+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_WEBSOCKETS_NEXT_MAX_MESSAGE_SIZE+++`
+endif::add-copy-button-to-env-var[]
+--|int
+|
-* If the value is a number followed by `h`, `m`, or `s`, it is prefixed with `PT`.
-* If the value is a number followed by `d`, it is prefixed with `P`.
-====
-endif::no-duration-note[]
+|===
\ No newline at end of file
diff --git a/_generated-doc/main/config/quarkus-websockets-next.adoc b/_generated-doc/main/config/quarkus-websockets-next.adoc
index 8aa5f07883..c9093d989f 100644
--- a/_generated-doc/main/config/quarkus-websockets-next.adoc
+++ b/_generated-doc/main/config/quarkus-websockets-next.adoc
@@ -27,40 +27,56 @@ endif::add-copy-button-to-env-var[]
|
-a| [[quarkus-websockets-next_quarkus-websockets-next-timeout]]`link:#quarkus-websockets-next_quarkus-websockets-next-timeout[quarkus.websockets-next.timeout]`
+a| [[quarkus-websockets-next_quarkus-websockets-next-per-message-compression-supported]]`link:#quarkus-websockets-next_quarkus-websockets-next-per-message-compression-supported[quarkus.websockets-next.per-message-compression-supported]`
[.description]
--
-TODO Not implemented yet. The default timeout to complete processing of a message.
+Compression Extensions for WebSocket are supported by default.
+
+See also link:https://datatracker.ietf.org/doc/html/rfc7692[RFC 7692]
ifdef::add-copy-button-to-env-var[]
-Environment variable: env_var_with_copy_button:+++QUARKUS_WEBSOCKETS_NEXT_TIMEOUT+++[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_WEBSOCKETS_NEXT_PER_MESSAGE_COMPRESSION_SUPPORTED+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
-Environment variable: `+++QUARKUS_WEBSOCKETS_NEXT_TIMEOUT+++`
+Environment variable: `+++QUARKUS_WEBSOCKETS_NEXT_PER_MESSAGE_COMPRESSION_SUPPORTED+++`
endif::add-copy-button-to-env-var[]
---|link:https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html[Duration]
- link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
+--|boolean
+|`true`
+
+
+a| [[quarkus-websockets-next_quarkus-websockets-next-compression-level]]`link:#quarkus-websockets-next_quarkus-websockets-next-compression-level[quarkus.websockets-next.compression-level]`
+
+
+[.description]
+--
+The compression level must be a value between 0 and 9. The default value is `HttpServerOptions++#++DEFAULT_WEBSOCKET_COMPRESSION_LEVEL`.
+
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_WEBSOCKETS_NEXT_COMPRESSION_LEVEL+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_WEBSOCKETS_NEXT_COMPRESSION_LEVEL+++`
+endif::add-copy-button-to-env-var[]
+--|int
|
-|===
-ifndef::no-duration-note[]
-[NOTE]
-[id='duration-note-anchor-{summaryTableId}']
-.About the Duration format
-====
-To write duration values, use the standard `java.time.Duration` format.
-See the link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html#parse(java.lang.CharSequence)[Duration#parse() Java API documentation] for more information.
-You can also use a simplified format, starting with a number:
+a| [[quarkus-websockets-next_quarkus-websockets-next-max-message-size]]`link:#quarkus-websockets-next_quarkus-websockets-next-max-message-size[quarkus.websockets-next.max-message-size]`
+
-* If the value is only a number, it represents time in seconds.
-* If the value is a number followed by `ms`, it represents time in milliseconds.
+[.description]
+--
+The maximum size of a message in bytes. The default values is `HttpServerOptions++#++DEFAULT_MAX_WEBSOCKET_MESSAGE_SIZE`.
-In other cases, the simplified format is translated to the `java.time.Duration` format for parsing:
+ifdef::add-copy-button-to-env-var[]
+Environment variable: env_var_with_copy_button:+++QUARKUS_WEBSOCKETS_NEXT_MAX_MESSAGE_SIZE+++[]
+endif::add-copy-button-to-env-var[]
+ifndef::add-copy-button-to-env-var[]
+Environment variable: `+++QUARKUS_WEBSOCKETS_NEXT_MAX_MESSAGE_SIZE+++`
+endif::add-copy-button-to-env-var[]
+--|int
+|
-* If the value is a number followed by `h`, `m`, or `s`, it is prefixed with `PT`.
-* If the value is a number followed by `d`, it is prefixed with `P`.
-====
-endif::no-duration-note[]
+|===
\ No newline at end of file
diff --git a/_versions/main/guides/dev-services.adoc b/_versions/main/guides/dev-services.adoc
index 2d44bc7c09..d2e32f4aad 100644
--- a/_versions/main/guides/dev-services.adoc
+++ b/_versions/main/guides/dev-services.adoc
@@ -165,6 +165,14 @@ More information can be found in the xref:elasticsearch-dev-services.adoc[Elasti
include::{generated-dir}/config/quarkus-elasticsearch-devservices-elasticsearch-dev-services-build-time-config.adoc[opts=optional, leveloffset=+1]
+=== Observability
+
+The Observability Dev Services will be enabled when the `quarkus-observability-devservices` extension is present in your application, and
+there is at least one dev resource on the classpath. More information can be found in the
+xref:observability-devservices.adoc[Observability Dev Services Guide].
+
+include::{generated-dir}/config/quarkus-observability-config-observability-configuration.adoc[opts=optional, leveloffset=+1]
+
== Dev Services beyond the Quarkus Platform
Many Quarkiverse extensions which are not in the Quarkus Platform also offer Dev Services.
diff --git a/_versions/main/guides/logging.adoc b/_versions/main/guides/logging.adoc
index 84bef6c0cc..4c0068b89a 100644
--- a/_versions/main/guides/logging.adoc
+++ b/_versions/main/guides/logging.adoc
@@ -446,7 +446,6 @@ To log events to a file on the application's host, use the Quarkus file log hand
The file log handler is disabled by default, so you must first enable it.
The Quarkus file log handler supports log file rotation.
-Log file rotation ensures effective log file management over time by maintaining a specified number of backup log files, while also keeping the primary log file up-to-date and manageable.
Log file rotation ensures effective log file management over time by maintaining a specified number of backup log files, while keeping the primary log file up-to-date and manageable.
diff --git a/_versions/main/guides/observability-devservices-lgtm.adoc b/_versions/main/guides/observability-devservices-lgtm.adoc
new file mode 100644
index 0000000000..df19940195
--- /dev/null
+++ b/_versions/main/guides/observability-devservices-lgtm.adoc
@@ -0,0 +1,282 @@
+////
+This guide is maintained in the main Quarkus repository
+and pull requests should be submitted there:
+https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
+////
+= Observability Dev Services with Grafana OTel LGTM
+
+include::_attributes.adoc[]
+:categories: observability,devservices,telemetry,metrics,tracing,logging, opentelemetry, micrometer, prometheus, tempo, loki, grafana
+:summary: Instructions on how to use Grafana Otel LGTM
+:topics: observability,grafana,lgtm,otlp,opentelemetry,devservices,micrometer
+:extensions: io.quarkus:quarkus-observability-devservices
+
+https://github.com/grafana/docker-otel-lgtm[OTel-LGTM] is `all-in-one` Docker image containing OpenTelemetry's https://github.com/open-telemetry/opentelemetry-proto/blob/main/docs/README.md[OTLP] as the protocol to transport metrics, tracing and logging data to an https://opentelemetry.io/docs/collector[OpenTelemetry Collector] which then stores signals data into https://prometheus.io/[Prometheus] (metrics), https://github.com/grafana/tempo[Tempo] (traces) and https://github.com/grafana/loki[Loki] (logs), only to have it visualized by https://github.com/grafana/grafana[Grafana]. It's used by Quarkus Observability to provide the Grafana OTel LGTM Dev Resource.
+
+== Configuring your project
+
+Add the Quarkus Grafana OTel LGTM sink (where data goes) extension to your build file:
+
+[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"]
+.pom.xml
+----
+
+ io.quarkus
+ quarkus-observability-devservices-lgtm
+ provided
+
+----
+
+[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"]
+.build.gradle
+----
+implementation("quarkus-observability-devservices-lgtm")
+----
+
+=== Metrics
+
+If you're using https://micrometer.io/[MicroMeter's] Quarkiverse OTLP registry to push metrics to Grafana OTel LGTM, this is how you would define the export endpoint url; where `quarkus.otel-collector.url` is provided by the Observability Dev Services extension.
+
+[source,properties]
+----
+# Micrometer OTLP registry
+%test.quarkus.micrometer.export.otlp.url=http://${quarkus.otel-collector.url}/v1/metrics
+%dev.quarkus.micrometer.export.otlp.url=http://${quarkus.otel-collector.url}/v1/metrics
+%prod.quarkus.micrometer.export.otlp.url=http://localhost:4318/v1/metrics
+----
+Please note that the `${quarkus.otel-collector.url}` value is generated by quarkus when it starts the Grafana OTel LGTM Dev Resource.
+
+Along OTel collector enpoint url, LGTM Dev Resource also provides a Grafana endpoint url - under `quarkus.grafana.url` property.
+
+In this case LGTM Dev Resource would be automatically started and used by Observability Dev Services.
+
+If you don't want all the hassle with Dev Services (e.g. lookup and re-use of existing running containers, etc) you can simply disable Dev Services and enable just Dev Resource usage:
+
+[source,properties]
+----
+quarkus.observability.enabled=false
+quarkus.observability.dev-resources=true
+----
+
+=== Tracing
+
+Just add the quarkus-opentelemetry extension to your build file:
+[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"]
+.pom.xml
+----
+
+ io.quarkus
+ quarkus-opentelemetry
+
+----
+
+[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"]
+.build.gradle
+----
+implementation("io.quarkus:quarkus-opentelemetry")
+----
+
+On the `application.properties` file, you can define:
+[source,properties]
+----
+# OpenTelemetry
+quarkus.otel.exporter.otlp.traces.protocol=http/protobuf
+%test.quarkus.otel.exporter.otlp.traces.endpoint=http://${quarkus.otel-collector.url}
+%dev.quarkus.otel.exporter.otlp.traces.endpoint=http://${quarkus.otel-collector.url}
+%prod.quarkus.otel.exporter.otlp.traces.endpoint=http://localhost:4318
+----
+=== Access Grafana
+
+Once you start your app in dev mode:
+
+include::{includes}/devtools/dev.adoc[]
+
+You will see a message like this:
+
+[source, log]
+----
+Lgtm Dev Services Starting: 2024-02-20 11:15:24,540 INFO [org.tes.con.wai.str.HttpWaitStrategy] (build-32) /loving_chatelet: Waiting for 60 seconds for URL: http://localhost:61907/ (where port 61907 maps to container port 3000)
+----
+Remember that Grafana is accessible in an ephemeral port, so you need to check the logs to see which port is being used. In this example, it's port 61907.
+
+If you miss the message you can always check the port with this Docker command:
+[source, bash]
+----
+docker ps | grep grafana
+----
+=== Tests
+
+And for the least 'auto-magical' usage in the tests, simply disable both (Dev Resources are already disabled by default):
+
+[source,properties]
+----
+quarkus.observability.enabled=false
+----
+
+And then explicitly list LGTM Dev Resource in the test as a `@QuarkusTestResource` resource:
+[source, java]
+----
+@QuarkusTest
+@QuarkusTestResource(value = LgtmResource.class, restrictToAnnotatedClass = true)
+@TestProfile(QuarkusTestResourceTestProfile.class)
+public class LgtmLifecycleTest extends LgtmTestBase {
+}
+----
+
+== Testing full Grafana OTel LGTM stack - example
+
+Use existing Quarkus MicroMeter OTLP registry
+
+[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"]
+.pom.xml
+----
+
+ io.quarkiverse.micrometer.registry
+ quarkus-micrometer-registry-otlp
+
+----
+
+[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"]
+.build.gradle
+----
+implementation("io.quarkiverse.micrometer.registry:quarkus-micrometer-registry-otlp")
+----
+
+On the test `application.properties` file, you need to define:
+[source,properties]
+----
+# Micrometer OTLP registry
+quarkus.micrometer.export.otlp.url=http://${quarkus.otel-collector.url}/v1/metrics
+# OpenTelemetry
+quarkus.otel.exporter.otlp.traces.protocol=http/protobuf
+quarkus.otel.exporter.otlp.traces.endpoint=http://${quarkus.otel-collector.url}
+----
+
+Simply inject the Meter registry into your code -- it will periodically push metrics to Grafana LGTM's OTLP HTTP endpoint.
+
+[source, java]
+----
+@Path("/api")
+public class SimpleEndpoint {
+ private static final Logger log = Logger.getLogger(SimpleEndpoint.class);
+
+ @Inject
+ MeterRegistry registry;
+
+ @PostConstruct
+ public void start() {
+ Gauge.builder("xvalue", arr, a -> arr[0])
+ .baseUnit("X")
+ .description("Some random x")
+ .tag("my_key", "x")
+ .register(registry);
+ }
+
+ // ...
+}
+----
+
+Where you can then check Grafana's datasource API for existing metrics data.
+
+[source, java]
+----
+public class LgtmTestBase {
+
+ @ConfigProperty(name = "quarkus.grafana.url")
+ String url; // NOTE -- injected Grafana endpoint url!
+
+ @Test
+ public void testTracing() {
+ String response = RestAssured.get("/api/poke?f=100").body().asString();
+ System.out.println(response);
+ GrafanaClient client = new GrafanaClient("http://" + url, "admin", "admin");
+ Awaitility.await().atMost(61, TimeUnit.SECONDS).until(
+ client::user,
+ u -> "admin".equals(u.login));
+ Awaitility.await().atMost(61, TimeUnit.SECONDS).until(
+ () -> client.query("xvalue_X"),
+ result -> !result.data.result.isEmpty());
+ }
+
+}
+
+// simple Grafana HTTP client
+
+public class GrafanaClient {
+ private static final ObjectMapper MAPPER = new ObjectMapper();
+
+ private final String url;
+ private final String username;
+ private final String password;
+
+ public GrafanaClient(String url, String username, String password) {
+ this.url = url;
+ this.username = username;
+ this.password = password;
+ }
+
+ private void handle(
+ String path,
+ Function method,
+ HttpResponse.BodyHandler bodyHandler,
+ BiConsumer, T> consumer) {
+ try {
+ String credentials = username + ":" + password;
+ String encodedCredentials = Base64.getEncoder().encodeToString(credentials.getBytes());
+
+ HttpClient httpClient = HttpClient.newHttpClient();
+ HttpRequest.Builder builder = HttpRequest.newBuilder()
+ .uri(URI.create(url + path))
+ .header("Authorization", "Basic " + encodedCredentials);
+ HttpRequest request = method.apply(builder).build();
+
+ HttpResponse response = httpClient.send(request, bodyHandler);
+ int code = response.statusCode();
+ if (code < 200 || code > 299) {
+ throw new IllegalStateException("Bad response: " + code + " >> " + response.body());
+ }
+ consumer.accept(response, response.body());
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException(e);
+ }
+ }
+
+ public User user() {
+ AtomicReference ref = new AtomicReference<>();
+ handle(
+ "/api/user",
+ HttpRequest.Builder::GET,
+ HttpResponse.BodyHandlers.ofString(),
+ (r, b) -> {
+ try {
+ User user = MAPPER.readValue(b, User.class);
+ ref.set(user);
+ } catch (JsonProcessingException e) {
+ throw new UncheckedIOException(e);
+ }
+ });
+ return ref.get();
+ }
+
+ public QueryResult query(String query) {
+ AtomicReference ref = new AtomicReference<>();
+ handle(
+ "/api/datasources/proxy/1/api/v1/query?query=" + query,
+ HttpRequest.Builder::GET,
+ HttpResponse.BodyHandlers.ofString(),
+ (r, b) -> {
+ try {
+ QueryResult result = MAPPER.readValue(b, QueryResult.class);
+ ref.set(result);
+ } catch (JsonProcessingException e) {
+ throw new UncheckedIOException(e);
+ }
+ });
+ return ref.get();
+ }
+}
+
+----
diff --git a/_versions/main/guides/observability-devservices.adoc b/_versions/main/guides/observability-devservices.adoc
new file mode 100644
index 0000000000..e906b22741
--- /dev/null
+++ b/_versions/main/guides/observability-devservices.adoc
@@ -0,0 +1,42 @@
+////
+This guide is maintained in the main Quarkus repository
+and pull requests should be submitted there:
+https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
+////
+= Observability Dev Services
+include::_attributes.adoc[]
+:categories: observability,devservices,telemetry,metrics,tracing,logging
+:summary: Entry point for Observability DevServices
+:topics: observability,grafana,lgtm,prometheus,victoriametrics,jaeger,otel,otlp
+:extensions: io.quarkus:quarkus-observability-devservices
+
+We are already familiar with xref:dev-services.adoc[Dev Service] concept, but in the case of Observability we need a way to orchestrate and connect more than a single dev service, usually a whole stack of them; e.g. a metrics agent periodically scraping application for metrics, pushing them into timeseries database, and Grafana feeding graphs of this timeseries data.
+
+With this in mind, we added a new concept of Dev Resource, an adapter between Dev Service concept and https://testcontainers.com/[Testcontainers]. And since we now have fine-grained services - with the Dev Resource per container, we can take this even further, allowing the user to choose the way to use this new Dev Resource concept:
+
+NOTE: Each Dev Resource implementation is an `@QuarkusTestResourceLifecycleManager` implementation as well
+
+* leave it to Dev Services to pick-up various Dev Resources from classpath, and apply xref:dev-services.adoc[Dev Service] concept to it
+
+* explicitly disable Dev Services and enable Dev Resources and use less-heavy concept of starting and stopping Dev Resources
+
+* explicitly disable both Dev Services and Dev Resources, and use Quarkus' `@QuarkusTestResource` testing concept (see Note)
+
+You can either add Observability extension dependency along with needed Dev Resources dependencies, or you use existing `sinks` - pom.xml files which add Observability extension dependency along with other required dependencies for certain technology stacks; e.g. `victoriametrics` sink would have `quarkus-observability-devresource-victoriametrics` and `quarkus-victoriametrics-client` dependencies already included in the `pom.xml`.
+
+[NOTE]
+====
+Make sure you set the `scope` of these sink dependencies to `provided`, otherwise libraries such as Testcontainers will end-up in your app's production libraries:
+[source, xml]
+----
+
+ io.quarkus
+ quarkus-observability-devservices-...
+ provided
+
+----
+====
+
+Let's see how all of this looks in practice, with the usual `all-in-one` Grafana usage, in the form of https://github.com/grafana/docker-otel-lgtm[OTel-LGTM] Docker image.
+
+* xref:observability-devservices-lgtm.adoc[Getting Started with Grafana-OTel-LGTM]
diff --git a/_versions/main/guides/opentelemetry.adoc b/_versions/main/guides/opentelemetry.adoc
index 8616bad992..5462114043 100644
--- a/_versions/main/guides/opentelemetry.adoc
+++ b/_versions/main/guides/opentelemetry.adoc
@@ -167,7 +167,21 @@ If you need to enable or disable the exporter at runtime, you can use the <