Skip to content

Commit ea96c08

Browse files
reyangcijothomasjmacdSergeyKanzhelev
authored
Add details to Asynchronous Gauge API (open-telemetry#1703)
* add details to asynchronous gauge * Update specification/metrics/api.md Co-authored-by: Cijo Thomas <[email protected]> * Update specification/metrics/api.md Co-authored-by: Cijo Thomas <[email protected]> * Update specification/metrics/api.md Co-authored-by: Cijo Thomas <[email protected]> * Update specification/metrics/api.md Co-authored-by: Joshua MacDonald <[email protected]> Co-authored-by: Cijo Thomas <[email protected]> Co-authored-by: Joshua MacDonald <[email protected]> Co-authored-by: Sergey Kanzhelev <[email protected]>
1 parent f876bae commit ea96c08

File tree

1 file changed

+101
-1
lines changed

1 file changed

+101
-1
lines changed

specification/metrics/api.md

+101-1
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,107 @@ Example uses for Asynchronous Gauge:
557557

558558
#### Asynchronous Gauge creation
559559

560-
TODO
560+
There MUST NOT be any API for creating an Asynchronous Gauge other than with a
561+
[`Meter`](#meter). This MAY be called `CreateObservableGauge`. If strong type is
562+
desired, the client can decide the language idiomatic name(s), for example
563+
`CreateUInt64ObservableGauge`, `CreateDoubleObservableGauge`,
564+
`CreateObservableGauge<UInt64>`, `CreateObservableGauge<double>`.
565+
566+
It is highly recommended that implementations use the name `ObservableGauge`
567+
(or any language idiomatic variation, e.g. `observable_gauge`) unless there is
568+
a strong reason not to do so. Please note that the name has nothing to do with
569+
[asynchronous
570+
pattern](https://en.wikipedia.org/wiki/Asynchronous_method_invocation) and
571+
[observer pattern](https://en.wikipedia.org/wiki/Observer_pattern).
572+
573+
The API MUST accept the following parameters:
574+
575+
* The `name` of the Instrument, following the [instrument naming
576+
rule](#instrument-naming-rule).
577+
* An optional `unit of measure`, following the [instrument unit
578+
rule](#instrument-unit).
579+
* An optional `description`, following the [instrument description
580+
rule](#instrument-description).
581+
* A `callback` function.
582+
583+
The `callback` function is responsible for reporting the
584+
[Measurement](#measurement)s. It will only be called when the Meter is being
585+
observed. Individual language client SHOULD define whether this callback
586+
function needs to be reentrant safe / thread safe or not.
587+
588+
The callback function SHOULD NOT take indefinite amount of time. If multiple
589+
independent SDKs coexist in a running process, they MUST invoke the callback
590+
function(s) independently.
591+
592+
Individual language client can decide what is the idiomatic approach. Here are
593+
some examples:
594+
595+
* Return a list (or tuple, generator, enumerator, etc.) of `Measurement`s.
596+
* Use an observer result argument to allow individual `Measurement`s to be reported.
597+
598+
User code is recommended not to provide more than one `Measurement` with the
599+
same `attributes` in a single callback. If it happens, the
600+
[SDK](./README.md#sdk) can decide how to handle it. For example, during the
601+
callback invocation if two measurements `value=3.38, attributes={cpu:1, core:2}`
602+
and `value=3.51, attributes={cpu:1, core:2}` are reported, the SDK can decide to
603+
simply let them pass through (so the downstream consumer can handle
604+
duplication), drop the entire data, pick the last one, or something else. The
605+
API must treat observations from a single callback as logically taking place at
606+
a single instant, such that when recorded, observations from a single callback
607+
MUST be reported with identical timestamps.
608+
609+
The API SHOULD provide some way to pass `state` to the callback. Individual
610+
language client can decide what is the idiomatic approach (e.g. it could be an
611+
additional parameter to the callback function, or captured by the lambda
612+
closure, or something else).
613+
614+
Here are some examples that individual language client might consider:
615+
616+
```python
617+
# Python
618+
619+
def cpu_frequency_callback():
620+
# Note: in the real world these would be retrieved from the operating system
621+
return (
622+
(3.38, ("cpu", 0), ("core", 0)),
623+
(3.51, ("cpu", 0), ("core", 1)),
624+
(0.57, ("cpu", 1), ("core", 0)),
625+
(0.56, ("cpu", 1), ("core", 1)),
626+
)
627+
628+
meter.create_observable_gauge(
629+
name="cpu.frequency",
630+
description="the real-time CPU clock speed",
631+
callback=cpu_frequency_callback,
632+
unit="GHz",
633+
value_type=float)
634+
```
635+
636+
```python
637+
# Python
638+
639+
def cpu_frequency_callback(result):
640+
# Note: in the real world these would be retrieved from the operating system
641+
result.Observe(3.38, ("cpu", 0), ("core", 0))
642+
result.Observe(3.51, ("cpu", 0), ("core", 1))
643+
result.Observe(0.57, ("cpu", 1), ("core", 0))
644+
result.Observe(0.56, ("cpu", 1), ("core", 1))
645+
646+
meter.create_observable_gauge(
647+
name="cpu.frequency",
648+
description="the real-time CPU clock speed",
649+
callback=cpu_frequency_callback,
650+
unit="GHz",
651+
value_type=float)
652+
```
653+
654+
```csharp
655+
// C#
656+
657+
// A simple scenario where only one value is reported
658+
659+
meter.CreateObservableGauge<double>("temperature", () => sensor.GetTemperature());
660+
```
561661

562662
#### Asynchronous Gauge operations
563663

0 commit comments

Comments
 (0)