Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unit semantic convention generator #21

Merged
merged 12 commits into from
Dec 14, 2020
Merged
Show file tree
Hide file tree
Changes from 10 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
47 changes: 12 additions & 35 deletions semantic-conventions/src/opentelemetry/semconv/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@
import sys
from typing import List

from opentelemetry.semconv.model.semantic_convention import (
SemanticConventionSet,
SemanticConventionType,
)
from opentelemetry.semconv.model.semantic_convention import SemanticConventionSet
from opentelemetry.semconv.templating.code import CodeRenderer

from opentelemetry.semconv.templating.markdown import MarkdownRenderer
Expand Down Expand Up @@ -51,28 +48,21 @@ def exclude_file_list(folder: str, pattern: str) -> List[str]:
return file_names


def filter_semconv(
semconv: SemanticConventionSet, span: bool, resource: bool, metric: bool
):
if span or resource or metric:
output = {}
for semconv_id in semconv.models:
model = semconv.models[semconv_id]
if span and model.type == SemanticConventionType.SPAN:
output[semconv_id] = model
if resource and model.type == SemanticConventionType.RESOURCE:
output[semconv_id] = model
if metric and model.type == SemanticConventionType.METRIC:
output[semconv_id] = model
semconv.models = output
def filter_semconv(semconv, type_filter):
if type_filter:
semconv.models = {
id: model
for id, model in semconv.models.items()
if model.TYPE_VALUE == type_filter
}


def main():
parser = setup_parser()
args = parser.parse_args()
check_args(args, parser)
semconv = parse_semconv(args, parser)
filter_semconv(semconv, args.span, args.resource, args.metric)
filter_semconv(semconv, args.only)
if len(semconv.models) == 0:
parser.error("No semantic convention model found!")
if args.flavor == "code":
Expand Down Expand Up @@ -175,22 +165,9 @@ def setup_parser():
"--debug", "-d", help="Enable debug output", action="store_true"
)
parser.add_argument(
"--span",
"-s",
help="Process only Span semantic conventions",
action="store_true",
)
parser.add_argument(
"--resource",
"-r",
help="Process only Resource semantic conventions",
action="store_true",
)
parser.add_argument(
"--metric",
"-m",
help="Process only Metric semantic conventions",
action="store_true",
"--only",
choices=["span", "resource", "metric", "units"],
help="Process only semantic conventions of the specified type.",
)
parser.add_argument(
"--yaml-root",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
from dataclasses import dataclass, field, replace
from typing import List, Tuple, Set

from opentelemetry.semconv.model.exceptions import ValidationError
from opentelemetry.semconv.model.semantic_attribute import SemanticAttribute
from opentelemetry.semconv.model.utils import validate_values

from ruamel.yaml.comments import CommentedSeq


# We cannot frozen due to later evaluation of the attributes
Expand Down Expand Up @@ -58,3 +62,36 @@ def inherit_anyof(self):
@dataclass(frozen=True)
class Include:
semconv_id: str


def parse_constraints(yaml_constraints):
""" This method parses the yaml representation for semantic convention attributes
creating a list of Constraint objects.
"""
constraints = ()
allowed_keys = ("include", "any_of")
for constraint in yaml_constraints:
validate_values(constraint, allowed_keys)
if len(constraint.keys()) > 1:
position = constraint.lc.data[list(constraint)[1]]
msg = (
"Invalid entry in constraint array - multiple top-level keys in entry."
)
raise ValidationError.from_yaml_pos(position, msg)
if "include" in constraint:
constraints += (Include(constraint.get("include")),)
elif "any_of" in constraint:
choice_sets = ()
for constraint_list in constraint.get("any_of"):
inner_id_list = ()
if isinstance(constraint_list, CommentedSeq):
inner_id_list = tuple(
attr_constraint for attr_constraint in constraint_list
)
else:
inner_id_list += (constraint_list,)
choice_sets += (inner_id_list,)
any_of = AnyOf(choice_sets)
any_of._yaml_src_position = constraint.get("any_of").lc.data
constraints += (any_of,)
return constraints
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,26 @@ class Required(Enum):
NO = 3


class HasAttributes:
def _set_attributes(self, prefix, node):
self.attrs_by_name = SemanticAttribute.parse(prefix, node.get("attributes"))

@property
def attributes(self):
if not hasattr(self, "attrs_by_name"):
return []

return list(self.attrs_by_name.values())


def unique_attributes(attributes):
output = []
for x in l:
if x.fqn not in [attr.fqn for attr in output]:
output.append(x)
return output


@dataclass
class SemanticAttribute:
fqn: str
Expand Down Expand Up @@ -85,6 +105,9 @@ def parse(prefix, yaml_attributes):
"sampling_relevant",
"note",
)
if not yaml_attributes:
return attributes

for attribute in yaml_attributes:
validate_values(attribute, allowed_keys)
attr_id = attribute.get("id")
Expand Down
Loading