Performance Metrics - dennisholee/notes GitHub Wiki

Use Micrometer API for Performance Metrics: Create performance metrics using Micrometer’s API to ensure compatibility with monitoring systems like Prometheus, assisting SLAs for throughput and availability. SLAs Assisted: Throughput (e.g., 1000 req/s), Availability (99.9% uptime).

java

import io.micrometer.core.instrument.MeterRegistry; MeterRegistry registry; // Injected registry.counter("app.request.count").increment(); // Tracks throughput for SLA

Integrate with Spring Boot for Performance Metrics: Use spring-boot-starter-actuator to auto-configure and expose performance metrics via /actuator/prometheus, assisting SLAs for monitoring and observability. SLAs Assisted: Observability (p99 latency < 500ms).

java

// application.properties management.endpoints.web.exposure.include=metrics,prometheus // Exposes metrics for SLA monitoring

Standardize Performance Metric Names: Follow Micrometer’s convention (e.g., myapp.service.latency, lowercase, dot-separated) for consistent performance metric naming, assisting SLA tracking. SLAs Assisted: Latency (avg latency < 200ms).

java

registry.timer("myapp.service.latency", "endpoint", "/login").record(() -> process()); // Latency for SLA

Add Tags for Performance Metric Context: Include tags (e.g., endpoint=/login, topic=my-topic) for granular performance metric analysis, assisting endpoint-specific SLAs. SLAs Assisted: Endpoint latency (e.g., /login < 300ms).

java

registry.counter("api.requests.total", "endpoint", "/login", "status", "200").increment(); // Throughput by endpoint

Ensure Thread Safety for Performance Metrics: Use Micrometer’s thread-safe Counter, Timer, etc., to collect performance metrics in concurrent environments, assisting high-concurrency SLAs. SLAs Assisted: Throughput (5000 concurrent users).

java

Counter counter = registry.counter("api.calls.total"); // Thread-safe for SLA counter.increment();

Minimize Overhead for Performance Metrics: Avoid excessive performance metric creation in hot paths to reduce impact, assisting performance SLAs. SLAs Assisted: Latency (metric overhead < 1ms).

java

private final Counter requestCounter = registry.counter("api.requests.total"); // Reuse for SLA public void handleRequest() { requestCounter.increment(); }

Implement Counter for Performance Metrics: Track occurrences of performance-related events (e.g., API requests, Kafka messages) using Counter to measure throughput for SLAs. SLAs Assisted: Throughput (1000 req/s).

java

registry.counter("api.requests.count", "endpoint", "/login").increment(); // Throughput for SLA

Implement Timer for Performance Metrics: Measure duration and count of operations (e.g., method execution, Kafka processing) using Timer for latency SLAs. SLAs Assisted: Latency (p95 < 500ms).

java

registry.timer("service.process.latency", "method", "process").record(() -> service.process()); // Latency for SLA

Implement Gauge for Performance Metrics: Monitor dynamic performance metrics (e.g., queue size, active threads) using Gauge for resource usage SLAs. SLAs Assisted: Resource usage (queue size < 1000).

java

Queue queue = new LinkedList<>(); Gauge.builder("queue.size", queue, Queue::size).register(registry); // Resource usage for SLA

Implement DistributionSummary for Performance Metrics: Record distributions of performance-related values (e.g., response sizes) using DistributionSummary for payload size SLAs. SLAs Assisted: Payload size (avg response < 1MB).

java

registry.summary("response.size.bytes", "endpoint", "/data").record(response.length()); // Payload size for SLA

Annotate Methods for Performance Metrics: Use @Timed or custom annotations to collect performance metrics (e.g., latency) with Spring AOP or AspectJ, assisting latency SLAs. SLAs Assisted: Method latency (< 200ms).

java

@Timed(value = "service.process.latency", percentiles = {0.95, 0.99}) public String process(String input) { return input.toUpperCase(); } // Latency for SLA

Use AspectJ for Performance Metrics: Apply AspectJ aspects to collect performance metrics (e.g., execution time) across methods, assisting cross-cutting latency SLAs. SLAs Assisted: Latency (p99 < 1s).

java

@Aspect @Component public class MetricsAspect { private final MeterRegistry registry; public MetricsAspect(MeterRegistry registry) { this.registry = registry; } @Around("@annotation(com.example.Timed)") public Object measure(ProceedingJoinPoint joinPoint) throws Throwable { return registry.timer("custom.method.latency").record(() -> joinPoint.proceed()); // Latency for SLA } }

Manually Instrument Code for Performance Metrics: Add manual performance metrics in critical paths (e.g., Kafka consumers) to meet latency and throughput SLAs. SLAs Assisted: Kafka consumer latency (< 100ms).

java

public void consume(ConsumerRecord<String, String> record) { registry.timer("kafka.consume.latency", "topic", record.topic()) .record(() -> process(record.value())); // Consumer latency for SLA }

Configure Spring Boot for Performance Metrics: Set management.endpoints.web.exposure.include=metrics,prometheus to expose performance metrics endpoints for SLA monitoring. SLAs Assisted: Availability (99.9% uptime).

java

// application.properties management.endpoints.web.exposure.include=metrics,prometheus

Instrument Kafka Performance Metrics: Measure Kafka producer/consumer latency, throughput, and errors to meet Kafka-specific SLAs. SLAs Assisted: Kafka throughput (10,000 msg/s), Latency (< 50ms).

java

public void send(String topic, String message) { registry.timer("kafka.produce.latency", "topic", topic) .record(() -> producer.send(new ProducerRecord<>(topic, message))); // Producer latency for SLA }

Validate Performance Metric Inputs: Use Java Bean Validation to ensure performance metric names/tags are valid, assisting data integrity SLAs. SLAs Assisted: Data integrity (no invalid metrics).

java

public class MetricConfig { @NotBlank private String metricName; @NotEmpty private Map<String, String> tags; // Getters/setters } public void record(@Valid MetricConfig config) { registry.counter(config.getMetricName(), config.getTags()).increment(); // Validated metric }

Enable Percentile Performance Metrics: Configure Timer and DistributionSummary for percentiles (e.g., p95, p99) to analyze performance metric distributions for SLA compliance. SLAs Assisted: Latency (p99 < 1s).

java

Timer.builder("service.latency").publishPercentiles(0.95, 0.99).register(registry); // Percentiles for SLA

Track Error Performance Metrics: Use Counter for error rates (e.g., HTTP 500s, Kafka failures) to monitor performance issues against error SLAs. SLAs Assisted: Error rate (< 0.1%).

java

registry.counter("api.errors.total", "endpoint", "/login", "status", "500").increment(); // Error rate for SLA

Monitor Resource Performance Metrics: Collect JVM/system performance metrics (e.g., memory, threads) to meet resource usage SLAs. SLAs Assisted: Resource usage (memory < 80%).

java

registry.gauge("jvm.memory.used", ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed()); // Memory for SLA

Write Unit Tests for Performance Metrics: Verify performance metrics with JUnit 5, Hamcrest, and SimpleMeterRegistry to ensure SLA compliance. SLAs Assisted: Metric accuracy for SLA reporting.

java

@Test void testProcessMetric() { SimpleMeterRegistry registry = new SimpleMeterRegistry(); MyService service = new MyService(registry); service.process("test"); assertThat(registry.counter("service.process.count").count(), equalTo(1.0)); // Throughput test }

Mock Dependencies for Performance Metrics: Use Mockito to isolate dependencies in performance metric tests, ensuring SLA-related metrics are accurate. SLAs Assisted: Kafka throughput reliability.

java

@Test void testKafkaMetric(@Mock KafkaProducer<String, String> producer) { SimpleMeterRegistry registry = new SimpleMeterRegistry(); KafkaService service = new KafkaService(producer, registry); service.send("test-topic", "msg"); assertThat(registry.counter("kafka.produce.count").count(), equalTo(1.0)); // Producer throughput }

Test AspectJ Performance Metrics: Test AspectJ advice for performance metrics to verify latency SLAs. SLAs Assisted: Latency (p95 < 500ms).

java

@Test void testMetricsAspect(@Mock MeterRegistry registry, @Mock ProceedingJoinPoint joinPoint) throws Throwable { when(joinPoint.proceed()).thenReturn("result"); MetricsAspect aspect = new MetricsAspect(registry); aspect.measure(joinPoint); verify(registry).timer(eq("custom.method.latency"), any()); // Aspect latency }

Configure MeterRegistry for Performance Metrics: Inject MeterRegistry (e.g., PrometheusMeterRegistry) for performance metrics collection. SLAs Assisted: Latency, Throughput SLAs.

java

@Bean public MeterRegistry meterRegistry() { return new PrometheusMeterRegistry(PrometheusConfig.DEFAULT); }

Set Common Tags for Performance Metrics: Apply common tags (e.g., application=myapp) to all performance metrics for SLA context. SLAs Assisted: Application-specific SLA context.

java

registry.config().commonTags("application", "myapp");

Environment-Specific Performance Metrics: Enable/disable performance metrics collection by environment to meet testing SLAs. SLAs Assisted: SLA accuracy in test environments.

java

@Value("${metrics.enabled:true}") private boolean metricsEnabled; public void record() { if (metricsEnabled) registry.counter("example.count").increment(); // Conditional throughput }

Export Performance Metrics to Prometheus/Grafana: Ensure performance metrics are collectable by Prometheus and visualizable in Grafana for SLA analysis. SLAs Assisted: Real-time SLA monitoring.

java

// application.properties management.endpoints.web.exposure.include=prometheus // Metrics scraped by Prometheus

Define Alerts for Performance Metrics: Create alerting rules for performance metric thresholds to enforce SLAs (e.g., p99 latency > 1s). SLAs Assisted: Latency, Error SLAs.

yaml

groups:

  • name: alerts rules:
    • alert: HighLatency expr: histogram_quantile(0.99, rate(service_latency_seconds_bucket[5m])) > 1 for: 5m

Document Performance Metrics: Follow a naming standard (e.g., namespace.component.metric) and provide a developer guide for performance metrics to ensure SLA compliance. SLAs Assisted: Clear SLA tracking.

java

// README.md // Performance Metrics: namespace.component.metric (e.g., myapp.api.request.latency)

Scan Annotations for Performance Metrics: Use annotation scanning to document performance metric-related annotations (e.g., @Timed) for SLA-related methods. SLAs Assisted: Latency SLAs for annotated methods.

java

Set<Class<?>> timedClasses = AnnotationScanner.findClassesWithAnnotation( "com.example", Timed.class, ClassLoader.getSystemClassLoader()); // Find timed methods

Handle Exceptions for Performance Metrics: Catch and log performance metric recording errors to prevent application failures, ensuring SLA reliability. SLAs Assisted: Availability (99.9% uptime).

java

try { registry.counter("example.count").increment(); // Throughput metric } catch (Exception e) { log.error("Failed to record performance metric", e); }

Example Implementation java

import io.micrometer.core.annotation.Timed; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.stereotype.Service; import javax.validation.constraints.NotBlank;

@Service public class MyService { private final MeterRegistry registry;

public MyService(MeterRegistry registry) { this.registry = registry; }

@Timed(value = "service.process.latency", percentiles = {0.95, 0.99})
public String process(@NotBlank String input) {
    registry.counter("service.process.count", "input", input).increment(); // Throughput for SLA
    return input.toUpperCase();
}

}

Test java

import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*;

class MyServiceTest { private final SimpleMeterRegistry registry = new SimpleMeterRegistry(); private final MyService service = new MyService(registry);

@Test
void testProcessMetrics() {
    service.process("test");
    assertThat(registry.counter("service.process.count", "input", "test").count(), equalTo(1.0)); // Throughput for SLA
    assertThat(registry.timer("service.process.latency").totalTime(TimeUnit.MILLISECONDS), greaterThan(0.0)); // Latency for SLA
}

}

⚠️ **GitHub.com Fallback** ⚠️