This is an automated email from the ASF dual-hosted git repository.

Miretpl pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 9b43d6abc0f Document service.name and service.instance.id for 
OpenTelemetry metrics (#71564)
9b43d6abc0f is described below

commit 9b43d6abc0fc0766b1b1a886657bb6befc33ee1d
Author: Stefan Wang <[email protected]>
AuthorDate: Wed Aug 19 13:38:37 2026 -0700

    Document service.name and service.instance.id for OpenTelemetry metrics 
(#71564)
    
    * Document how to separate metrics from replicated Airflow components
    
    Every Airflow process reports the same service.name, so in HA the
    schedulers publish the same gauge series and the backend keeps whichever
    export landed last. Setting service.instance.id per replica already fixes
    this, but nothing in the metrics docs says so.
    
    Signed-off-by: 1fanwang <[email protected]>
    
    * Cover both service.name and service.instance.id, nest under OpenTelemetry
    
    Frame the section around identifying a metric's source rather than around 
the
    collision that motivated it: service.name says which component reports, and
    service.instance.id says which instance of it, so both are needed and each 
has
    its own environment variable.
    
    Make it a subsection of Setup - OpenTelemetry, since it only applies there, 
and
    move the StatsD caveat to the StatsD section where a StatsD user will meet 
it.
    
    Name the job label alongside instance, and drop the claim that one backend
    implements the Prometheus compatibility spec.
    
    Signed-off-by: 1fanwang <[email protected]>
    
    * Describe processes rather than replicas, and state the defaults
    
    Airflow processes running the same component are independent, with no
    leader-follower relationship, so calling them replicas describes something 
the
    deployment does not have. Talk about components and their processes instead.
    
    Say what each attribute defaults to and what that costs: service.name is
    airflow for every process, so a scheduler, a triggerer and a worker arrive
    under one name, and service.instance.id is unset, so processes running one
    component cannot be told apart. Distinguishing components is useful on its 
own,
    independently of running several of any one of them.
    
    Signed-off-by: 1fanwang <[email protected]>
    
    * Cover scheduler HA in the StatsD note and tighten the wording
    
    Every scheduler emits pool gauges under the same StatsD series, so with
    more than one the server keeps whichever value arrived last. Say so in
    the StatsD note rather than only pointing at OpenTelemetry.
    
    Signed-off-by: 1fanwang <[email protected]>
    
    * Use the same 'when' phrasing in the StatsD note
    
    Signed-off-by: 1fanwang <[email protected]>
    
    ---------
    
    Signed-off-by: 1fanwang <[email protected]>
---
 .../logging-monitoring/metrics.rst                 | 53 ++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git 
a/airflow-core/docs/administration-and-deployment/logging-monitoring/metrics.rst
 
b/airflow-core/docs/administration-and-deployment/logging-monitoring/metrics.rst
index af0fa6e300b..d3b9e2da3d4 100644
--- 
a/airflow-core/docs/administration-and-deployment/logging-monitoring/metrics.rst
+++ 
b/airflow-core/docs/administration-and-deployment/logging-monitoring/metrics.rst
@@ -53,6 +53,14 @@ custom StatsD client. This module must be available on your 
:envvar:`PYTHONPATH`
 
 See :doc:`../modules_management` for details on how Python and Airflow manage 
modules.
 
+.. note::
+
+    StatsD has no resource concept, so metrics cannot be attributed to the 
process that
+    produced them. When several processes run the same component, such as 
schedulers in high
+    availability, each exports the same series and the server keeps whichever 
value arrived last.
+    Use OpenTelemetry to tell them apart, as described in
+    :ref:`identifying-components-and-their-instances`.
+
 
 Setup - OpenTelemetry
 ---------------------
@@ -98,6 +106,51 @@ Add the Collector details to your configuration file e.g. 
``airflow.cfg``
     `SDK environment variable documentation 
<https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#periodic-exporting-metricreader>`_
 for more information.
 
 
+.. _identifying-components-and-their-instances:
+
+Identifying components and their instances
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+OpenTelemetry labels each metric with the resource that produced it. Two 
resource attributes
+decide how much of a deployment can be told apart:
+
+``service.name``
+    Which component reported the metric. It defaults to ``airflow`` for every 
Airflow process, so
+    a scheduler, a triggerer and a worker arrive under one name. Set it per 
component to attribute
+    a metric to the kind of process that produced it.
+
+``service.instance.id``
+    Which process of that component reported the metric. It is unset by 
default, so processes
+    running the same component (e.g. 2+ schedulers) are indistinguishable. Set 
it per process
+    to attribute a metric to one of them.
+
+Airflow reads ``service.name`` from ``OTEL_SERVICE_NAME``, and every other 
resource attribute from
+``OTEL_RESOURCE_ATTRIBUTES``:
+
+.. code-block:: bash
+
+    # on one of the schedulers
+    export OTEL_SERVICE_NAME="airflow-scheduler"
+    export OTEL_RESOURCE_ATTRIBUTES="service.instance.id=$(hostname)"
+
+Processes that share a resource also share a series, and the backend keeps 
whichever export
+arrived last. When several processes run the same component, data are lost 
instead of aggregated:
+each scheduler samples the metadata database on its own loop, so a gauge such 
as
+``pool.open_slots`` reports an arbitrary scheduler's sample rather than a 
value derived from all
+of them.
+
+Once each process is identified, its samples form their own series and can be 
combined
+deliberately — for example, the lowest number of open slots any scheduler 
observed:
+
+.. code-block:: text
+
+    min by (pool_name) (airflow_pool_open_slots)
+
+How the attributes surface depends on the backend. Those implementing the 
OpenTelemetry
+`Prometheus compatibility 
<https://opentelemetry.io/docs/specs/otel/compatibility/prometheus_and_openmetrics/>`_
+spec expose them as the ``job`` and ``instance`` labels.
+
+
 Enable Https
 -----------------
 

Reply via email to