diff --git a/apps/opentelemetry/README.md b/apps/opentelemetry/README.md index 00151cdc..bed24b1e 100644 --- a/apps/opentelemetry/README.md +++ b/apps/opentelemetry/README.md @@ -199,21 +199,23 @@ in the Resource. The default detectors read resource attributes from the OS environment variable `OTEL_RESOURCE_ATTRIBUTES` and Application environment variable `resource`. -### Span Limits +### Limits The number of Attributes, Events and Links on a Span are limited, as well as the length of an Attribute's value. When the limit is reached any additional Attributes, Events or Links are dropped and Attribute values larger than the length limit are truncated. -| OS | Application | Default | Type | -|:---------------------------------------|:-----------------------------|:---------|:------------------------| -| OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT | attribute_count_limit | 128 | integer | -| OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT | attribute_value_length_limit | infinity | integer | infinity | -| OTEL_SPAN_EVENT_COUNT_LIMIT | event_count_limit | 128 | integer | -| OTEL_SPAN_LINK_COUNT_LIMIT | link_count_limit | 128 | integer | -| OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT | attribute_per_event_limit | 128 | integer | -| OTEL_LINK_ATTRIBUTE_COUNT_LIMIT | attribute_per_link_limit | 128 | integer +| OS | Application | Default | Type | +|:---------------------------------------|:----------------------------------|:---------|:------------------------| +| OTEL_ATTRIBUTE_COUNT_LIMIT | attribute_count_limit | 128 | integer | +| OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT | attribute_value_length_limit | infinity | integer | infinity | +| OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT | span_attribute_count_limit | 128 | integer | +| OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT | span_attribute_value_length_limit | infinity | integer | infinity | +| OTEL_SPAN_EVENT_COUNT_LIMIT | event_count_limit | 128 | integer | +| OTEL_SPAN_LINK_COUNT_LIMIT | link_count_limit | 128 | integer | +| OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT | attribute_per_event_limit | 128 | integer | +| OTEL_LINK_ATTRIBUTE_COUNT_LIMIT | attribute_per_link_limit | 128 | integer Read more in the specification about [Span limits](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#span-limits) diff --git a/apps/opentelemetry_api/include/opentelemetry.hrl b/apps/opentelemetry_api/include/opentelemetry.hrl index 79d036d2..0cea0d8e 100644 --- a/apps/opentelemetry_api/include/opentelemetry.hrl +++ b/apps/opentelemetry_api/include/opentelemetry.hrl @@ -78,3 +78,10 @@ %% developer-facing error message message = <<"">> :: unicode:unicode_binary() }). + +-record(attributes, { + count_limit :: integer(), + value_length_limit :: integer() | infinity, + dropped :: integer(), + map :: map() + }). \ No newline at end of file diff --git a/apps/opentelemetry_api/src/otel_attributes.erl b/apps/opentelemetry_api/src/otel_attributes.erl index 026ee47a..3f0ac291 100644 --- a/apps/opentelemetry_api/src/otel_attributes.erl +++ b/apps/opentelemetry_api/src/otel_attributes.erl @@ -17,6 +17,8 @@ %%%------------------------------------------------------------------------- -module(otel_attributes). +-include("opentelemetry.hrl"). + -export([new/3, set/2, set/3, @@ -32,12 +34,6 @@ is_number(Value) orelse is_binary(Value) orelse is_list(Value))). --record(attributes, { - count_limit :: integer(), - value_length_limit :: integer() | infinity, - dropped :: integer(), - map :: map() - }). -type t() :: #attributes{}. diff --git a/apps/opentelemetry_api_experimental/src/otel_counter.erl b/apps/opentelemetry_api_experimental/src/otel_counter.erl index 36dd2257..ad78b57c 100644 --- a/apps/opentelemetry_api_experimental/src/otel_counter.erl +++ b/apps/opentelemetry_api_experimental/src/otel_counter.erl @@ -32,10 +32,10 @@ create(Meter, Name, Opts) -> otel_meter:create_counter(Meter, Name, Opts). --spec add(otel_meter:t(), otel_instrument:name(), pos_integer() |float(), opentelemetry:attributes_map()) -> ok. +-spec add(otel_meter:t(), otel_instrument:name(), pos_integer() | float(), opentelemetry:attributes_map() | otel_attributes:t()) -> ok. add(Meter, Name, Number, Attributes) -> otel_meter:record(Meter, Name, Number, Attributes). --spec add(otel_instrument:t(), pos_integer() |float(), opentelemetry:attributes_map()) -> ok. +-spec add(otel_instrument:t(), pos_integer() | float(), opentelemetry:attributes_map() | otel_attributes:t()) -> ok. add(Instrument=#instrument{module=Module}, Number, Attributes) -> Module:record(Instrument, Number, Attributes). diff --git a/apps/opentelemetry_api_experimental/src/otel_histogram.erl b/apps/opentelemetry_api_experimental/src/otel_histogram.erl index e16eef14..fff86512 100644 --- a/apps/opentelemetry_api_experimental/src/otel_histogram.erl +++ b/apps/opentelemetry_api_experimental/src/otel_histogram.erl @@ -33,10 +33,10 @@ create(Meter, Name, Opts) -> otel_meter:create_histogram(Meter, Name, Opts). --spec record(otel_meter:t(), otel_instrument:name(), pos_integer() | float(), opentelemetry:attributes_map()) -> ok. +-spec record(otel_meter:t(), otel_instrument:name(), pos_integer() | float(), opentelemetry:attributes_map() | otel_attributes:t()) -> ok. record(Meter, Name, Number, Attributes) -> otel_meter:record(Meter, Name, Number, Attributes). --spec record(otel_instrument:t(), pos_integer() | float(), opentelemetry:attributes_map()) -> ok. +-spec record(otel_instrument:t(), pos_integer() | float(), opentelemetry:attributes_map() | otel_attributes:t()) -> ok. record(Instrument=#instrument{module=Module}, Number, Attributes) -> Module:record(Instrument, Number, Attributes). diff --git a/apps/opentelemetry_api_experimental/src/otel_instrument.erl b/apps/opentelemetry_api_experimental/src/otel_instrument.erl index 6feac48a..87018b4d 100644 --- a/apps/opentelemetry_api_experimental/src/otel_instrument.erl +++ b/apps/opentelemetry_api_experimental/src/otel_instrument.erl @@ -29,7 +29,7 @@ -type kind() :: ?KIND_COUNTER | ?KIND_OBSERVABLE_COUNTER | ?KIND_HISTOGRAM | ?KIND_OBSERVABLE_GAUGE | ?KIND_UPDOWN_COUNTER | ?KIND_OBSERVABLE_UPDOWNCOUNTER. -type unit() :: atom(). %% latin1, maximum length of 63 characters --type observation() :: {number(), opentelemetry:attributes_map()}. +-type observation() :: {number(), opentelemetry:attributes_map() | otel_attributes:t()}. -type named_observations() :: {name(), [observation()]}. -type callback_args() :: term(). -type callback_result() :: [observation()] | diff --git a/apps/opentelemetry_api_experimental/src/otel_observable_counter.erl b/apps/opentelemetry_api_experimental/src/otel_observable_counter.erl index a4bbc67e..5dabd996 100644 --- a/apps/opentelemetry_api_experimental/src/otel_observable_counter.erl +++ b/apps/opentelemetry_api_experimental/src/otel_observable_counter.erl @@ -20,8 +20,10 @@ -export([create/3, create/5]). +-spec create(otel_meter:t(), otel_instrument:name(), otel_instrument:opts()) -> otel_instrument:t(). create(Meter, Name, Opts) -> otel_meter:create_observable_counter(Meter, Name, Opts). +-spec create(otel_meter:t(), otel_instrument:name(), otel_instrument:callback(), otel_instrument:callback_args(), otel_instrument:opts()) -> otel_instrument:t(). create(Meter, Name, Callback, CallbackArgs, Opts) -> otel_meter:create_observable_counter(Meter, Name, Callback, CallbackArgs, Opts). diff --git a/apps/opentelemetry_api_experimental/src/otel_observable_gauge.erl b/apps/opentelemetry_api_experimental/src/otel_observable_gauge.erl index 46f8c9b6..6816d352 100644 --- a/apps/opentelemetry_api_experimental/src/otel_observable_gauge.erl +++ b/apps/opentelemetry_api_experimental/src/otel_observable_gauge.erl @@ -27,8 +27,10 @@ -export([create/3, create/5]). +-spec create(otel_meter:t(), otel_instrument:name(), otel_instrument:opts()) -> otel_instrument:t(). create(Meter, Name, Opts) -> otel_meter:create_observable_gauge(Meter, Name, Opts). +-spec create(otel_meter:t(), otel_instrument:name(), otel_instrument:callback(), otel_instrument:callback_args(), otel_instrument:opts()) -> otel_instrument:t(). create(Meter, Name, Callback, CallbackArgs, Opts) -> otel_meter:create_observable_gauge(Meter, Name, Callback, CallbackArgs, Opts). diff --git a/apps/opentelemetry_api_experimental/src/otel_observable_updowncounter.erl b/apps/opentelemetry_api_experimental/src/otel_observable_updowncounter.erl index 565c821f..7315c851 100644 --- a/apps/opentelemetry_api_experimental/src/otel_observable_updowncounter.erl +++ b/apps/opentelemetry_api_experimental/src/otel_observable_updowncounter.erl @@ -25,8 +25,10 @@ -export([create/3, create/5]). +-spec create(otel_meter:t(), otel_instrument:name(), otel_instrument:opts()) -> otel_instrument:t(). create(Meter, Name, Opts) -> otel_meter:create_observable_updowncounter(Meter, Name, Opts). +-spec create(otel_meter:t(), otel_instrument:name(), otel_instrument:callback(), otel_instrument:callback_args(), otel_instrument:opts()) -> otel_instrument:t(). create(Meter, Name, Callback, CallbackArgs, Opts) -> otel_meter:create_observable_updowncounter(Meter, Name, Callback, CallbackArgs, Opts). diff --git a/apps/opentelemetry_api_experimental/src/otel_updown_counter.erl b/apps/opentelemetry_api_experimental/src/otel_updown_counter.erl index 64c73d0a..04b1b28d 100644 --- a/apps/opentelemetry_api_experimental/src/otel_updown_counter.erl +++ b/apps/opentelemetry_api_experimental/src/otel_updown_counter.erl @@ -32,10 +32,10 @@ create(Meter, Name, Opts) -> otel_meter:create_updown_counter(Meter, Name, Opts). --spec add(otel_meter:t(), otel_instrument:name(), number(), opentelemetry:attributes_map()) -> ok. +-spec add(otel_meter:t(), otel_instrument:name(), number(), opentelemetry:attributes_map() | otel_attributes:t()) -> ok. add(Meter, Name, Number, Attributes) -> otel_meter:record(Meter, Name, Number, Attributes). --spec add(otel_instrument:t(), number(), opentelemetry:attributes_map()) -> ok. +-spec add(otel_instrument:t(), number(), opentelemetry:attributes_map() | otel_attributes:t()) -> ok. add(Instrument=#instrument{module=Module}, Number, Attributes) -> Module:record(Instrument, Number, Attributes). diff --git a/apps/opentelemetry_experimental/src/otel_meter_server.erl b/apps/opentelemetry_experimental/src/otel_meter_server.erl index 6b59e428..544c480d 100644 --- a/apps/opentelemetry_experimental/src/otel_meter_server.erl +++ b/apps/opentelemetry_experimental/src/otel_meter_server.erl @@ -359,12 +359,15 @@ metric_reader(ReaderId, ReaderPid, DefaultAggregationMapping, Temporality) -> %% for each ViewAggregation a Measurement updates a Metric (`#metric') %% active metrics are indexed by the ViewAggregation name + the Measurement's Attributes +handle_measurement(Meter, Name, Number, AttributesRecord, ViewAggregationsTab, MetricsTab) when is_record(AttributesRecord, attributes) -> + Matches = ets:match(ViewAggregationsTab, {{Meter, Name}, '$1'}), + update_aggregations(Number, AttributesRecord, Matches, MetricsTab); + handle_measurement(Meter, Name, Number, Attributes, ViewAggregationsTab, MetricsTab) -> AttributeCountLimit = otel_limits:attribute_count_limit(), AttributeValueLengthLimit = otel_limits:attribute_value_length_limit(), AttributesRecord = otel_attributes:new(Attributes, AttributeCountLimit, AttributeValueLengthLimit), - Matches = ets:match(ViewAggregationsTab, {{Meter, Name}, '$1'}), - update_aggregations(Number, AttributesRecord, Matches, MetricsTab). + handle_measurement(Meter, Name, Number, AttributesRecord, ViewAggregationsTab, MetricsTab). update_aggregations(Value, Attributes, ViewAggregations, MetricsTab) -> lists:foreach(fun([ViewAggregation=#view_aggregation{}]) -> diff --git a/apps/opentelemetry_experimental/src/otel_observables.erl b/apps/opentelemetry_experimental/src/otel_observables.erl index 55da1599..3114a9f9 100644 --- a/apps/opentelemetry_experimental/src/otel_observables.erl +++ b/apps/opentelemetry_experimental/src/otel_observables.erl @@ -21,6 +21,7 @@ -include_lib("kernel/include/logger.hrl"). -include_lib("opentelemetry_api_experimental/include/otel_metrics.hrl"). +-include_lib("opentelemetry_api/include/opentelemetry.hrl"). -include("otel_metrics.hrl"). -include("otel_view.hrl"). @@ -96,6 +97,8 @@ handle_observations(MetricsTab, ViewAggregation, [{Number, Attributes} | Rest]) AttributeCountLimit = otel_limits:attribute_count_limit(), AttributeValueLengthLimit = otel_limits:attribute_value_length_limit(), AttributesRecord = otel_attributes:new(Attributes, AttributeCountLimit, AttributeValueLengthLimit), + handle_observations(MetricsTab, ViewAggregation, [{Number, AttributesRecord} | Rest]); +handle_observations(MetricsTab, ViewAggregation, [{Number, AttributesRecord} | Rest]) when is_number(Number), is_record(AttributesRecord, attributes) -> _ = otel_aggregation:maybe_init_aggregate(MetricsTab, ViewAggregation, Number, AttributesRecord), handle_observations(MetricsTab, ViewAggregation, Rest); handle_observations(MetricsTab, ViewAggregation, [Result | Rest]) ->