From eccadce704203603b7bf5177db881343398d0017 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 20 Feb 2024 12:20:11 -0800 Subject: [PATCH] Add metrics to the context of non-scoped codegen (#270) --- semantic-conventions/README.md | 3 +- .../opentelemetry/semconv/templating/code.py | 9 ++++++ .../data/jinja/metrics/expected_metrics.java | 16 ++++++++++ .../tests/data/jinja/metrics/metrics_template | 11 +++++++ .../src/tests/data/yaml/metrics/metrics.yaml | 30 +++++++++++++++++++ .../src/tests/semconv/templating/test_code.py | 18 +++++++++++ 6 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 semantic-conventions/src/tests/data/jinja/metrics/expected_metrics.java create mode 100644 semantic-conventions/src/tests/data/jinja/metrics/metrics_template create mode 100644 semantic-conventions/src/tests/data/yaml/metrics/metrics.yaml diff --git a/semantic-conventions/README.md b/semantic-conventions/README.md index d671ad10..33876b6c 100644 --- a/semantic-conventions/README.md +++ b/semantic-conventions/README.md @@ -189,9 +189,10 @@ Processes all parsed semantic conventions - `semconvs` - the dictionary containing parsed `BaseSemanticConvention` instances with semconv `id` as a key - `attributes_and_templates` - the dictionary containing all attributes (including template ones) grouped by their root namespace. Each element in the dictionary is a list of attributes that share the same root namespace. Attributes that don't have a namespace - appear under `""` key. + appear under `""` key. Attributes and templates are sorted by attribute name. - `attributes` - the list of all attributes from all parsed semantic conventions. Does not include template attributes. - `attribute_templates` - the list of all attribute templates from all parsed semantic conventions. +- `metrics` - the list of all metric semantic conventions sorted by metric name. #### The `root_namespace` pattern diff --git a/semantic-conventions/src/opentelemetry/semconv/templating/code.py b/semantic-conventions/src/opentelemetry/semconv/templating/code.py index 6b828fcb..e1a554c8 100644 --- a/semantic-conventions/src/opentelemetry/semconv/templating/code.py +++ b/semantic-conventions/src/opentelemetry/semconv/templating/code.py @@ -233,6 +233,7 @@ def get_data_single_file( "attributes": semconvset.attributes(), "attribute_templates": semconvset.attribute_templates(), "attributes_and_templates": self._grouped_attribute_definitions(semconvset), + "metrics": self._all_metrics_definitions(semconvset), } data.update(self.parameters) return data @@ -387,6 +388,14 @@ def _grouped_metric_definitions(self, semconvset): ) return grouped_metrics + def _all_metrics_definitions(self, semconvset): + all_metrics = [] + for semconv in semconvset.models.values(): + if is_metric(semconv): + all_metrics.append(semconv) + + return sorted(all_metrics, key=lambda a: a.metric_name) + def _write_template_to_file(self, template, data, output_name): template.globals["now"] = datetime.datetime.utcnow() template.globals["version"] = os.environ.get("ARTIFACT_VERSION", "dev") diff --git a/semantic-conventions/src/tests/data/jinja/metrics/expected_metrics.java b/semantic-conventions/src/tests/data/jinja/metrics/expected_metrics.java new file mode 100644 index 00000000..8dccdd34 --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/metrics/expected_metrics.java @@ -0,0 +1,16 @@ +class AllMetrics { + /** + * first metric description + * Unit: {one} + * Instrument: counter + * Experimental: False + */ + public static final String FIRST_METRIC = "first.metric"; + /** + * second metric description + * Unit: s + * Instrument: histogram + * Experimental: True + */ + public static final String SECOND_GROUP_METRIC = "second_group.metric"; +} \ No newline at end of file diff --git a/semantic-conventions/src/tests/data/jinja/metrics/metrics_template b/semantic-conventions/src/tests/data/jinja/metrics/metrics_template new file mode 100644 index 00000000..c49a3803 --- /dev/null +++ b/semantic-conventions/src/tests/data/jinja/metrics/metrics_template @@ -0,0 +1,11 @@ +class AllMetrics { +{%- for metric in metrics %} + /** + * {{metric.brief | to_doc_brief}} + * Unit: {{ metric.unit }} + * Instrument: {{ metric.instrument }} + * Experimental: {{ metric | is_experimental }} + */ + public static final String {{ metric.metric_name | to_const_name }} = "{{metric.metric_name}}"; +{%- endfor %} +} diff --git a/semantic-conventions/src/tests/data/yaml/metrics/metrics.yaml b/semantic-conventions/src/tests/data/yaml/metrics/metrics.yaml new file mode 100644 index 00000000..3d2c670b --- /dev/null +++ b/semantic-conventions/src/tests/data/yaml/metrics/metrics.yaml @@ -0,0 +1,30 @@ +groups: + - id: first_group_id + type: attribute_group + brief: first description + prefix: first + attributes: + - id: attr_one + type: boolean + brief: short description of attr_one + + - id: first_metric_id + brief: first metric description + metric_name: first.metric + instrument: counter + type: metric + unit: "{one}" + stability: stable + extends: first_group_id + + - id: second_group_id + brief: second metric description + metric_name: second_group.metric + type: metric + instrument: histogram + unit: "s" + prefix: second_group + attributes: + - id: attr_two + type: int + brief: short description of attr_two diff --git a/semantic-conventions/src/tests/semconv/templating/test_code.py b/semantic-conventions/src/tests/semconv/templating/test_code.py index e85a81de..5bc45f05 100644 --- a/semantic-conventions/src/tests/semconv/templating/test_code.py +++ b/semantic-conventions/src/tests/semconv/templating/test_code.py @@ -23,6 +23,24 @@ def test_codegen_units(test_file_path, read_test_file): assert result == expected +def test_codegen_metrics_all(test_file_path, read_test_file): + semconv = SemanticConventionSet(debug=False) + semconv.parse(test_file_path("yaml", "metrics", "metrics.yaml")) + semconv.finish() + + template_path = test_file_path("jinja", "metrics", "metrics_template") + renderer = CodeRenderer({}, trim_whitespace=False) + + filename = os.path.join(tempfile.mkdtemp(), "AllMetrics.java") + renderer.render(semconv, template_path, filename, None) + with open(filename, "r", encoding="utf-8") as f: + result = f.read() + + expected = read_test_file("jinja", "metrics", "expected_metrics.java") + + assert result == expected + + def test_strip_blocks_enabled(test_file_path, read_test_file): """Tests that the Jinja whitespace control params are fed to the Jinja environment""" semconv = SemanticConventionSet(debug=False)