CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-dropwizard--dropwizard-project

Java framework for developing ops-friendly, high-performance, RESTful web applications

Pending
Overview
Eval results
Files

metrics.mddocs/

Metrics and Monitoring

Built-in application metrics collection, health checks, and operational endpoints for production monitoring and observability.

Capabilities

Metric Registry

Central registry for collecting and managing application metrics including timers, counters, meters, histograms, and gauges.

package com.codahale.metrics;

public class MetricRegistry {
    /**
     * Creates or retrieves a timer metric.
     */
    public Timer timer(String name);
    
    /**
     * Creates or retrieves a counter metric.
     */
    public Counter counter(String name);
    
    /**
     * Creates or retrieves a meter metric.
     */
    public Meter meter(String name);
    
    /**
     * Creates or retrieves a histogram metric.
     */
    public Histogram histogram(String name);
    
    /**
     * Registers a gauge metric.
     */
    public <T> Gauge<T> register(String name, Gauge<T> gauge);
    
    /**
     * Returns all registered metrics.
     */
    public Map<String, Metric> getMetrics();
    
    /**
     * Removes a metric from the registry.
     */
    public boolean remove(String name);
}

Usage Example:

@Override
public void run(MyConfiguration configuration, Environment environment) {
    final MetricRegistry metrics = environment.metrics();
    
    // Create metrics
    final Timer requestTimer = metrics.timer("requests");
    final Counter activeUsers = metrics.counter("active-users");
    final Meter errorRate = metrics.meter("errors");
    
    // Register a gauge
    metrics.register("queue-size", new Gauge<Integer>() {
        @Override
        public Integer getValue() {
            return messageQueue.size();
        }
    });
}

Metric Annotations

Annotations for automatically collecting metrics on methods and classes without manual instrumentation.

package com.codahale.metrics.annotation;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Timed {
    /**
     * The name of the timer metric.
     */
    String name() default "";
    
    /**
     * Whether the timer should be absolute or relative to the class.
     */
    boolean absolute() default false;
}

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Metered {
    /**
     * The name of the meter metric.
     */
    String name() default "";
    
    /**
     * Whether the meter should be absolute or relative to the class.
     */
    boolean absolute() default false;
}

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Counted {
    /**
     * The name of the counter metric.
     */
    String name() default "";
    
    /**
     * Whether the counter should be absolute or relative to the class.
     */
    boolean absolute() default false;
    
    /**
     * Whether the counter should be monotonic (always incrementing).
     */
    boolean monotonic() default false;
}

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExceptionMetered {
    /**
     * The name of the exception meter metric.
     */
    String name() default "";
    
    /**
     * Whether the meter should be absolute or relative to the class.
     */
    boolean absolute() default false;
    
    /**
     * The cause of the exception to meter.
     */
    Class<? extends Throwable> cause() default Exception.class;
}

Usage Example:

@Path("/users")
public class UserResource {
    
    @GET
    @Timed(name = "get-users-timer")
    @Metered(name = "get-users-requests")
    public List<User> getUsers() {
        return userService.findAll();
    }
    
    @POST
    @Timed
    @ExceptionMetered
    public User createUser(@Valid User user) {
        return userService.create(user);
    }
    
    @GET
    @Path("/{id}")
    @Counted(name = "user-lookups", monotonic = true)
    public Optional<User> getUser(@PathParam("id") Long id) {
        return userService.findById(id);
    }
}

Health Checks

Health check system for monitoring application and dependency health with detailed status reporting.

package com.codahale.metrics.health;

public abstract class HealthCheck {
    /**
     * Performs the health check and returns the result.
     */
    protected abstract Result check() throws Exception;
    
    /**
     * Returns a healthy result with an optional message.
     */
    protected static Result healthy();
    protected static Result healthy(String message);
    protected static Result healthy(String message, Object... args);
    
    /**
     * Returns an unhealthy result with a message.
     */
    protected static Result unhealthy(String message);
    protected static Result unhealthy(String message, Object... args);
    protected static Result unhealthy(Throwable error);
    
    public static class Result {
        public boolean isHealthy();
        public String getMessage();
        public Throwable getError();
    }
}

public class HealthCheckRegistry {
    /**
     * Registers a health check.
     */
    public void register(String name, HealthCheck healthCheck);
    
    /**
     * Runs all registered health checks.
     */
    public Map<String, HealthCheck.Result> runHealthChecks();
    
    /**
     * Runs a specific health check.
     */
    public HealthCheck.Result runHealthCheck(String name);
}

Usage Example:

public class DatabaseHealthCheck extends HealthCheck {
    private final DataSource dataSource;
    
    public DatabaseHealthCheck(DataSource dataSource) {
        this.dataSource = dataSource;
    }
    
    @Override
    protected Result check() throws Exception {
        try (Connection connection = dataSource.getConnection()) {
            if (connection.isValid(5)) {
                return Result.healthy("Database connection is valid");
            } else {
                return Result.unhealthy("Database connection is invalid");
            }
        } catch (SQLException e) {
            return Result.unhealthy("Cannot connect to database: %s", e.getMessage());
        }
    }
}

public class ExternalServiceHealthCheck extends HealthCheck {
    private final HttpClient httpClient;
    private final String serviceUrl;
    
    @Override
    protected Result check() throws Exception {
        try {
            Response response = httpClient.target(serviceUrl + "/health")
                                         .request()
                                         .get();
            
            if (response.getStatus() == 200) {
                return Result.healthy("External service is available");
            } else {
                return Result.unhealthy("External service returned status: %d", 
                                       response.getStatus());
            }
        } catch (Exception e) {
            return Result.unhealthy("External service is unreachable: %s", e.getMessage());
        }
    }
}

// Register health checks
@Override
public void run(MyConfiguration configuration, Environment environment) {
    environment.healthChecks().register("database", 
                                       new DatabaseHealthCheck(dataSource));
    environment.healthChecks().register("external-api", 
                                       new ExternalServiceHealthCheck(httpClient, apiUrl));
}

JVM Metrics

Built-in JVM metrics for monitoring memory usage, garbage collection, thread pools, and system resources.

package io.dropwizard.metrics.jvm;

public class JvmAttributeGaugeSet implements MetricSet {
    /**
     * JVM runtime information including name, version, vendor.
     */
}

public class MemoryUsageGaugeSet implements MetricSet {
    /**
     * Memory usage metrics for heap and non-heap memory.
     */
}

public class GarbageCollectorMetricSet implements MetricSet {
    /**
     * Garbage collection metrics including count and time.
     */
}

public class ThreadStatesGaugeSet implements MetricSet {
    /**
     * Thread state metrics including count by state.
     */
}

public class ClassLoadingGaugeSet implements MetricSet {
    /**
     * Class loading metrics including loaded and unloaded counts.
     */
}

Usage Example:

@Override
public void run(MyConfiguration configuration, Environment environment) {
    final MetricRegistry metrics = environment.metrics();
    
    // Register JVM metrics
    metrics.registerAll(new JvmAttributeGaugeSet());
    metrics.registerAll(new MemoryUsageGaugeSet());
    metrics.registerAll(new GarbageCollectorMetricSet());
    metrics.registerAll(new ThreadStatesGaugeSet());
    metrics.registerAll(new ClassLoadingGaugeSet());
}

Metrics Reporters

Built-in reporters for exporting metrics to various monitoring systems and formats.

package com.codahale.metrics;

public abstract class ScheduledReporter implements Reporter {
    /**
     * Starts the reporter with the given period.
     */
    public void start(long period, TimeUnit unit);
    
    /**
     * Stops the reporter.
     */
    public void stop();
    
    /**
     * Reports metrics once.
     */
    public void report();
    
    protected abstract void report(Map<String, Gauge> gauges,
                                  Map<String, Counter> counters,
                                  Map<String, Histogram> histograms,
                                  Map<String, Meter> meters,
                                  Map<String, Timer> timers);
}

// Built-in reporters
public class ConsoleReporter extends ScheduledReporter {
    public static Builder forRegistry(MetricRegistry registry);
}

public class CsvReporter extends ScheduledReporter {
    public static Builder forRegistry(MetricRegistry registry);
}

public class Slf4jReporter extends ScheduledReporter {
    public static Builder forRegistry(MetricRegistry registry);
}

Usage Example:

@Override
public void run(MyConfiguration configuration, Environment environment) {
    final MetricRegistry metrics = environment.metrics();
    
    // Console reporter for development
    final ConsoleReporter consoleReporter = ConsoleReporter.forRegistry(metrics)
        .convertRatesTo(TimeUnit.SECONDS)
        .convertDurationsTo(TimeUnit.MILLISECONDS)
        .build();
    consoleReporter.start(1, TimeUnit.MINUTES);
    
    // CSV reporter for file-based metrics
    final CsvReporter csvReporter = CsvReporter.forRegistry(metrics)
        .formatFor(Locale.US)
        .convertRatesTo(TimeUnit.SECONDS)
        .convertDurationsTo(TimeUnit.MILLISECONDS)
        .build(new File("metrics/"));
    csvReporter.start(30, TimeUnit.SECONDS);
    
    // SLF4J reporter for log-based metrics
    final Slf4jReporter slf4jReporter = Slf4jReporter.forRegistry(metrics)
        .outputTo(LoggerFactory.getLogger("metrics"))
        .convertRatesTo(TimeUnit.SECONDS)
        .convertDurationsTo(TimeUnit.MILLISECONDS)
        .build();
    slf4jReporter.start(5, TimeUnit.MINUTES);
}

Custom Metrics

Creating custom metrics for application-specific monitoring requirements.

// Custom gauge for dynamic values
public class QueueSizeGauge implements Gauge<Integer> {
    private final BlockingQueue<?> queue;
    
    public QueueSizeGauge(BlockingQueue<?> queue) {
        this.queue = queue;
    }
    
    @Override
    public Integer getValue() {
        return queue.size();
    }
}

// Custom health check with dependencies
public class CompositeHealthCheck extends HealthCheck {
    private final List<HealthCheck> dependencies;
    
    public CompositeHealthCheck(List<HealthCheck> dependencies) {
        this.dependencies = dependencies;
    }
    
    @Override
    protected Result check() throws Exception {
        for (HealthCheck dependency : dependencies) {
            Result result = dependency.execute();
            if (!result.isHealthy()) {
                return result;
            }
        }
        return Result.healthy("All dependencies are healthy");
    }
}

Monitoring Endpoints

Admin Interface

Built-in administrative interface providing access to metrics, health checks, and operational commands.

Default endpoints:

  • /admin/metrics - JSON metrics output
  • /admin/healthcheck - Health check results
  • /admin/ping - Simple ping endpoint
  • /admin/threads - Thread dump
  • /admin/tasks/gc - Force garbage collection

Usage Example:

@Override
public void run(MyConfiguration configuration, Environment environment) {
    // Custom admin task
    environment.admin().addTask(new EchoTask());
    
    // Custom admin servlet
    environment.admin().addServlet("custom", new CustomAdminServlet())
                       .addMapping("/admin/custom/*");
}

public class EchoTask extends PostBodyTask {
    public EchoTask() {
        super("echo");
    }
    
    @Override
    public void execute(Map<String, List<String>> parameters, 
                       String body, 
                       PrintWriter output) throws Exception {
        output.println("Echo: " + body);
    }
}

Metrics Configuration

Configuring metrics collection, reporting, and filtering through application configuration.

# Configuration example
metrics:
  frequency: 1 minute
  reporters:
    - type: console
      timeZone: UTC
      output: stdout
    - type: csv
      file: ./metrics/
    - type: graphite
      host: localhost
      port: 2003
      prefix: myapp
  jvmMetrics: true

Install with Tessl CLI

npx tessl i tessl/maven-io-dropwizard--dropwizard-project

docs

authentication.md

configuration.md

core-application.md

database.md

index.md

metrics.md

rest-api.md

testing.md

validation.md

tile.json