api-versioning
Use when versioning Spring MVC or WebFlux APIs in Spring Boot 3 / Spring Framework 6. Covers explicit URL, header, and media-type…
Use when adding Spring AI-specific model observations, token usage, latency, externally configured cost attribution, advisor telemetry, or protected prompt and completion logging. Use production-observability for general service metrics, health, logs, and OTLP setup.
Claude Code
$ npx -y skills add rrezartprebreza/spring-boot-skills --skill ai-observability --agent claude-code
Codex
$ npx skills add rrezartprebreza/spring-boot-skills --skill ai-observability -a codex -y
Cursor
$ npx skills add rrezartprebreza/spring-boot-skills --skill ai-observability -a cursor -y
Gemini CLI
$ npx skills add rrezartprebreza/spring-boot-skills --skill ai-observability -a gemini-cli -y
GitHub Copilot
$ npx skills add rrezartprebreza/spring-boot-skills --skill ai-observability -a github-copilot -y
OpenCode
$ npx skills add rrezartprebreza/spring-boot-skills --skill ai-observability -a opencode -y
Windsurf
$ npx skills add rrezartprebreza/spring-boot-skills --skill ai-observability -a windsurf -y
name: ai-observability description: > Use when adding Spring AI-specific model observations, token usage, latency, externally configured cost attribution, advisor telemetry, or protected prompt and completion logging. Use production-observability for general service metrics, health, logs, and OTLP setup.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>Spring AI 1.0+ includes built-in Micrometer instrumentation:
spring:
ai:
chat:
observations:
log-prompt: false # GA renamed include-prompt → log-prompt. true only in local dev (PII)
log-completion: false # GA renamed include-completion → log-completion
management:
metrics:
tags:
application: order-service
endpoints:
web:
exposure:
include: health,prometheus,metricsAuto-generated metrics (OpenTelemetry GenAI semantic conventions):
@Component
@RequiredArgsConstructor
public class AiMetrics {
private final MeterRegistry meterRegistry;
private final Timer.Builder promptTimer = Timer.builder("ai.prompt.latency")
.description("LLM prompt latency");
private final Counter.Builder tokenCounter = Counter.builder("ai.tokens.used")
.description("Total tokens consumed");
public <T> T track(String operation, String model, Supplier<T> call) {
return Timer.builder("ai.prompt.latency")
.tag("operation", operation)
.tag("model", model)
.register(meterRegistry)
.record(call); // record(Supplier) — recordCallable throws checked Exception
}
public void recordTokens(String operation, String model, int inputTokens, int outputTokens) {
Counter.builder("ai.tokens.used")
.tag("operation", operation)
.tag("model", model)
.tag("type", "input")
.register(meterRegistry)
.increment(inputTokens);
Counter.builder("ai.tokens.used")
.tag("operation", operation)
.tag("model", model)
.tag("type", "output")
.register(meterRegistry)
.increment(outputTokens);
}
}GA replaced the whole advisor API: `CallAroundAdvisor` → `CallAdvisor`, `AdvisedRequest` → `ChatClientRequest`, `AdvisedResponse` → `ChatClientResponse`, and `Usage.getGenerationTokens()` → `getCompletionTokens()`. Agents reliably generate the old one — it does not compile on 1.0.
@Component
public class AiAuditAdvisor implements CallAdvisor {
private static final Logger log = LoggerFactory.getLogger(AiAuditAdvisor.class);
@Override
public ChatClientResponse adviseCall(ChatClientRequest request, CallAdvisorChain chain) {
String requestId = UUID.randomUUID().toString();
long start = System.currentTimeMillis();
log.info("[AI-AUDIT] requestId={} promptLength={}",
requestId, request.prompt().getUserMessage().getText().length());
try {
ChatClientResponse response = chain.nextCall(request);
long latency = System.currentTimeMillis() - start;
ChatResponse chatResponse = response.chatResponse();
if (chatResponse != null && chatResponse.getMetadata() != null) {
Usage usage = chatResponse.getMetadata().getUsage();
log.info("[AI-AUDIT] requestId={} latencyMs={} inputTokens={} outputTokens={}",
requestId, latency,
usage.getPromptTokens(), usage.getCompletionTokens()); // GA: not getGenerationTokens()
}
return response;
} catch (Exception e) {
log.error("[AI-AUDIT] requestId={} FAILED after {}ms", requestId,
System.currentTimeMillis() - start, e);
throw e;
}
}
@Override
public String getName() { return "AiAuditAdvisor"; }
@Override
public int getOrder() { return Ordered.LOWEST_PRECEDENCE; }
}The [audit advisor template](templates/AiAuditAdvisor.java) treats telemetry as best-effort. Catch submission failures around the call to the separate async bean, as well as persistence failures inside it: a full or stopped executor can reject a task before its method runs. Use a bounded executor and monitor rejected audit tasks; do not use caller-runs when response latency must remain independent of audit storage. Store sanitized error types, not raw provider exception messages. Mandatory compliance audit records need durable delivery, not this best-effort design.
See [Spring task execution and rejection policies](https://docs.spring.io/spring-framework/reference/integration/scheduling.html).
@Entity
@Table(name = "ai_audit_log")
public class AiAuditLog {
@Id @GeneratedValue(strategy = GenerationType.UUID)
private UUID id;
private String operation;
private String model;
private int inputTokens;
private int outputTokens;
private dProduction-grade Claude Code and Codex skills for Spring Boot developers
Use when versioning Spring MVC or WebFlux APIs in Spring Boot 3 / Spring Framework 6. Covers explicit URL, header, and media-type…
Use when introducing or correcting grouped Spring Boot configuration, typed property binding, validation, profiles or secret…
Use when packaging a Spring Boot 3 application as an OCI image or GraalVM native executable. Covers buildpacks, layered images,…
Use when evolving aggregate invariants, value objects or domain events in an existing DDD-style Spring Boot 3 application, or…
Use when implementing Kafka, RabbitMQ, Pulsar, or JMS producers and consumers in Spring Boot 3. Covers event contracts,…
Use when creating database migrations, schema changes, seed data, or any SQL that modifies database structure. Covers Flyway…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.