Skip to content

Commit

Permalink
Clean up docs, add syntax.md and semconv.schema.json (#53)
Browse files Browse the repository at this point in the history
Co-authored-by: Armin Ruech <[email protected]>
Co-authored-by: Yuri Shkuro <[email protected]>
Co-authored-by: Giovanni Liva <[email protected]>
Co-authored-by: Christian Neumüller <[email protected]>
Co-authored-by: Gernot Reisinger <[email protected]>
  • Loading branch information
5 people authored Jul 22, 2021
1 parent 56f5bfa commit cab67bf
Show file tree
Hide file tree
Showing 3 changed files with 601 additions and 13 deletions.
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 @@
{
"$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

0 comments on commit cab67bf

Please sign in to comment.