Métricas de Micrometer para Java

SE APLICA A: NoSQL

El SDK de Java para Azure Cosmos DB implementa métricas de cliente y usa Micrometer para la instrumentación en sistemas de observabilidad muy utilizados, como Prometheus. En este artículo se incluyen instrucciones y fragmentos de código para extraer métricas en Prometheus, tomadas de este ejemplo. La lista completa de métricas que proporciona el SDK se documenta aquí. Si los clientes se implementan en Azure Kubernetes Service (AKS), también puede usar el servicio administrado para Prometheus de Azure Monitor con extracción personalizada; consulte la documentación aquí.

Consumo de métricas de Prometheus

Prometheus se puede descargar aquí. Para consumir métricas de Micrometer en el SDK de Java para Azure Cosmos DB mediante Prometheus, antes hay que asegurarse de haber importado las bibliotecas necesarias tanto para el registro como para el cliente:

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
    <version>1.6.6</version>
</dependency>

<dependency>
    <groupId>io.prometheus</groupId>
    <artifactId>simpleclient_httpserver</artifactId>
    <version>0.5.0</version>
</dependency>

En la aplicación, proporcione el registro de Prometheus a la configuración de telemetría. Observe que puede establecer varios umbrales de diagnóstico, lo que ayudará a limitar las métricas consumidas a las que más le interesen:

//prometheus meter registry
PrometheusMeterRegistry prometheusRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);

//provide the prometheus registry to the telemetry config
CosmosClientTelemetryConfig telemetryConfig = new CosmosClientTelemetryConfig()
        .diagnosticsThresholds(
                new CosmosDiagnosticsThresholds()
                        // Any requests that violate (are lower than) any of the below thresholds that are set
                        // will not appear in "request-level" metrics (those with "rntbd" or "gw" in their name).
                        // The "operation-level" metrics (those with "ops" in their name) will still be collected.
                        // Use this to reduce noise in the amount of metrics collected.
                        .setRequestChargeThreshold(10)
                        .setNonPointOperationLatencyThreshold(Duration.ofDays(10))
                        .setPointOperationLatencyThreshold(Duration.ofDays(10))
        )
        // Uncomment below to apply sampling to help further tune client-side resource consumption related to metrics.
        // The sampling rate can be modified after Azure Cosmos DB Client initialization – so the sampling rate can be
        // modified without any restarts being necessary.
        //.sampleDiagnostics(0.25)
        .clientCorrelationId("samplePrometheusMetrics001")
        .metricsOptions(new CosmosMicrometerMetricsOptions().meterRegistry(prometheusRegistry)
                //.configureDefaultTagNames(CosmosMetricTagName.PARTITION_KEY_RANGE_ID)
                .applyDiagnosticThresholdsForTransportLevelMeters(true)
        );

Inicie el servidor de HttpServer local para exponer las métricas del Registro de medidores a Prometheus:

try {
    HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
    server.createContext("/metrics", httpExchange -> {
        String response = prometheusRegistry.scrape();
        int i = 1;
        httpExchange.sendResponseHeaders(200, response.getBytes().length);
        try (OutputStream os = httpExchange.getResponseBody()) {
            os.write(response.getBytes());
        }
    });
    new Thread(server::start).start();
} catch (IOException e) {
    throw new RuntimeException(e);
}

Asegúrese de pasar clientTelemetryConfig al crear CosmosClient:

//  Create async client
client = new CosmosClientBuilder()
    .endpoint(AccountSettings.HOST)
    .key(AccountSettings.MASTER_KEY)
    .clientTelemetryConfig(telemetryConfig)
    .consistencyLevel(ConsistencyLevel.SESSION) //make sure we can read our own writes
    .contentResponseOnWriteEnabled(true)
    .buildAsyncClient();

Al agregar el punto de conexión para el cliente de la aplicación a prometheus.yml, agregue el nombre de dominio y el puerto a "destinos". Por ejemplo, si Prometheus se ejecuta en el mismo servidor que el cliente de la aplicación, puede agregar localhost:8080 al targets como se indica a continuación:

scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: "prometheus"

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
      - targets: ["localhost:9090", "localhost:8080"]

Ahora puede consumir métricas de Prometheus:

Screenshot of metrics graph in Prometheus explorer.

Pasos siguientes