Class ExternalSourceMetrics

java.lang.Object
org.elasticsearch.xpack.esql.datasources.spi.ExternalSourceMetrics

public final class ExternalSourceMetrics extends Object
Node-level holder for the ES|QL external-data-source operational metrics, published through the node MeterRegistry (APM/OTLP) for serverless dashboards and alerts. Mirrors the RepositoriesMetrics / PlanTelemetryManager idiom: instruments are registered once in the constructor and recorded at the event.

This first cut covers the object-store read layer. The per-StorageObject StorageObjectMetricsCounters already tracks request count, request nanos, bytes read and retries for the query profile; this holder bridges those same events to the registry. The counters call recordRequest(long, long, java.lang.String) / recordRetry(java.lang.String) once a metrics holder is attached to them (see StorageObject#attachMetrics); when none is attached they use NOOP.

  • Field Details

    • STORAGE_REQUESTS_TOTAL

      public static final String STORAGE_REQUESTS_TOTAL
      One completed object-store read request on a scanned data object.
      See Also:
    • STORAGE_REQUESTS_DURATION

      public static final String STORAGE_REQUESTS_DURATION
      Wall time of a single object-store read request, in milliseconds.
      See Also:
    • STORAGE_BYTES_READ_TOTAL

      public static final String STORAGE_BYTES_READ_TOTAL
      Bytes returned by object-store reads, before decompression.
      See Also:
    • STORAGE_RETRIES_TOTAL

      public static final String STORAGE_RETRIES_TOTAL
      Automatic retries issued by the cross-provider retry decorator.
      See Also:
    • STORAGE_ERRORS_TOTAL

      public static final String STORAGE_ERRORS_TOTAL
      Object-store reads that exhausted the retry policy and gave up with a terminal failure.

      Word choice is deliberate: errors here (object-store read give-up) and failures on DISCOVERY_FAILURES_TOTAL (discovery/resolution failure) name two distinct event classes and must not be "unified" into one term — they match the source issue's taxonomy.

      See Also:
    • STORAGE_THROTTLED_TOTAL

      public static final String STORAGE_THROTTLED_TOTAL
      Object-store reads whose terminal failure was a provider throttling / rate-limit response.
      See Also:
    • STORAGE_READ_STALL_DURATION

      public static final String STORAGE_READ_STALL_DURATION
      Time an object-store read spent sleeping in retry backoff before it completed or gave up, in milliseconds.
      See Also:
    • QUERIES_TOTAL

      public static final String QUERIES_TOTAL
      One completed external-source query at the coordinator (dimensioned by OUTCOME_ATTRIBUTE). Counts queries whose ANALYZED plan contained an external source; a query that fails DURING analysis (before the external-source flag is set) is not attributed here — its discovery failure is captured by DISCOVERY_FAILURES_TOTAL instead.
      See Also:
    • QUERY_DURATION

      public static final String QUERY_DURATION
      Wall time of a completed external-source query, in milliseconds.
      See Also:
    • QUERIES_CANCELLED_TOTAL

      public static final String QUERIES_CANCELLED_TOTAL
      External-source queries that ended in cancellation.
      See Also:
    • QUERIES_PARTIAL_TOTAL

      public static final String QUERIES_PARTIAL_TOTAL
      External-source queries that returned partial results.
      See Also:
    • QUERY_TIME_TO_FIRST_ROW

      public static final String QUERY_TIME_TO_FIRST_ROW
      Time from an external-source scan operator's start to its first emitted page, in milliseconds. A per-scan proxy for time-to-first-row: it is measured per scan operator (captured at operator construction, after planning and discovery), so a single query with several external-source scans records several observations.
      See Also:
    • DISCOVERY_DURATION

      public static final String DISCOVERY_DURATION
      Wall time of external-source discovery resolution per resolved path, in milliseconds. Recorded once per discovery pass, so a query with multiple comma-separated paths records several observations (not one per query). This is resolve time INCLUDING listing cache hits: on a cache hit the underlying glob expansion / listing is skipped, so the sample is a near-zero resolve time paired with the cached file/byte counts. It is therefore a resolve-cost quantity, not a pure listing-latency quantity — a bimodal distribution (cheap hits, expensive misses) is expected.
      See Also:
    • DISCOVERY_FILES_SCANNED

      public static final String DISCOVERY_FILES_SCANNED
      Number of files discovered by external-source listing per resolved path (a query may resolve several).
      See Also:
    • DISCOVERY_BYTES_SCANNED

      public static final String DISCOVERY_BYTES_SCANNED
      Estimated bytes across the files discovered by external-source listing per resolved path (a query may resolve several).
      See Also:
    • DISCOVERY_FAILURES_TOTAL

      public static final String DISCOVERY_FAILURES_TOTAL
      External-source discovery attempts that failed to resolve.
      See Also:
    • PARSE_ROWS_TOTAL

      public static final String PARSE_ROWS_TOTAL
      Rows parsed out of a format reader by the external-source scan operator.
      See Also:
    • PARSE_DURATION

      public static final String PARSE_DURATION
      Cumulative reader-thread time an external-source scan operator spent reading and parsing an object, in milliseconds — summed across parallel parse workers (FormatReaderStatus.readNanos()), not wall time.
      See Also:
    • PARSE_SPLITS_SCANNED

      public static final String PARSE_SPLITS_SCANNED
      Number of splits scanned by an external-source scan operator. A scan/parse-phase quantity — the per-operator count of splits this scan actually processed — sibling of PARSE_ROWS_TOTAL / PARSE_DURATION.
      See Also:
    • READER_POOL_REJECTED_TOTAL

      public static final String READER_POOL_REJECTED_TOTAL
      Reader-pool submissions rejected because the parsing executor was saturated.
      See Also:
    • BREAKER_TRIPPED_TOTAL

      public static final String BREAKER_TRIPPED_TOTAL
      External-source reads rejected by a circuit breaker.
      See Also:
    • SCHEME_ATTRIBUTE

      public static final String SCHEME_ATTRIBUTE
      Storage scheme dimension, normalised to one canonical token per provider via canonicalScheme(String): s3, gcs, azure, http, file.
      See Also:
    • OUTCOME_ATTRIBUTE

      public static final String OUTCOME_ATTRIBUTE
      Query-outcome dimension, a closed low-cardinality set: success, failure, cancelled.
      See Also:
    • OUTCOME_SUCCESS

      public static final String OUTCOME_SUCCESS
      Successful query outcome.
      See Also:
    • OUTCOME_FAILURE

      public static final String OUTCOME_FAILURE
      Failed query outcome (non-cancellation error).
      See Also:
    • OUTCOME_CANCELLED

      public static final String OUTCOME_CANCELLED
      Cancelled query outcome.
      See Also:
    • NOOP

      public static final ExternalSourceMetrics NOOP
      No-op holder backed by MeterRegistry.NOOP, used where no node registry is available (decorators with no attached holder, tests) so call sites never branch on null.
  • Constructor Details

    • ExternalSourceMetrics

      public ExternalSourceMetrics(MeterRegistry meterRegistry)
  • Method Details

    • recordRequest

      public void recordRequest(long durationMillis, long bytes, String scheme)
      Records one completed read request: increments the request count, adds the bytes read, and observes the request duration. scheme is the raw storage scheme, canonicalised on lookup by schemeAttrs(String).

      Best-effort: an instrumentation failure is swallowed (logged at TRACE) so it can never break the caller's read/query/producer path — every public recordX method self-guards this way.

    • recordRetry

      public void recordRetry(String scheme)
      Records one automatic retry against the given storage scheme. Best-effort (self-guarded).
    • recordError

      public void recordError(String scheme)
      Records one object-store read that exhausted retries and gave up terminally on the given scheme. Best-effort (self-guarded).
    • recordThrottled

      public void recordThrottled(String scheme)
      Records one object-store read whose terminal failure was a provider throttling response on the given scheme. Best-effort (self-guarded).
    • recordReadStall

      public void recordReadStall(long millis, String scheme)
      Records the total time an object-store read spent in retry backoff on the given scheme, in milliseconds. Best-effort (self-guarded).
    • recordQuery

      public void recordQuery(String outcome, long durationMillis, boolean partial)
      Records one completed external-source query: increments QUERIES_TOTAL tagged with outcome, observes QUERY_DURATION carrying the same outcome (so latency can be split by success/failure/cancelled), and increments QUERIES_CANCELLED_TOTAL when the outcome is OUTCOME_CANCELLED and QUERIES_PARTIAL_TOTAL when partial is set.

      Attribution scope: this is only reached for queries whose ANALYZED plan contained an external source. A query that fails during analysis (before the external-source flag is set) is not counted here; its discovery failure is captured by recordDiscoveryFailure() / DISCOVERY_FAILURES_TOTAL. Best-effort (self-guarded).

    • recordTimeToFirstRow

      public void recordTimeToFirstRow(long millis, String scheme)
      Records the time from an external-source scan operator's start to its first emitted page, in milliseconds, on the given storage scheme. Best-effort (self-guarded).
    • recordDiscovery

      public void recordDiscovery(long durationMillis, long filesScanned, long bytesScanned, String scheme)
      Records one external-source discovery pass: its wall time, the file count and the estimated byte total, on the given storage scheme. Best-effort (self-guarded).
    • recordDiscoveryFailure

      public void recordDiscoveryFailure()
      Records one external-source discovery attempt that failed to resolve. Best-effort (self-guarded).
    • recordParse

      public void recordParse(long rows, long parseDurationMillis, String scheme)
      Records the rows parsed and the read/parse wall time of one external-source scan operator, in milliseconds, on the given storage scheme. Best-effort (self-guarded).
    • recordSplitsScanned

      public void recordSplitsScanned(long splits, String scheme)
      Records the number of splits scanned by one external-source scan operator, on the given storage scheme. Best-effort (self-guarded).
    • recordPoolRejected

      public void recordPoolRejected()
      Records one reader-pool submission rejected because the parsing executor was saturated. Best-effort (self-guarded).
    • recordBreakerTripped

      public void recordBreakerTripped()
      Records one external-source read rejected by a circuit breaker. Best-effort (self-guarded).
    • canonicalScheme

      public static String canonicalScheme(String scheme)
      Folds a raw storage-path scheme into the single canonical token used for the SCHEME_ATTRIBUTE dimension, so provider aliases (s3a/s3n, wasb/wasbs, https) and the bucket-prefix form (gs) do not fragment a provider across multiple metric series. Unknown schemes pass through lower-cased.