# cromeroprofile/spring-boot-monitoring architecture

> Architecture diagram of the GitHub repository cromeroprofile/spring-boot-monitoring, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-18). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/cromeroprofile/spring-boot-monitoring
- Repository: https://github.com/cromeroprofile/spring-boot-monitoring

## Overview

1. This repo is a small Spring Boot 3 application written in Kotlin, focused on observability rather than business logic. The only visible application source file is `KotlinMvcApplication.kt`, which suggests a thin MVC entrypoint backed mostly by framework auto-configuration.

2. The application runtime is configured through two main files:
   - `src/main/resources/application.properties` for Spring/Micrometer/Actuator behavior
   - `src/main/resources/logback-spring.xml` for log shipping and log correlation
   These two files are central to how the app emits telemetry.

3. The application’s request path is the standard Spring MVC layer: incoming HTTP traffic hits the Spring Boot app, which produces three observability signals from the same request context:
   - metrics via Actuator/Micrometer
   - distributed traces via Micrometer Tracing + Brave
   - logs via Logback with trace context injected into the log pattern

4. Metrics flow from the app to Prometheus. Spring Boot exposes an `/actuator/prometheus` endpoint, and Prometheus scrapes it according to `docker/prometheus/prometheus.yml`. The README indicates histogram/percentile data is enabled so Prometheus samples can include `trace_id`/`span_id` exemplars.

5. Traces flow from the app to Grafana Tempo. The repo uses Zipkin-compatible tracing export (`zipkin-reporter-brave` in the README) and Tempo is configured to receive Zipkin-format spans. This makes Tempo the trace store for request-level latency and span inspection.

6. Logs flow from the app to Grafana Loki. `logback-spring.xml` configures a Loki appender, and the log pattern includes labels such as application name, host, log level, class, and importantly `traceID`. That trace label is what enables log-to-trace correlation.

7. Grafana is the read side of the system. It does not collect data itself; it queries the three backends:
   - Prometheus for metrics
   - Tempo for traces
   - Loki for logs
   The provided dashboard is centered on “Logs, Traces, Metrics” as a single observability view.

8. Correlation is the key architectural idea in this repo. The same trace context is propagated across metrics, logs, and traces, so a user can move from a metric exemplar to a trace, then jump from that trace into related logs. The README explicitly frames `trace_id` as the join key across all layers.

9. `docker-compose.yml` is the infrastructure boundary for the whole stack. It starts the observability services locally, so the application and the monitoring stack can be run as a self-contained demo environment without external dependencies.

10. The configuration files under `docker/` are operationally important:
   - Grafana provisioning files prewire datasources and dashboards
   - Prometheus config defines scrape behavior
   - Tempo config defines the tracing receiver/storage behavior
   - Grafana provisioning auto-loads the dashboard and datasource setup
   This means the repo is designed for repeatable local startup, not manual UI setup.

11. The project uses Maven (`pom.xml`) as the build and dependency manager. The README highlights the key dependencies that shape architecture: Spring Boot Actuator, Micrometer Prometheus registry, Micrometer Tracing with Brave, Zipkin reporter, and Loki4j Logback appender.

12. In diagram terms, the main boundaries are:
   - client/request traffic into Spring Boot MVC
   - telemetry egress from the app to Prometheus, Tempo, and Loki
   - Grafana as the visualization/query layer over those stores
   - Docker Compose as the environment orchestrator that ties everything together

Main entry points: [`docker-compose.yml`](https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/docker-compose.yml) (Compose), [`src/main/kotlin/com/example/kotlinmvc/KotlinMvcApplication.kt`](https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/src/main/kotlin/com/example/kotlinmvc/KotlinMvcApplication.kt) (App entry), [`src/main/resources/application.properties`](https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/src/main/resources/application.properties) (App props), [`docker/grafana/provisioning/datasources/datasource.yml`](https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/docker/grafana/provisioning/datasources/datasource.yml) (Grafana datasources)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["Application"]
  node_app_main["App entry<br/>spring boot app"]
  node_mvc["Spring MVC<br/>request layer"]
  node_actuator["Actuator<br/>metrics endpoint"]
  node_tracing["Tracing<br/>micrometer-brave"]
  node_logging["Logging<br/>logback-loki"]
end

subgraph group_config["Runtime Config"]
  node_app_props["App props<br/>spring config"]
  node_logback["Logback config<br/>logging config<br/>[logback-spring.xml]"]
end

subgraph group_infra["Observability Stack"]
  node_compose{{"Compose<br/>infra orchestrator<br/>[docker-compose.yml]"}}
  node_prometheus_cfg["Prometheus cfg<br/>scrape config<br/>[prometheus.yml]"]
  node_tempo_cfg["Tempo cfg<br/>trace backend config<br/>[tempo-local.yaml]"]
  node_grafana_ds["Grafana datasources<br/>grafana provisioning<br/>[datasource.yml]"]
  node_grafana_dash["Grafana dashboard<br/>grafana provisioning"]
  node_grafana_dash_cfg["Dashboards cfg<br/>grafana provisioning<br/>[dashboard.yml]"]
  node_prometheus[("Prometheus<br/>metrics store")]
  node_tempo[("Tempo<br/>trace store")]
  node_loki[("Loki<br/>log store")]
  node_grafana["Grafana<br/>visualization"]
end

node_repo{{"Repo<br/>spring-boot-monitoring"}}
node_build["Maven<br/>build<br/>[pom.xml]"]

node_repo -->|"built with"| node_build
node_repo -->|"runs in"| node_compose
node_build -->|"packages"| node_app_main
node_compose -->|"starts"| node_prometheus
node_compose -->|"starts"| node_tempo
node_compose -->|"starts"| node_loki
node_compose -->|"starts"| node_grafana
node_compose -->|"mounts"| node_prometheus_cfg
node_compose -->|"mounts"| node_tempo_cfg
node_compose -->|"mounts"| node_grafana_ds
node_compose -->|"mounts"| node_grafana_dash_cfg
node_compose -->|"loads"| node_grafana_dash
node_app_main -->|"handles requests"| node_mvc
node_app_main -->|"exposes metrics"| node_actuator
node_app_main -->|"creates spans"| node_tracing
node_app_main -->|"emits logs"| node_logging
node_app_props -->|"configures"| node_actuator
node_app_props -->|"configures"| node_tracing
node_logback -->|"configures"| node_logging
node_mvc -->|"scraped by"| node_prometheus
node_tracing -->|"exports to"| node_tempo
node_logging -->|"ships to"| node_loki
node_prometheus -->|"queried by"| node_grafana
node_tempo -->|"queried by"| node_grafana
node_loki -->|"queried by"| node_grafana
node_grafana_ds -->|"provisions"| node_grafana
node_grafana_dash -->|"provisions"| node_grafana

click node_build "https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/pom.xml"
click node_app_main "https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/src/main/kotlin/com/example/kotlinmvc/KotlinMvcApplication.kt"
click node_app_props "https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/src/main/resources/application.properties"
click node_logback "https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/src/main/resources/logback-spring.xml"
click node_compose "https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/docker-compose.yml"
click node_prometheus_cfg "https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/docker/prometheus/prometheus.yml"
click node_tempo_cfg "https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/docker/tempo/tempo-local.yaml"
click node_grafana_ds "https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/docker/grafana/provisioning/datasources/datasource.yml"
click node_grafana_dash "https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/docker/grafana/provisioning/dashboards/logs_traces_metrics.json"
click node_grafana_dash_cfg "https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/docker/grafana/provisioning/dashboards/dashboard.yml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app_main,node_mvc,node_actuator,node_tracing,node_logging toneBlue
class node_app_props,node_logback toneAmber
class node_compose,node_prometheus_cfg,node_tempo_cfg,node_grafana_ds,node_grafana_dash,node_grafana_dash_cfg,node_prometheus,node_tempo,node_loki,node_grafana toneMint
class node_repo,node_build toneNeutral
```

## Components

### Application

Spring Boot request path and telemetry emission

- [App entry](https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/src/main/kotlin/com/example/kotlinmvc/KotlinMvcApplication.kt): spring boot app · Thin Kotlin Spring Boot MVC entrypoint · `src/main/kotlin/com/example/kotlinmvc/KotlinMvcApplication.kt`
- **Spring MVC**: request layer · Incoming HTTP request handling and controller runtime
- **Actuator**: metrics endpoint · Exposes application and Prometheus metrics
- **Tracing**: micrometer-brave · Propagates trace context and exports spans
- **Logging**: logback-loki · Logback pipeline with trace-aware log enrichment

### Runtime Config

Application and observability configuration files

- [App props](https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/src/main/resources/application.properties): spring config · Spring and Micrometer runtime settings · `src/main/resources/application.properties`
- [Logback config](https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/src/main/resources/logback-spring.xml): logging config · Loki appender and traceId-aware log pattern · `src/main/resources/logback-spring.xml`

### Observability Stack

Local monitoring services and their wiring

- [Compose](https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/docker-compose.yml): infra orchestrator · Starts the app and observability stack locally · `docker-compose.yml`
- [Prometheus cfg](https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/docker/prometheus/prometheus.yml): scrape config · Defines scrape target and metrics collection behavior · `docker/prometheus/prometheus.yml`
- [Tempo cfg](https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/docker/tempo/tempo-local.yaml): trace backend config · Configures Zipkin-format trace ingestion and storage · `docker/tempo/tempo-local.yaml`
- [Grafana datasources](https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/docker/grafana/provisioning/datasources/datasource.yml): grafana provisioning · Auto-wires Prometheus, Tempo, and Loki connections · `docker/grafana/provisioning/datasources/datasource.yml`
- [Grafana dashboard](https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/docker/grafana/provisioning/dashboards/logs_traces_metrics.json): grafana provisioning · Preloads the Logs, Traces, Metrics dashboard · `docker/grafana/provisioning/dashboards/logs_traces_metrics.json`
- [Dashboards cfg](https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/docker/grafana/provisioning/dashboards/dashboard.yml): grafana provisioning · Enables dashboard auto-loading · `docker/grafana/provisioning/dashboards/dashboard.yml`
- **Prometheus**: metrics store · Scrapes and stores application metrics and exemplars
- **Tempo**: trace store · Stores and serves distributed traces
- **Loki**: log store · Stores application logs for correlation and search
- **Grafana**: visualization · Queries metrics, traces, and logs in one view

### Other components

- **Repo**: spring-boot-monitoring · Local demo stack for correlated logs, traces, and metrics
- [Maven](https://github.com/cromeroprofile/spring-boot-monitoring/blob/main/pom.xml): build · Project build and dependency management · `pom.xml`

## Connections

- Repo → Maven: built with · Maven manages build and dependencies
- Repo → Compose: runs in · Docker Compose defines the local demo environment
- Maven → App entry: packages · Build produces the Spring Boot application
- Compose → Prometheus: starts · Compose launches the metrics backend
- Compose → Tempo: starts · Compose launches the tracing backend
- Compose → Loki: starts · Compose launches the log backend
- Compose → Grafana: starts · Compose launches the visualization layer
- Compose → Prometheus cfg: mounts · Prometheus uses repo-provided scrape config
- Compose → Tempo cfg: mounts · Tempo uses repo-provided trace config
- Compose → Grafana datasources: mounts · Grafana loads datasources automatically
- Compose → Dashboards cfg: mounts · Grafana dashboard provisioning is enabled
- Compose → Grafana dashboard: loads · Grafana imports the bundled observability dashboard
- App entry → Spring MVC: handles requests · Spring MVC receives incoming HTTP traffic
- App entry → Actuator: exposes metrics · Actuator publishes Prometheus-friendly metrics
- App entry → Tracing: creates spans · Micrometer Tracing captures request spans
- App entry → Logging: emits logs · Logback writes trace-enriched application logs
- App props → Actuator: configures · Application properties tune actuator and metrics behavior
- App props → Tracing: configures · Application properties influence tracing export and sampling
- Logback config → Logging: configures · Logback config sets Loki appender and log pattern
- Spring MVC → Prometheus: scraped by · Prometheus collects metrics from the application endpoint
- Tracing → Tempo: exports to · Spans are sent in Zipkin-compatible format
- Logging → Loki: ships to · Logs are forwarded to Loki
- Prometheus → Grafana: queried by · Grafana reads metrics for dashboards
- Tempo → Grafana: queried by · Grafana reads traces for investigation
- Loki → Grafana: queried by · Grafana reads logs for correlation
- Grafana datasources → Grafana: provisions · Datasource provisioning connects Grafana to backends
- Grafana dashboard → Grafana: provisions · Dashboard provisioning loads the main observability view
