This post walks through wiring up a Spring Boot app to emit metrics to Prometheus, visualise them in Grafana, ship structured logs to Elasticsearch via Logstash, and view them in Kibana — plus one alert rule to fire when error rates spike.
Pom.xml setup:
<!-- Micrometer + Prometheus registry --><dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId></dependency><!-- Actuator to expose /actuator/prometheus --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- Log4j2 (exclude default Logback) --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId></dependency>
Application properties:
spring: application: name: my-servicemanagement: endpoints: web: exposure: include: prometheus, health, info metrics: export: prometheus: enabled: true tags: application: ${spring.application.name}logging: config: classpath:log4j2.xml
This exposes the Prometheus scrape endpoint at /actuator/prometheus. Micrometer automatically tags every metric with the app name.
log4j2.xml:
<Configuration> <Appenders> <Console name="JSON" target="SYSTEM_OUT"> <JsonTemplateLayout eventTemplateUri="classpath:EcsLayout.json" /> </Console> </Appenders> <Loggers> <Root level="INFO"> <AppenderRef ref="JSON" /> </Root> </Loggers></Configuration>
Using JsonTemplateLayout with the built-in ECS template emits structured JSON that Logstash can parse with zero extra config. Add log4j-layout-template-json to your pom if needed.
Simple Controller in Java:
@Servicepublic class OrderService { private final Counter orderCounter; private static final Logger log = LogManager.getLogger(OrderService.class); public OrderService(MeterRegistry registry) { orderCounter = Counter.builder("orders.created") .description("Total orders placed") .register(registry); } public void placeOrder(Order order) { orderCounter.increment(); log.info("Order placed", StructuredArguments.keyValue("orderId", order.getId())); }}
Prometheus scrape config:
scrape_configs: - job_name: my-service metrics_path: /actuator/prometheus static_configs: - targets: ['localhost:8080']
example Grafana alert which fires when the HTTP 5xx error rate exceeds 5 % over the last 5 minutes.
# PromQL query for the alert conditionsum(rate(http_server_requests_seconds_count{ application="my-service", status=~"5.."}[5m]))/sum(rate(http_server_requests_seconds_count{ application="my-service"}[5m]))> 0.05
minimal logstash.conf. Pipe your app’s stdout into Logstash (or use Filebeat). Kibana will auto-discover the index pattern my-service-logs-*.
input { stdin {} }filter { json { source => "message" } }output { elasticsearch { hosts => ["http://localhost:9200"] index => "my-service-logs-%{+YYYY.MM.dd}" }}
- Metrics — Spring Boot Actuator + Micrometer exposes
/actuator/prometheusfor Prometheus to scrape, then Grafana queries Prometheus. - Logs — Log4j2 with
JsonTemplateLayout(ECS format) writes structured JSON to stdout → Logstash → Elasticsearch → Kibana. - Alert — a single PromQL rule in Grafana fires when HTTP 5xx errors exceed 5% over 5 minutes.

Hinterlasse einen Kommentar