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

Clean up docs, add syntax.md and semconv.schema.json #53

Merged
merged 8 commits into from
Jul 22, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
53 changes: 40 additions & 13 deletions semantic-conventions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,25 @@ For help try:
docker run --rm otel/semconvgen -h
```

## Model definition language (YAML input)

The expected YAML input file format is documented in [syntax.md](./syntax.md).

There is also a JSON schema definition available for the YAML files, which can
be used e.g. in VS code to get validation and auto-completion: [semconv.schema.json](./semconv.schema.json).
For example, with the `redhat.vscode-yaml` plugin, use the following snippet in your VS Code `settings.json` to apply it
to the test YAML files:

```json
{
"yaml.schemas": {
"./semantic-conventions/semconv.schema.json": [
"semantic-conventions/src/tests/**/*.yaml"
]
}
}
```

## Markdown Tables

Tables can be generated using the command:
Expand All @@ -26,12 +45,12 @@ docker run --rm otel/semconvgen --yaml-root {yaml_folder} markdown --markdown-ro

Where `{yaml_folder}` is the absolute path to the directory containing the yaml files and
`{markdown_folder}` the absolute path to the directory containing the markdown definitions
(`specification` for [opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification/tree/master/)).
(`specification` for [opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification/tree/main/)).

The tool will automatically replace the tables with the up to date definition of the semantic conventions.
To do so, the tool looks for special tags in the markdown.

```
```markdown
<!-- semconv {semantic_convention_id} -->
<!-- endsemconv -->
```
Expand Down Expand Up @@ -68,13 +87,27 @@ semantic conventions that have the tag `network`.

The image supports [Jinja](https://jinja.palletsprojects.com/en/2.11.x/) templates to generate code from the models.

For example, the following template is used by the [opentelemetry-java-instrumentation](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/master/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/typedspan)
to generate Java classes. [Template Link.](https://gist.github.com/thisthat/7e34742f4a7f1b5df57118f859a19c3b)
For example, opentelemetry-java [generates typed constants for semantic conventions](https://github.com/open-telemetry/opentelemetry-java/blob/main/semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/SemanticAttributes.java)
using [this template](https://github.com/open-telemetry/opentelemetry-java/blob/main/buildscripts/semantic-convention/templates/SemanticAttributes.java.j2).

The image can generate code with the following command:
The commands used to generate that are
[here in the opentelemetry-java repo](https://github.com/open-telemetry/opentelemetry-java/blob/main/buildscripts/semantic-convention/generate.sh).
Note especially the `docker run` commands. For example to generate the aforementioned `SemanticAttributes.java`,
the following command is used:

```bash
docker run --rm otel/semconvgen --yaml-root {yaml_folder} code --template {jinja-file} --output {output-file}
docker run --rm \
-v ${SCRIPT_DIR}/opentelemetry-specification/semantic_conventions/trace:/source \
-v ${SCRIPT_DIR}/templates:/templates \
-v ${ROOT_DIR}/semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/:/output \
otel/semconvgen:$GENERATOR_VERSION \
--yaml-root /source \
code \
--template /templates/SemanticAttributes.java.j2 \
--output /output/SemanticAttributes.java \
-Dclass=SemanticAttributes \
-DschemaUrl=$SCHEMA_URL \
-Dpkg=io.opentelemetry.semconv.trace.attributes
```

By default, all models are fed into the specified template at once, i.e. only a single file is generated.
Expand All @@ -89,10 +122,4 @@ This way, multiple files are generated. The value of `pattern` can be one of the
- `extends`: The id of the parent semantic convention.

Finally, additional value can be passed to the template in form of `key=value` pairs separated by
comma using the `--parameters [{key=value},]+` flag.

For example, to generate the typed spans used by the [opentelemetry-java-instrumentation](https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/master/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/typedspan), the following command can be used:

```bash
docker run --rm otel/semconvgen --yaml-root ${yamls} code --template typed_span_class.java.j2 --file-per-group semconv_id -o ${output}/Span.java
```
comma using the `--parameters [{key=value},]+` or `-D` flag.
301 changes: 301 additions & 0 deletions semantic-conventions/semconv.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,301 @@
{
Oberon00 marked this conversation as resolved.
Show resolved Hide resolved
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"description": "YAML schema for semantic convention generator, use for example with VS Code.",
"additionalProperties": false,
"properties": {
"groups": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"id",
"brief"
],
"anyOf": [
{
"required": [
"attributes"
]
},
{
"required": [
"extends"
]
}
],
"properties": {
"id": {
"type": "string",
"description": "unique string"
},
"type": {
"type": "string",
"enum": [
"span",
"resource",
"metric"
]
},
"brief": {
"type": "string",
"description": "a brief description of the semantic convention"
},
"note": {
"type": "string",
"description": "a more elaborate description of the semantic convention. It defaults to an empty string"
},
"prefix": {
"type": "string",
"description": "prefix of the attribute for this semconv. It defaults to an empty string."
},
"extends": {
"type": "string",
"description": "reference another semantic convention ID. It inherits all attributes from the specified semconv."
},
"span_kind": {
"type": "string",
"enum": [
"client",
"server",
"producer",
"consumer",
"internal"
],
"description": "specifies the kind of the span. Leaf semconv nodes (in the hierarchy tree) that do not have this field set will generate a warning."
},
"attributes": {
"type": "array",
"items": {
"$ref": "#/definitions/Attribute"
},
"description": "list of attributes that belong to the semconv"
},
"constraints": {
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"additionalProperties": false,
"required": [
"any_of"
],
"properties": {
"any_of": {
"type": "array",
"description": " accepts a list of sequences. Each sequence contains a list of attribute ids that are required. any_of enforces that all attributes of at least one of the sequences are set.",
"items": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "string"
}
]
}
}
}
},
{
"type": "object",
"additionalProperties": false,
"required": [
"include"
],
"properties": {
"include": {
"type": "string",
"description": "accepts a semantic conventions id. It includes as part of this semantic convention all constraints and required attributes that are not already defined in the current semantic convention."
}
}
}
]
}
}
}
}
}
},
"definitions": {
"AttributeEnumType": {
"type": "object",
"additionalProperties": false,
"properties": {
"allow_custom_values": {
"type": "boolean"
},
"members": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"id",
"value"
],
"properties": {
"id": {
"type": "string",
"description": "string unique"
},
"value": {
"type": [
"string",
"number"
],
"description": "string or number, value of the enum entry."
},
"brief": {
"type": "string",
"description": "brief description of the enum entry value. It defaults to the value of ID."
},
"note": {
"type": "string",
"description": "longer description. It defaults to an empty string."
}
}
}
}
}
},
"AttributeFullSpec": {
"required": [
"id",
"type"
],
"properties": {
"id": {
"type": "string",
"description": "unique string"
},
"type": {
"oneOf": [
{
"type": "string",
"enum": [
"string",
"int",
"double",
"boolean",
"string[]",
"int[]",
"double[]",
"boolean[]"
],
"description": "literal denoting the type"
},
{
"$ref": "#/definitions/AttributeEnumType"
}
]
}
}
},
"AttributeReference": {
"type": "object",
"required": [
"ref"
],
"properties": {
"ref": {
"type": "string",
"description": "reference an existing attribute"
},
"tag": {
"type": "string",
"description": "associates a tag to the attribute"
}
}
},
"ValueType": {
"oneOf": [
{
"type": [
"string",
"boolean",
"number"
]
},
{
"type": "array",
"items": {
"type": [
"boolean",
"number",
"string"
]
}
}
]
},
"Attribute": {
"type": "object",
"allOf": [
{
"properties": {
"required": {
"description": "specifies if the attribute is mandatory. Can be 'always', or 'conditional'. When omitted, the attribute is not required. When set to 'conditional',the string provided as <condition> MUST specify the conditions under which the attribute is required.",
"oneOf": [
{
"type": "string",
"enum": [
"always"
]
},
{
"type": "object",
"additionalProperties": false,
"required": [
"conditional"
],
"properties": {
"conditional": {
"type": "string"
}
}
}
]
},
"sampling_relevant": {
"type": "boolean",
"description": "specifies if it is relevant for sampling. It defaults to false.",
"default": false
},
"brief": {
"type": "string",
"description": "brief description of the attribute."
},
"note": {
"type": "string",
"description": "additional notes to the attribute. It defaults to an empty string."
},
"examples": {
"$ref": "#/definitions/ValueType",
"description": "sequence/dictionary of example values for the attribute. They are optional for boolean and enum attributes. Example values must be of the same type of the attribute. If only a single example is provided, it can directly be reported without encapsulating it into a sequence/dictionary."
},
"deprecated": {
"type": "string",
"description": "specifies if the attribute is deprecated. The string provided as <description> MUST specify why it's deprecated and/or what to use instead."
}
}
},
{
"oneOf": [
{
"$ref": "#/definitions/AttributeFullSpec"
},
{
"$ref": "#/definitions/AttributeReference"
}
]
}
]
}
}
}
Loading