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

Miretpl pushed a commit to branch v3-3-test
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/v3-3-test by this push:
     new a0050407725 [v3-3-test] Document service.name and service.instance.id 
for OpenTelemetry metrics (#71564) (#71854)
a0050407725 is described below

commit a0050407725180eb5fe64b537d33588ee510676c
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Wed Aug 19 22:55:34 2026 +0200

    [v3-3-test] Document service.name and service.instance.id for OpenTelemetry 
metrics (#71564) (#71854)
    
    * 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.
    
    
    
    * 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.
    
    
    
    * 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.
    
    
    
    * 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.
    
    
    
    * Use the same 'when' phrasing in the StatsD note
    
    
    
    ---------
    (cherry picked from commit 9b43d6abc0fc0766b1b1a886657bb6befc33ee1d)
    
    Signed-off-by: 1fanwang <[email protected]>
    Co-authored-by: Stefan Wang <[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