Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Add `Values` method to `HeaderCarrier` to implement the new `ValuesGetter` interface in `go.opentelemetry.io/otel/propagation`. (#5973)
- Update `Baggage` in `go.opentelemetry.io/otel/propagation` to retrieve multiple values for a key when the carrier implements `ValuesGetter`. (#5973)
- Add `AssertEqual` function in `go.opentelemetry.io/otel/log/logtest`. (#6662)
- The `go.opentelemetry.io/otel/semconv/v1.32.0` package.
The package contains semantic conventions from the `v1.32.0` version of the OpenTelemetry Semantic Conventions.
See the [migration documentation](./semconv/v1.32.0/MIGRATION.md) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/v1.31.0`(#6782)

### Removed

Expand Down
87 changes: 65 additions & 22 deletions semconv/helpers.j2
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,16 @@
{%- endfor -%}
{%- endmacro -%}

{%- macro to_go_name(fqn) -%}
{%- macro to_go_name(fqn="", pkg="") -%}
{%- if pkg != "" -%}
{%- set n = pkg | length -%}
{%- if pkg == fqn[:n] -%}
{%- set fqn = fqn[n:] -%}
{%- if fqn[0] == "." or fqn[0] == "." -%}
{%- set fqn = fqn[1:] -%}
{%- endif -%}
{%- endif -%}
{%- endif -%}
{{ repl(smart_title_case(fqn | replace(" ", "") | replace("_", ".") | acronym)) }}
{%- endmacro -%}

Expand Down Expand Up @@ -49,26 +58,30 @@ Examples: {{ attr.examples | trim("[]") }}
{%- endfor -%}
{%- endmacro -%}

{%- macro it_reps(brief) -%}
{%- macro prefix_brief(brief, prefix="") -%}
{%- set norms = [
"MUST", "REQUIRED", "SHALL",
"SHOULD", "RECOMMENDED",
"MAY", "OPTIONAL"
"MUST", "REQUIRED", "SHALL",
"SHOULD", "RECOMMENDED",
"MAY", "OPTIONAL"
] -%}
{%- set brief = brief | trim() | trim(".") -%}
{%- set brief = brief | trim() -%}
{%- if first_word(brief) is in norms -%}
It {{ brief }}.
{%- else -%}
It represents {% if brief[:2] == "A " or brief[:3] == "An " or brief[:4] == "The " -%}
{{ lower_first(brief) }}.
{{ prefix }} {% if brief[:2] == "A " or brief[:3] == "An " or brief[:4] == "The " -%}
{{ lower_first(brief) | trim(".") }}.
{%- else -%}
the {{ lower_first(brief) }}.
the {{ lower_first(brief) | trim(".") }}.
{%- endif -%}
{%- endif -%}
{%- endmacro -%}

{%- macro keydoc(attr) -%}
{{ to_go_name(attr.name) }}Key is the attribute Key conforming to the "{{ attr.name }}" semantic conventions. {{ it_reps(attr.brief) }}
{%- macro it_reps(brief) -%}
{{ prefix_brief(brief, "It represents") }}
{%- endmacro -%}

{%- macro keydoc(attr, pkg="") -%}
{{ to_go_name(attr.name, pkg) }}Key is the attribute Key conforming to the "{{ attr.name }}" semantic conventions. {{ it_reps(attr.brief) }}

{% if attr is enum -%}
Type: Enum
Expand All @@ -82,7 +95,7 @@ Stability: {{ attr.stability | title }}
{{ deprecated_doc(attr) }}
{%- endmacro -%}

{%- macro generate_consts(group) -%}
{%- macro generate_consts(group, pkg="") -%}
{#- TODO: generate with group docs (i.e group by registry namespace) #}

{{ ["Namespace: " ~ group.root_namespace] | comment(format="go") }}
Expand All @@ -91,26 +104,26 @@ const (
{#- TODO: Handle template attributes. #}
{%- if not attribute.type is template_type %}
{{ keydoc(attribute) | comment(format="go_1tab") }}
{{to_go_name(attribute.name)}}Key = attribute.Key("{{attribute.name}}")
{{to_go_name(attribute.name, pkg=pkg)}}Key = attribute.Key("{{attribute.name}}")
{% endif -%}
{%- endfor -%}
)
{%- endmacro -%}

{%- macro generate_funcs(group) -%}
{%- macro generate_funcs(group, pkg="") -%}
{%- for attribute in group.attributes if not attribute is enum %}
{#- TODO: Handle template attributes. #}
{%- if not attribute.type is template_type %}

{{ [to_go_name(attribute.name) ~ " returns an attribute KeyValue conforming to the \"" ~ attribute.name ~ "\" semantic conventions. " ~ it_reps(attribute.brief) ] | comment(format="go") }}
func {{to_go_name(attribute.name)}}(val {{attribute.type | instantiated_type | map_text("attribute_type_value")}}) attribute.KeyValue {
return {{to_go_name(attribute.name)}}Key.{{attribute.type | instantiated_type | map_text("attribute_type_method")}}(val)
{{ [to_go_name(attribute.name, pkg) ~ " returns an attribute KeyValue conforming to the \"" ~ attribute.name ~ "\" semantic conventions. " ~ it_reps(attribute.brief) ] | comment(format="go") }}
func {{to_go_name(attribute.name, pkg)}}(val {{attribute.type | instantiated_type | map_text("attribute_type_value")}}) attribute.KeyValue {
return {{to_go_name(attribute.name, pkg)}}Key.{{attribute.type | instantiated_type | map_text("attribute_type_method")}}(val)
}
{%- endif %}
{%- endfor %}
{%- endmacro -%}

{%- macro generate_vars(group) -%}
{%- macro generate_vars(group, pkg="") -%}
{#- Render values for enums #}
{%- for attribute in group.attributes %}
{%- if attribute is enum %}
Expand All @@ -123,17 +136,47 @@ var (
{%- else %}
{{ [value.brief or value.id, "Stability: " ~ value.stability] | comment(format="go_1tab") }}
{%- endif %}
{{to_go_name(attribute.name ~ "." ~ value.id)}} = {{ to_go_name(attribute.name) }}Key.{{attribute.type | instantiated_type | map_text("attribute_type_method")}}({{ value.value | print_member_value }})
{{to_go_name(attribute.name ~ "." ~ value.id, pkg=pkg)}} = {{ to_go_name(attribute.name, pkg=pkg) }}Key.{{attribute.type | instantiated_type | map_text("attribute_type_method")}}({{ value.value | print_member_value }})
{%- endfor %}
)
{%- endif %}
{%- endfor %}
{%- endmacro -%}

{%- macro metric_keydoc(metric) -%}
{%- macro metric_keydoc(metric, pkg="") -%}
{%- if not metric.brief -%}
{{ to_go_name(metric.metric_name) }} is the metric conforming to the "{{ metric.metric_name}}" semantic conventions.
{{ to_go_name(metric.metric_name, pkg=pkg) }} is the metric conforming to the "{{ metric.metric_name}}" semantic conventions.
{%- else -%}
{{ to_go_name(metric.metric_name) }} is the metric conforming to the "{{ metric.metric_name}}" semantic conventions. {{ it_reps(metric.brief)|trim(".") }}.
{{ to_go_name(metric.metric_name, pkg=pkg) }} is the metric conforming to the "{{ metric.metric_name}}" semantic conventions. {{ it_reps(metric.brief)|trim(".") }}.
{%- endif %}
{%- endmacro -%}

{%- macro metric_typedoc(metric, pkg="") -%}
{%- if not metric.brief -%}
{{ to_go_name(metric.metric_name, pkg=pkg) }} is an instrument used to record metric values conforming to the "{{ metric.metric_name}}" semantic conventions.
{%- else -%}
{{ to_go_name(metric.metric_name, pkg=pkg) }} is an instrument used to record metric values conforming to the "{{ metric.metric_name}}" semantic conventions. {{ it_reps(metric.brief)|trim(".") }}.
{%- endif %}
{%- endmacro -%}

{%- macro member_type(member) %}
{%- if member.value is string %}string{%- endif %}
{%- if member.value is boolean %}bool{%- endif %}
{%- if member.value is int %}int64{%- endif %}
{%- if member.value is float %}float64{%- endif %}
{%- endmacro %}

{%- macro attr_type(attribute) %}
{%- if attribute.type is mapping %}
{{- member_type(attribute.type.members[0]) }}
{%- elif attribute.type == "template[boolean]" %}boolean
{%- elif attribute.type == "template[int]" %}int
{%- elif attribute.type == "template[double]" %}double
{%- elif attribute.type == "template[string]" %}string
{%- elif attribute.type == "template[boolean[]]" %}boolean[]
{%- elif attribute.type == "template[int[]]" %}int[]
{%- elif attribute.type == "template[double[]]" %}double[]
{%- elif attribute.type == "template[string[]]" %}string[]
{%- else %}{{ attribute.type | trim }}
{%- endif %}
{%- endmacro %}
220 changes: 220 additions & 0 deletions semconv/instrument.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
{% import 'helpers.j2' as h -%}

{%- macro instrument_default(metric) -%}
{%- set ns = namespace(value="Int64", inst="unknown") -%}
{%- set divisible = ["s", "ms"] -%}
{%- if metric.unit is in divisible -%}
{%- set ns.value="Float64" -%}
{%- endif -%}
{%- if metric.instrument == "counter" -%}
{%- set ns.inst="Counter" -%}
{%- elif metric.instrument == "updowncounter" -%}
{%- set ns.inst="UpDownCounter" -%}
{%- elif metric.instrument == "gauge" -%}
{%- set ns.inst="Gauge" -%}
{%- elif metric.instrument == "histogram" -%}
{%- set ns.inst="Histogram" -%}
{%- endif -%}
{{ ns.value ~ ns.inst }}
{%- endmacro -%}

{%- macro instrument(metric) -%}
{{ metric.metric_name | map_text("instrument", instrument_default(metric)) }}
{%- endmacro -%}

{%- macro value_type(metric) -%}
{%- if instrument(metric)[:7] == "Float64" -%}
Float64
{%- else -%}
Int64
{%- endif -%}
{%- endmacro -%}

{%- macro param_name(raw="", pkg="") -%}
{%- set reserved = [
"type", "break", "default", "func", "interface", "select", "case", "defer",
"go", "map", "struct", "chan", "else", "goto", "const", "fallthrough", "if",
"range", "type", "continue", "for", "import", "return", "var",
]-%}
{%- set name = raw -%}
{%- if pkg != "" -%}
{%- set n = pkg | length -%}
{%- if pkg == name[:n] -%}
{%- set name = name[n:] -%}
{%- if name[0] == "." or name[0] == "." -%}
{%- set name = name[1:] -%}
{%- endif -%}
{%- endif -%}
{%- endif -%}
{%- if name | lower is in reserved -%}
{{ raw | camel_case }}
{%- else -%}
{{ name | camel_case }}
{%- endif -%}
{%- endmacro -%}

{%- macro params_docs(attrs, pkg="") -%}
{%- set ns = namespace(output='') -%}
{%- for attr in attrs | required | attribute_sort -%}
{%- set ns.output = ns.output ~ "\n\nThe " ~ param_name(attr.name, pkg) ~ " is the " ~ h.lower_first(attr.brief) -%}
{%- endfor -%}
{%- if attrs | not_required | length > 0 -%}
{%- set ns.output = ns.output ~ "\n\nAll additional attrs passed are included in the recorded value." -%}
{%- endif -%}
{%- if ns.output != "" -%}
//
{{ ns.output | comment }}
{%- endif -%}
{%- endmacro -%}

{%- macro param(attr, pkg="") -%}
{%- if attr.type is mapping -%}
{{ param_name(attr.name, pkg) }} {{ h.to_go_name(attr.name, pkg) }}Attr,
{%- else -%}
{{ param_name(attr.name, pkg) }} {{ attr.type | map_text("attribute_type_value")}},
{%- endif -%}
{%- endmacro -%}

{%- macro params(attrs, type="", pkg="", prefix="") -%}
{%- for attr in attrs | required | attribute_sort -%}
{{ prefix ~ param(attr, pkg) }}
{% endfor -%}
{{ prefix ~ "attrs ...attribute.KeyValue," }}
{%- endmacro -%}

{%- macro to_attribute(attr, pkg="") -%}
{%- if attr.type is mapping -%}
attribute.{{ h.attr_type(attr) | map_text("attribute_type_method")}}("{{ attr.name }}", {{ h.member_type(attr.type.members[0]) }}({{ param_name(attr.name, pkg) }})),
{%- else -%}
attribute.{{ attr.type | map_text("attribute_type_method")}}("{{ attr.name }}", {{ param_name(attr.name, pkg) }}),
{%- endif -%}
{%- endmacro -%}

{%- macro with_attributes_opt(attrs, pkg="", prefix="") -%}
{%- if attrs | length > 0 -%}
{{ prefix }}metric.WithAttributes(
{%- if attrs | required | length > 0 %}
{{ prefix }} append(
{{ prefix }} attrs,
{%- for attr in attrs | required | attribute_sort %}
{{ prefix }} {{ to_attribute(attr, pkg) }}
{%- endfor %}
{{ prefix }} )...,
{%- else %}
{{ prefix }} attrs...,
{%- endif %}
{{ prefix }}),
{%- endif -%}
{%- endmacro -%}

{%- macro add_method_with_optional(metric, inst, pkg="") -%}
{%- set name = h.to_go_name(metric.metric_name, pkg) -%}
{%- set req_attr = metric.attributes | required | attribute_sort -%}
func (m {{ name }}) Add(
ctx context.Context,
incr {{ value_type(metric) | lower }},
{{ params(metric.attributes, pkg=pkg, prefix="\t") }}
) {
o := addOptPool.Get().(*[]metric.AddOption)
defer func() {
*o = (*o)[:0]
addOptPool.Put(o)
}()

*o = append(
*o,
{{ with_attributes_opt(metric.attributes, pkg=pkg, prefix="\t\t") }}
)

m.{{ inst }}.Add(ctx, incr, *o...)
}
{%- endmacro -%}

{%- macro add_method(metric, inst, pkg="") -%}

// Add adds incr to the existing count.
{%- if metric.attributes | length > 0 %}
{{ params_docs(metric.attributes, pkg=pkg) }}
{%- if metric.note is defined %}
//
{{ metric.note | comment }}
{%- endif %}
{{ add_method_with_optional(metric, inst, pkg) }}
{%- else %}
{%- if metric.note is defined %}
//
{{ metric.note | comment }}
{%- endif %}
func (m {{ h.to_go_name(metric.metric_name, pkg) }}) Add(ctx context.Context, incr {{ value_type(metric) | lower }}, attrs ...attribute.KeyValue) {
if len(attrs) == 0 {
m.{{ inst }}.Add(ctx, incr)
return
}

o := addOptPool.Get().(*[]metric.AddOption)
defer func() {
*o = (*o)[:0]
addOptPool.Put(o)
}()

*o = append(*o, metric.WithAttributes(attrs...))
m.{{ inst }}.Add(ctx, incr, *o...)
}
{%- endif -%}
{%- endmacro -%}

{%- macro record_method_with_optional(metric, inst, pkg="") -%}
{%- set name = h.to_go_name(metric.metric_name, pkg) -%}
{%- set req_attr = metric.attributes | required | attribute_sort -%}
func (m {{ name }}) Record(
ctx context.Context,
val {{ value_type(metric) | lower }},
{{ params(metric.attributes, pkg=pkg, prefix="\t") }}
) {
o := recOptPool.Get().(*[]metric.RecordOption)
defer func() {
*o = (*o)[:0]
recOptPool.Put(o)
}()

*o = append(
*o,
{{ with_attributes_opt(metric.attributes, pkg=pkg, prefix="\t\t") }}
)

m.{{ inst }}.Record(ctx, val, *o...)
}
{%- endmacro -%}

{%- macro record_method(metric, inst, pkg="") -%}

// Record records val to the current distribution.
{%- if metric.attributes | length > 0 %}
{{ params_docs(metric.attributes, pkg=pkg) }}
{%- if metric.note is defined %}
//
{{ metric.note | comment }}
{%- endif %}
{{ record_method_with_optional(metric, inst, pkg) }}
{%- else %}
{%- set name = h.to_go_name(metric.metric_name, pkg) -%}
{%- if metric.note is defined %}
//
{{ metric.note | comment }}
{%- endif %}
func (m {{ name }}) Record(ctx context.Context, val {{ value_type(metric) | lower }}, attrs ...attribute.KeyValue) {
if len(attrs) == 0 {
m.{{ inst }}.Record(ctx, val)
}

o := recOptPool.Get().(*[]metric.RecordOption)
defer func() {
*o = (*o)[:0]
recOptPool.Put(o)
}()

*o = append(*o, metric.WithAttributes(attrs...))
m.{{ inst }}.Record(ctx, val, *o...)
}
{%- endif -%}
{%- endmacro -%}
Loading