Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 28 additions & 10 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -87,20 +87,23 @@ configurations {

repositories {
mavenCentral()
maven { url = uri("https://repo.spring.io/milestone") }
}

dependencies {

developmentOnly(libs.bundles.spring.boot.dev)
developmentOnly(libs.spring.boot.docker.compose)
developmentOnly(libs.spring.ai.spring.boot.docker.compose) {
exclude(group = "org.springframework.boot", module = "spring-boot-starter-mongodb")
}

implementation(libs.spring.boot.starter.web)
implementation(libs.spring.boot.starter.webmvc)
implementation(libs.spring.boot.starter.json)
implementation(libs.spring.boot.starter.actuator)
implementation(libs.spring.boot.starter.aop)
implementation(libs.spring.ai.starter.mcp.server.webmvc)
implementation(libs.solr.solrj)
implementation(libs.commons.csv)
// JSpecify for nullability annotations
implementation(libs.jspecify)

implementation(platform("io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom:2.11.0"))
implementation("io.opentelemetry.instrumentation:opentelemetry-spring-boot-starter")
Expand All @@ -113,6 +116,15 @@ dependencies {
implementation(libs.spring.boot.starter.security)
implementation(libs.spring.boot.starter.oauth2.resource.server)

// OpenTelemetry (HTTP mode only - for metrics, tracing, and log export)
implementation(libs.spring.boot.starter.opentelemetry)
implementation(libs.opentelemetry.logback.appender)
implementation("io.micrometer:micrometer-tracing-bridge-otel")
runtimeOnly(libs.micrometer.registry.otlp)

// AspectJ (required for @Observed annotation support in Spring Boot 4)
implementation(libs.spring.boot.starter.aspectj)

// Error Prone and NullAway for null safety analysis
errorprone(libs.errorprone.core)
errorprone(libs.nullaway)
Expand All @@ -127,6 +139,18 @@ dependencyManagement {
}
}

// Force opentelemetry-proto to a version compiled with protobuf 3.x
// This resolves NoSuchMethodError with protobuf 4.x
// See: https://github.com/micrometer-metrics/micrometer/issues/5658
configurations.all {
resolutionStrategy.eachDependency {
if (requested.group == "io.opentelemetry.proto" && requested.name == "opentelemetry-proto") {
useVersion("1.3.2-alpha")
because("Version 1.8.0-alpha has protobuf 4.x incompatibility causing NoSuchMethodError")
}
}
}

// Configures Spring Boot plugin to generate build metadata at build time
// This creates META-INF/build-info.properties containing:
// - build.artifact: The artifact name (e.g., "solr-mcp")
Expand Down Expand Up @@ -417,12 +441,6 @@ jib {
environment =
mapOf(
// Disable Spring Boot Docker Compose support when running in container
// Docker Compose integration is disabled in the container image.
// It is only useful for local development (HTTP profile) where
// the host has Docker and a compose.yaml. Inside a container,
// Docker Compose cannot start sibling containers without a
// Docker socket mount, so it must be turned off.
// The application-stdio.properties also disables it for STDIO mode.
"SPRING_DOCKER_COMPOSE_ENABLED" to "false",
)

Expand Down
46 changes: 26 additions & 20 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,33 @@ services:
environment:
ZOO_4LW_COMMANDS_WHITELIST: "mntr,conf,ruok"

# =============================================================================
# LGTM Stack - Grafana observability backend (Loki, Grafana, Tempo, Mimir)
# =============================================================================
# This all-in-one container provides:
# - Loki: Log aggregation (LogQL queries)
# - Grafana: Visualization at http://localhost:3000 (no auth required)
# - Tempo: Distributed tracing (TraceQL queries)
# - Mimir: Prometheus-compatible metrics storage
# - OpenTelemetry Collector: Receives OTLP data on ports 4317 (gRPC) and 4318 (HTTP)
#
# Spring Boot auto-configures OTLP endpoints when this container is running.
# =============================================================================
# OpenTelemetry LGTM Stack (HTTP mode only)
# =============================================================================
# Provides a complete observability stack for local development:
# - Grafana: Visualization dashboards (http://localhost:3000)
# - Loki: Log aggregation
# - Tempo: Distributed tracing
# - Mimir: Metrics storage (Prometheus-compatible)
# - OpenTelemetry Collector: Receives OTLP data on ports 4317 (gRPC) and 4318 (HTTP)
#
# Usage:
# docker compose up -d lgtm # Start only the observability stack
# docker compose up -d # Start everything including Solr
#
# Access Grafana at http://localhost:3000 (no authentication required)
# Pre-configured datasources for Loki, Tempo, and Mimir are available.
lgtm:
image: grafana/otel-lgtm:latest
ports:
- "3000:3000" # Grafana UI
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver
networks: [ search ]
labels:
# Prevent Spring Boot auto-configuration from trying to manage this service
org.springframework.boot.ignore: "true"
image: grafana/otel-lgtm:latest
ports:
- "3000:3000" # Grafana UI
- "4317:4317" # OTLP gRPC receiver
- "4318:4318" # OTLP HTTP receiver
networks: [ search ]
environment:
# Disable authentication for local development
GF_AUTH_ANONYMOUS_ENABLED: "true"
GF_AUTH_ANONYMOUS_ORG_ROLE: "Admin"

volumes:
data:
Expand Down
Loading