opentelemetry-php: Some metrics not rendered. What am I doing wrong?

Describe your environment

Hello there, It is a local environment to test the SDK, composed by Docker composer as follows:

Forget about the comments. I know they are not well, but i wrote them while learning this SDK 😃

version: '3.7'
services:
  zipkin:
    platform: &platform linux/amd64
    image: openzipkin/zipkin-slim
    ports:
    - 9411:9411
  jaeger:
    platform: *platform
    image: jaegertracing/all-in-one
    environment:
      COLLECTOR_ZIPKIN_HOST_PORT: 9412
    ports:
    - 9412:9412
    - 16686:16686
  collector:
    platform: *platform
    image: otel/opentelemetry-collector-contrib
    command: ["--config=/etc/otel-collector-config.yml"]
    volumes:
      - ./files/collector/otel-collector-config.yml:/etc/otel-collector-config.yml
    ports:
      - "1888:1888"   # pprof extension
      - "8888:8888"   # Prometheus metrics exposed by the collector
      - "8889:8889"   # Prometheus exporter metrics
      - "13133:13133" # health_check extension
      - "9411"   # Zipkin receiver
      - "4317:4317"        # OTLP gRPC receiver
      - "4318:4318" # OTLP/HTTP receiver
      - "55680:55679" # zpages extension

About the OTEL Collector configuration:

receivers:
  otlp:
    protocols:
      grpc:
      http:
  zipkin:

exporters:
  zipkin:
    endpoint: "http://zipkin:9411/api/v2/spans"

  logging:
    verbosity: detailed

  # Expose all the metrics on the collector's /metrics for better debugging before sending by remote_write
  # Ref: https://opentelemetry.io/docs/reference/specification/metrics/sdk_exporters/prometheus/
  # Ref: https://www.timescale.com/blog/prometheus-vs-opentelemetry-metrics-a-complete-guide/
  prometheus:
    endpoint: "0.0.0.0:8889"
    metric_expiration: 5m
    resource_to_telemetry_conversion:
      enabled: true

processors:
  batch:

extensions:
  health_check:
  pprof:
    endpoint: :1888
  zpages:
    endpoint: :55679

service:
  extensions: [pprof, zpages, health_check]
  telemetry:
    logs:
      level: "debug"
  pipelines:
    traces:
      receivers: [otlp, zipkin]
      processors: [batch]
      exporters: [logging]

    metrics:
      receivers: [otlp]
      processors: [batch]
      exporters: [logging, prometheus]

    logs:
      receivers: [ otlp ]
      processors: [ batch ]
      exporters: [ logging ]

And the version for PHP as follows, too:

Warning: Version warning: Imagick was compiled against ImageMagick version 1808 but version 1809 is loaded. Imagick will run but may behave surprisingly in Unknown on line 0
PHP 8.1.17 (cli) (built: Mar 16 2023 13:07:08) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.17, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.17, Copyright (c), by Zend Technologies

Steps to reproduce Basically, I modified the basic example to forward the metrics using GRPC, and to add as many as I can, just for testing. The code:

<?php

// Example based on https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/supplementary-guidelines.md#synchronous-example
declare(strict_types=1);

require_once __DIR__ . '/../../vendor/autoload.php';

# To use GRPC protocol
use OpenTelemetry\API\Common\Signal\Signals; // ok
use OpenTelemetry\Contrib\Grpc\GrpcTransportFactory; // ok
use OpenTelemetry\Contrib\Otlp\MetricExporter; // ok
use OpenTelemetry\Contrib\Otlp\OtlpUtil; // ok

#
use OpenTelemetry\API\Metrics\ObserverInterface; // ok
use OpenTelemetry\SDK\Common\Attribute\Attributes; // ok
use OpenTelemetry\SDK\Common\Instrumentation\InstrumentationScopeFactory; // ok
use OpenTelemetry\SDK\Common\Time\ClockFactory; // ok
use OpenTelemetry\SDK\Metrics\Aggregation\ExplicitBucketHistogramAggregation; // Optional
use OpenTelemetry\SDK\Metrics\Exemplar\ExemplarFilter\WithSampledTraceExemplarFilter; // ok
use OpenTelemetry\SDK\Metrics\MeterProvider; // ok
use OpenTelemetry\SDK\Metrics\MetricReader\ExportingReader; // ok
use OpenTelemetry\SDK\Metrics\StalenessHandler\ImmediateStalenessHandlerFactory; // ok
use OpenTelemetry\SDK\Metrics\View\CriteriaViewRegistry; // ok
use OpenTelemetry\SDK\Metrics\View\SelectionCriteria\InstrumentNameCriteria; // optional
use OpenTelemetry\SDK\Metrics\View\ViewTemplate; // optional
use OpenTelemetry\SDK\Resource\ResourceInfoFactory; // ok

// 1. Declare the exporter you need. By default OTLP for applications because of the performance
$clock = ClockFactory::getDefault();
$reader = new ExportingReader(
    new MetricExporter(
        (new GrpcTransportFactory())->create('http://localhost:4317' . OtlpUtil::method(Signals::METRICS))
    ),
    $clock
);

// 2. TODO
$views = new CriteriaViewRegistry();

// 2.1 Let's imagine we export the metrics as Histogram, and to simplify the story we will only have one histogram bucket (-Inf, +Inf):
// $views->register(
//     new InstrumentNameCriteria('http.server.duration'),
//     ViewTemplate::create()
//         ->withAttributeKeys(['http.method', 'http.status_code'])
//         ->withAggregation(new ExplicitBucketHistogramAggregation([])),
// );

// 3. Create a meter provider
$meterProvider = new MeterProvider(
    null,
    ResourceInfoFactory::emptyResource(), // Or the following to auto calculate useful metrics labels: ResourceInfoFactory::defaultResource(),
    $clock,
    Attributes::factory(),
    new InstrumentationScopeFactory(Attributes::factory()),
    [$reader],
    $views,
    new WithSampledTraceExemplarFilter(),
    new ImmediateStalenessHandlerFactory(),
);

// 4. Once we get the metrics provider
$meter = $meterProvider->getMeter('io.opentelemetry.contrib.php');

// 4.1 COUNTERS

// 4.1.1 Counter can be set to manually change the value
// Ref: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#updowncounter-creation
$simpleCounter = $meter->createCounter('process.counter.duration', 'ms', 'A simple counter.');
$simpleCounter->add(500, ["something" => "liked-by-you"]);
$simpleCounter->add(500, ["something" => "liked-by-you"]);
$simpleCounter->add(500, ["something" => "liked-by-you"]);
$reader->collect();

// 4.1.2 Counter can be set automatically
$observableCounter = $meter->createObservableCounter('process.counter.duration.dos', 'ms', 'An observable counter.');
$observableCounter->observe(static function (ObserverInterface $observer): void {
    $observer->observe(memory_get_usage(true));
});


// 4.2 GAUGES

// 4.2.1 Gauges can be set manually

// 4.2.2 Gauges can be set automatically
$observableGauge = $meter->createObservableGauge('name', 'unit', 'description');
$observableGauge->observe(static function (ObserverInterface $observer): void {
    $observer->observe(memory_get_usage(true));
});


// 4.3 UP-DOWN-COUNTERS

// 4.3.1 UpDownCounters can be set Manually observing a function
$upDownCounter = $meter->createUpDownCounter('process.counter.bytes', 'ms', 'A simple gauge.');
$upDownCounter->add(7000);
$upDownCounter->add(-500);
$reader->collect();

// 4.3.2 UpDownCounters can be set automatically observing a function
$observableUDCounter = $meter->createObservableUpDownCounter('process.memory.usage', 'By', 'The amount of physical memory in use.');
$observableUDCounter->observe(static function (ObserverInterface $observer): void {
    $observer->observe(memory_get_usage(true));
});


// 4.4 HISTOGRAMS

// 4.4.1 Histograms can be used too
$serverDuration = $meter->createHistogram('http.server.duration', 'ms', 'measures the duration inbound HTTP requests');

// During the time range (T0, T1]:
$serverDuration->record(50, ['http.method' => 'GET', 'http.status_code' => 200]);
$serverDuration->record(100, ['http.method' => 'GET', 'http.status_code' => 200]);
$serverDuration->record(1, ['http.method' => 'GET', 'http.status_code' => 500]);
$reader->collect();

// During the time range (T1, T2]:
$reader->collect();

// During the time range (T2, T3]:
$serverDuration->record(5, ['http.method' => 'GET', 'http.status_code' => 500]);
$serverDuration->record(2, ['http.method' => 'GET', 'http.status_code' => 500]);
$reader->collect();

// During the time range (T3, T4]:
$serverDuration->record(100, ['http.method' => 'GET', 'http.status_code' => 200]);
$reader->collect();

// During the time range (T4, T5]:
$serverDuration->record(100, ['http.method' => 'GET', 'http.status_code' => 200]);
$serverDuration->record(30, ['http.method' => 'GET', 'http.status_code' => 200]);
$serverDuration->record(50, ['http.method' => 'GET', 'http.status_code' => 200]);
$reader->collect();



//
$meterProvider->shutdown();

What is the expected behavior? I expected to see all the metrics inside OTEL logs and in /metrics too

What is the actual behavior? I can see almost all the information on logging, but some of them are not being exported in /metrics. So I suspect I am configuring the MetricsProvider os similar in a bad way, and they are being discarded in the middle of the processs.

What I see on logs:

2023-04-27T14:49:34.897Z	info	MetricsExporter	{"kind": "exporter", "data_type": "metrics", "name": "logging", "#metrics": 41}
2023-04-27T14:49:34.898Z	info	ResourceMetrics #0
Resource SchemaURL:
ScopeMetrics #0
ScopeMetrics SchemaURL:
InstrumentationScope io.opentelemetry.contrib.php
Metric #0
Descriptor:
     -> Name: process.counter.duration
     -> Description: A simple counter.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: true
     -> AggregationTemporality: Delta
NumberDataPoints #0
Data point attributes:
     -> something: Str(liked-by-you)
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.688238063 +0000 UTC
Value: 1500
ResourceMetrics #1
Resource SchemaURL:
ScopeMetrics #0
ScopeMetrics SchemaURL:
InstrumentationScope io.opentelemetry.contrib.php
Metric #0
Descriptor:
     -> Name: process.counter.duration
     -> Description: A simple counter.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: true
     -> AggregationTemporality: Delta
Metric #1
Descriptor:
     -> Name: process.counter.duration.dos
     -> Description: An observable counter.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: true
     -> AggregationTemporality: Cumulative
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.724087771 +0000 UTC
Value: 6291456
Metric #2
Descriptor:
     -> Name: name
     -> Description: description
     -> Unit: unit
     -> DataType: Gauge
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.724087771 +0000 UTC
Value: 6291456
Metric #3
Descriptor:
     -> Name: process.counter.bytes
     -> Description: A simple gauge.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: false
     -> AggregationTemporality: Delta
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.724087771 +0000 UTC
Value: 6500
ResourceMetrics #2
Resource SchemaURL:
ScopeMetrics #0
ScopeMetrics SchemaURL:
InstrumentationScope io.opentelemetry.contrib.php
Metric #0
Descriptor:
     -> Name: process.counter.duration
     -> Description: A simple counter.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: true
     -> AggregationTemporality: Delta
Metric #1
Descriptor:
     -> Name: process.counter.duration.dos
     -> Description: An observable counter.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: true
     -> AggregationTemporality: Cumulative
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.726477355 +0000 UTC
Value: 6291456
Metric #2
Descriptor:
     -> Name: name
     -> Description: description
     -> Unit: unit
     -> DataType: Gauge
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.726477355 +0000 UTC
Value: 6291456
Metric #3
Descriptor:
     -> Name: process.counter.bytes
     -> Description: A simple gauge.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: false
     -> AggregationTemporality: Delta
Metric #4
Descriptor:
     -> Name: process.memory.usage
     -> Description: The amount of physical memory in use.
     -> Unit: By
     -> DataType: Sum
     -> IsMonotonic: false
     -> AggregationTemporality: Cumulative
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.726477355 +0000 UTC
Value: 6291456
Metric #5
Descriptor:
     -> Name: http.server.duration
     -> Description: measures the duration inbound HTTP requests
     -> Unit: ms
     -> DataType: Histogram
     -> AggregationTemporality: Delta
HistogramDataPoints #0
Data point attributes:
     -> http.method: Str(GET)
     -> http.status_code: Int(200)
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.726477355 +0000 UTC
Count: 2
Sum: 150.000000
ExplicitBounds #0: 0.000000
ExplicitBounds #1: 5.000000
ExplicitBounds #2: 10.000000
ExplicitBounds #3: 25.000000
ExplicitBounds #4: 50.000000
ExplicitBounds #5: 75.000000
ExplicitBounds #6: 100.000000
ExplicitBounds #7: 250.000000
ExplicitBounds #8: 500.000000
ExplicitBounds #9: 1000.000000
Buckets #0, Count: 0
Buckets #1, Count: 0
Buckets #2, Count: 0
Buckets #3, Count: 0
Buckets #4, Count: 1
Buckets #5, Count: 0
Buckets #6, Count: 1
Buckets #7, Count: 0
Buckets #8, Count: 0
Buckets #9, Count: 0
Buckets #10, Count: 0
HistogramDataPoints #1
Data point attributes:
     -> http.method: Str(GET)
     -> http.status_code: Int(500)
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.726477355 +0000 UTC
Count: 1
Sum: 1.000000
ExplicitBounds #0: 0.000000
ExplicitBounds #1: 5.000000
ExplicitBounds #2: 10.000000
ExplicitBounds #3: 25.000000
ExplicitBounds #4: 50.000000
ExplicitBounds #5: 75.000000
ExplicitBounds #6: 100.000000
ExplicitBounds #7: 250.000000
ExplicitBounds #8: 500.000000
ExplicitBounds #9: 1000.000000
Buckets #0, Count: 0
Buckets #1, Count: 1
Buckets #2, Count: 0
Buckets #3, Count: 0
Buckets #4, Count: 0
Buckets #5, Count: 0
Buckets #6, Count: 0
Buckets #7, Count: 0
Buckets #8, Count: 0
Buckets #9, Count: 0
Buckets #10, Count: 0
ResourceMetrics #3
Resource SchemaURL:
ScopeMetrics #0
ScopeMetrics SchemaURL:
InstrumentationScope io.opentelemetry.contrib.php
Metric #0
Descriptor:
     -> Name: process.counter.duration
     -> Description: A simple counter.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: true
     -> AggregationTemporality: Delta
Metric #1
Descriptor:
     -> Name: process.counter.duration.dos
     -> Description: An observable counter.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: true
     -> AggregationTemporality: Cumulative
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.729236813 +0000 UTC
Value: 6291456
Metric #2
Descriptor:
     -> Name: name
     -> Description: description
     -> Unit: unit
     -> DataType: Gauge
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.729236813 +0000 UTC
Value: 6291456
Metric #3
Descriptor:
     -> Name: process.counter.bytes
     -> Description: A simple gauge.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: false
     -> AggregationTemporality: Delta
Metric #4
Descriptor:
     -> Name: process.memory.usage
     -> Description: The amount of physical memory in use.
     -> Unit: By
     -> DataType: Sum
     -> IsMonotonic: false
     -> AggregationTemporality: Cumulative
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.729236813 +0000 UTC
Value: 6291456
Metric #5
Descriptor:
     -> Name: http.server.duration
     -> Description: measures the duration inbound HTTP requests
     -> Unit: ms
     -> DataType: Histogram
     -> AggregationTemporality: Delta
ResourceMetrics #4
Resource SchemaURL:
ScopeMetrics #0
ScopeMetrics SchemaURL:
InstrumentationScope io.opentelemetry.contrib.php
Metric #0
Descriptor:
     -> Name: process.counter.duration
     -> Description: A simple counter.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: true
     -> AggregationTemporality: Delta
Metric #1
Descriptor:
     -> Name: process.counter.duration.dos
     -> Description: An observable counter.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: true
     -> AggregationTemporality: Cumulative
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.730979896 +0000 UTC
Value: 6291456
Metric #2
Descriptor:
     -> Name: name
     -> Description: description
     -> Unit: unit
     -> DataType: Gauge
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.730979896 +0000 UTC
Value: 6291456
Metric #3
Descriptor:
     -> Name: process.counter.bytes
     -> Description: A simple gauge.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: false
     -> AggregationTemporality: Delta
Metric #4
Descriptor:
     -> Name: process.memory.usage
     -> Description: The amount of physical memory in use.
     -> Unit: By
     -> DataType: Sum
     -> IsMonotonic: false
     -> AggregationTemporality: Cumulative
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.730979896 +0000 UTC
Value: 6291456
Metric #5
Descriptor:
     -> Name: http.server.duration
     -> Description: measures the duration inbound HTTP requests
     -> Unit: ms
     -> DataType: Histogram
     -> AggregationTemporality: Delta
HistogramDataPoints #0
Data point attributes:
     -> http.method: Str(GET)
     -> http.status_code: Int(500)
StartTimestamp: 2023-04-27 14:49:34.729236813 +0000 UTC
Timestamp: 2023-04-27 14:49:34.730979896 +0000 UTC
Count: 2
Sum: 7.000000
ExplicitBounds #0: 0.000000
ExplicitBounds #1: 5.000000
ExplicitBounds #2: 10.000000
ExplicitBounds #3: 25.000000
ExplicitBounds #4: 50.000000
ExplicitBounds #5: 75.000000
ExplicitBounds #6: 100.000000
ExplicitBounds #7: 250.000000
ExplicitBounds #8: 500.000000
ExplicitBounds #9: 1000.000000
Buckets #0, Count: 0
Buckets #1, Count: 2
Buckets #2, Count: 0
Buckets #3, Count: 0
Buckets #4, Count: 0
Buckets #5, Count: 0
Buckets #6, Count: 0
Buckets #7, Count: 0
Buckets #8, Count: 0
Buckets #9, Count: 0
Buckets #10, Count: 0
ResourceMetrics #5
Resource SchemaURL:
ScopeMetrics #0
ScopeMetrics SchemaURL:
InstrumentationScope io.opentelemetry.contrib.php
Metric #0
Descriptor:
     -> Name: process.counter.duration
     -> Description: A simple counter.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: true
     -> AggregationTemporality: Delta
Metric #1
Descriptor:
     -> Name: process.counter.duration.dos
     -> Description: An observable counter.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: true
     -> AggregationTemporality: Cumulative
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.73318848 +0000 UTC
Value: 6291456
Metric #2
Descriptor:
     -> Name: name
     -> Description: description
     -> Unit: unit
     -> DataType: Gauge
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.73318848 +0000 UTC
Value: 6291456
Metric #3
Descriptor:
     -> Name: process.counter.bytes
     -> Description: A simple gauge.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: false
     -> AggregationTemporality: Delta
Metric #4
Descriptor:
     -> Name: process.memory.usage
     -> Description: The amount of physical memory in use.
     -> Unit: By
     -> DataType: Sum
     -> IsMonotonic: false
     -> AggregationTemporality: Cumulative
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.73318848 +0000 UTC
Value: 6291456
Metric #5
Descriptor:
     -> Name: http.server.duration
     -> Description: measures the duration inbound HTTP requests
     -> Unit: ms
     -> DataType: Histogram
     -> AggregationTemporality: Delta
HistogramDataPoints #0
Data point attributes:
     -> http.method: Str(GET)
     -> http.status_code: Int(200)
StartTimestamp: 2023-04-27 14:49:34.730979896 +0000 UTC
Timestamp: 2023-04-27 14:49:34.73318848 +0000 UTC
Count: 1
Sum: 100.000000
ExplicitBounds #0: 0.000000
ExplicitBounds #1: 5.000000
ExplicitBounds #2: 10.000000
ExplicitBounds #3: 25.000000
ExplicitBounds #4: 50.000000
ExplicitBounds #5: 75.000000
ExplicitBounds #6: 100.000000
ExplicitBounds #7: 250.000000
ExplicitBounds #8: 500.000000
ExplicitBounds #9: 1000.000000
Buckets #0, Count: 0
Buckets #1, Count: 0
Buckets #2, Count: 0
Buckets #3, Count: 0
Buckets #4, Count: 0
Buckets #5, Count: 0
Buckets #6, Count: 1
Buckets #7, Count: 0
Buckets #8, Count: 0
Buckets #9, Count: 0
Buckets #10, Count: 0
ResourceMetrics #6
Resource SchemaURL:
ScopeMetrics #0
ScopeMetrics SchemaURL:
InstrumentationScope io.opentelemetry.contrib.php
Metric #0
Descriptor:
     -> Name: process.counter.duration
     -> Description: A simple counter.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: true
     -> AggregationTemporality: Delta
Metric #1
Descriptor:
     -> Name: process.counter.duration.dos
     -> Description: An observable counter.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: true
     -> AggregationTemporality: Cumulative
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.73535773 +0000 UTC
Value: 6291456
Metric #2
Descriptor:
     -> Name: name
     -> Description: description
     -> Unit: unit
     -> DataType: Gauge
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.73535773 +0000 UTC
Value: 6291456
Metric #3
Descriptor:
     -> Name: process.counter.bytes
     -> Description: A simple gauge.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: false
     -> AggregationTemporality: Delta
Metric #4
Descriptor:
     -> Name: process.memory.usage
     -> Description: The amount of physical memory in use.
     -> Unit: By
     -> DataType: Sum
     -> IsMonotonic: false
     -> AggregationTemporality: Cumulative
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.73535773 +0000 UTC
Value: 6291456
Metric #5
Descriptor:
     -> Name: http.server.duration
     -> Description: measures the duration inbound HTTP requests
     -> Unit: ms
     -> DataType: Histogram
     -> AggregationTemporality: Delta
HistogramDataPoints #0
Data point attributes:
     -> http.method: Str(GET)
     -> http.status_code: Int(200)
StartTimestamp: 2023-04-27 14:49:34.73318848 +0000 UTC
Timestamp: 2023-04-27 14:49:34.73535773 +0000 UTC
Count: 3
Sum: 180.000000
ExplicitBounds #0: 0.000000
ExplicitBounds #1: 5.000000
ExplicitBounds #2: 10.000000
ExplicitBounds #3: 25.000000
ExplicitBounds #4: 50.000000
ExplicitBounds #5: 75.000000
ExplicitBounds #6: 100.000000
ExplicitBounds #7: 250.000000
ExplicitBounds #8: 500.000000
ExplicitBounds #9: 1000.000000
Buckets #0, Count: 0
Buckets #1, Count: 0
Buckets #2, Count: 0
Buckets #3, Count: 0
Buckets #4, Count: 2
Buckets #5, Count: 0
Buckets #6, Count: 1
Buckets #7, Count: 0
Buckets #8, Count: 0
Buckets #9, Count: 0
Buckets #10, Count: 0
ResourceMetrics #7
Resource SchemaURL:
ScopeMetrics #0
ScopeMetrics SchemaURL:
InstrumentationScope io.opentelemetry.contrib.php
Metric #0
Descriptor:
     -> Name: process.counter.duration
     -> Description: A simple counter.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: true
     -> AggregationTemporality: Delta
Metric #1
Descriptor:
     -> Name: process.counter.duration.dos
     -> Description: An observable counter.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: true
     -> AggregationTemporality: Cumulative
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.737409271 +0000 UTC
Value: 6291456
Metric #2
Descriptor:
     -> Name: name
     -> Description: description
     -> Unit: unit
     -> DataType: Gauge
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.737409271 +0000 UTC
Value: 6291456
Metric #3
Descriptor:
     -> Name: process.counter.bytes
     -> Description: A simple gauge.
     -> Unit: ms
     -> DataType: Sum
     -> IsMonotonic: false
     -> AggregationTemporality: Delta
Metric #4
Descriptor:
     -> Name: process.memory.usage
     -> Description: The amount of physical memory in use.
     -> Unit: By
     -> DataType: Sum
     -> IsMonotonic: false
     -> AggregationTemporality: Cumulative
NumberDataPoints #0
StartTimestamp: 2023-04-27 14:49:34.686599105 +0000 UTC
Timestamp: 2023-04-27 14:49:34.737409271 +0000 UTC
Value: 6291456
Metric #5
Descriptor:
     -> Name: http.server.duration
     -> Description: measures the duration inbound HTTP requests
     -> Unit: ms
     -> DataType: Histogram
     -> AggregationTemporality: Delta
	{"kind": "exporter", "data_type": "metrics", "name": "logging"}
2023-04-27T14:49:42.212Z	debug	prometheusexporter@v0.75.0/collector.go:371	collect called	{"kind": "exporter", "data_type": "metrics", "name": "prometheus"}
2023-04-27T14:49:42.212Z	debug	prometheusexporter@v0.75.0/accumulator.go:279	Accumulator collect called	{"kind": "exporter", "data_type": "metrics", "name": "prometheus"}
2023-04-27T14:49:42.212Z	debug	prometheusexporter@v0.75.0/collector.go:395	metric served: Desc{fqName: "name", help: "description", constLabels: {}, variableLabels: []}	{"kind": "exporter", "data_type": "metrics", "name": "prometheus"}
2023-04-27T14:49:42.212Z	debug	prometheusexporter@v0.75.0/collector.go:395	metric served: Desc{fqName: "process_counter_duration", help: "A simple counter.", constLabels: {}, variableLabels: [something]}	{"kind": "exporter", "data_type": "metrics", "name": "prometheus"}
2023-04-27T14:49:42.212Z	debug	prometheusexporter@v0.75.0/collector.go:395	metric served: Desc{fqName: "process_memory_usage", help: "The amount of physical memory in use.", constLabels: {}, variableLabels: []}	{"kind": "exporter", "data_type": "metrics", "name": "prometheus"}
2023-04-27T14:49:42.212Z	debug	prometheusexporter@v0.75.0/collector.go:395	metric served: Desc{fqName: "process_counter_duration_dos", help: "An observable counter.", constLabels: {}, variableLabels: []}	{"kind": "exporter", "data_type": "metrics", "name": "prometheus"}

And what I see on /metrics

# HELP name description
# TYPE name gauge
name 6.291456e+06
# HELP process_counter_duration A simple counter.
# TYPE process_counter_duration counter
process_counter_duration{something="liked-by-you"} 1500
# HELP process_counter_duration_dos An observable counter.
# TYPE process_counter_duration_dos counter
process_counter_duration_dos 6.291456e+06
# HELP process_memory_usage The amount of physical memory in use.
# TYPE process_memory_usage gauge
process_memory_usage 6.291456e+06

Some of them are being clearly discarded like the histogram, and some others. So the question: what am I doing bad at code level? can it be a bug on the SDK? 😃

Additional context Add any other context about the problem here.

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 15 (1 by maintainers)

Most upvoted comments

@achetronic new releases available now.

When it is expected to have a release with all the improvements?

Let’s say in the next couple of days. Hopefully a few PRs get approved and merged after our weekly meeting which is in a few hours.

@achetronic #990 adds that env var, thanks for pointing out that it was missing in our implementation.

Hi @achetronic it was auto-closed because a related PR (#987) was merged (which I assume Nevay was confident would fix the issue). That fix is not yet in any released version, so can you try it against sdk dev-main ? If you still think it’s broken with the latest code, feel free to re-open.

Hello @brettmc thank for your response! 🙏🏼

I thought the beta8 was released with that change, but you are completely right the changes are in dev-main so tested against. It is a bit “difficult” because in composer you would need:

"open-telemetry/api": "^1.0",
"open-telemetry/exporter-otlp": "^1.0",
"open-telemetry/sdk": "dev-main",
"open-telemetry/transport-grpc": "^1.0",

and the version matrix is not compatible. But I left like the following, AND replaced directly the content of vendor/open-telemetry/sdk with the content of dev-main from the repository, just for testing

"open-telemetry/api": "^1.0",
"open-telemetry/exporter-otlp": "^1.0",
"open-telemetry/sdk": "^1.0",
"open-telemetry/transport-grpc": "^1.0",

With the latest changes, I confirm It send more metrics in a consistent way


Regarding to the detectors, I found that env variable quite useful for Kubernetes environments with autoscaler deployed, to disable some of the detectors not to increase too much the cardinality of the metrics with no sense, thank you!


But there are a last “uncomfortable” thing on auto-instrumentation (this applies for PHP pure applications, and for symfony too). To enable Temporality::CUMULATIVE on auto-instrumentation, it’s needed to craft the ExportingReader again, and re-configure the SDK, etc. IMHO, it is not full auto-instrumentation, then. For example, with auto-instrumentation on Symfony, it should be only needed to add some lines to the config/services.yaml as follows:

# ...
    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/'
        exclude:
            - '../src/DependencyInjection/'
            - '../src/Entity/'
            - '../src/Kernel.php'
        properties:
            instrumentation: '@OpenTelemetry\API\Common\Instrumentation\CachedInstrumentation'

    # add more service definitions when explicit configuration is needed
    # please note that last definitions always *replace* previous ones
    # ---
    # Load the instrumentation library
    OpenTelemetry\API\Common\Instrumentation\CachedInstrumentation:
        public: true
        class: \OpenTelemetry\API\Common\Instrumentation\CachedInstrumentation
        arguments:
            $name: "io.opentelemetry.contrib.php"

I noticed from the OTEL Python SDK, there is an environment variable called OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE to define exactly this. Because it is more or less the only thing still needed to be defined on MeterProvider (I see the rest of the parameters are configured with reasonable defaults)

🙏🏼 Is it possible to add this environment variable to PHP SDK? I think it would be nice to have it here just for those Symfony projects out there. If not, it is still needed to modify the Kernel.php to add all the configuration (for Laravel the configuration of SDK can be covered without modifying core features or breaking framework patterns)

@Nevay Last question:

When we create auto instrumentation this way:

$instrumentation = new \OpenTelemetry\API\Common\Instrumentation\CachedInstrumentation('demo');

Is there a way to avoid to include SDK attributes?

counter_sample{host_arch="arm64",host_name="albyhernandezs-MacBook-Pro.local",job="unknown_service",os_description="22.1.0",os_name="Darwin",os_type="darwin",os_version="Darwin Kernel Version 22.1.0: Sun Oct  9 20:15:09 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T6000",process_command="src/metrics-autoload-sdk.php",process_command_args="[\"src/metrics-autoload-sdk.php\"]",process_executable_path="/opt/homebrew/Cellar/php@8.1/8.1.17/bin/php",process_owner="alby.hernandez",process_pid="61759",process_runtime_name="cli",process_runtime_version="8.1.17",service_name="unknown_service",something="liked-by-you",telemetry_sdk_language="php",telemetry_sdk_name="opentelemetry",telemetry_sdk_version="0.0.17"} 1

just to have:

counter_sample{something="liked-by-you"} 1

Found in the documentation!

So everything solved and clear. Thank you a lot @Nevay . I will close the issue to clean some noise 🙏🏼