@intentius/chant-lexicon-otel 0.124.31 → 0.124.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attribution.js +391 -0
- package/dist/catalog.js +42 -0
- package/dist/codegen/docs-cli.js +3 -0
- package/dist/codegen/docs.js +101 -0
- package/dist/codegen/generate-cli.js +7 -0
- package/dist/codegen/generate.js +43 -0
- package/dist/codegen/package.js +28 -0
- package/dist/collector.js +150 -0
- package/dist/components/common.js +50 -0
- package/dist/components/connectors.js +242 -0
- package/dist/components/exporters.js +57 -0
- package/dist/components/extensions.js +58 -0
- package/dist/components/filtering.js +106 -0
- package/dist/components/index.js +9 -0
- package/dist/components/k8s-receivers.js +36 -0
- package/dist/components/processors.js +103 -0
- package/dist/components/receivers.js +61 -0
- package/dist/components/sampling.js +257 -0
- package/dist/composites/catalog.js +368 -0
- package/dist/composites/genai-pipeline.js +28 -0
- package/dist/composites/index.js +8 -0
- package/dist/composites/node-agent.js +156 -0
- package/dist/composites/otlp-collector.js +57 -0
- package/dist/composites/red-metrics.js +95 -0
- package/dist/composites/tail-sampling-tier.js +132 -0
- package/dist/config-hygiene.js +464 -0
- package/dist/configmap.js +86 -0
- package/dist/define.js +204 -0
- package/dist/detect.js +22 -0
- package/dist/genai.js +569 -0
- package/dist/import/embedded.js +57 -0
- package/dist/import/generator.js +459 -0
- package/dist/import/parser.js +199 -0
- package/dist/index.js +34 -0
- package/dist/init-templates.js +119 -0
- package/dist/integrity.json +2 -2
- package/dist/lint/audit-catalog.js +49 -0
- package/dist/lint/post-synth/index.js +52 -0
- package/dist/lint/post-synth/otel-helpers.js +103 -0
- package/dist/lint/post-synth/otel101.js +13 -0
- package/dist/lint/post-synth/otel102.js +13 -0
- package/dist/lint/post-synth/otel103.js +13 -0
- package/dist/lint/post-synth/otel104.js +13 -0
- package/dist/lint/post-synth/otel105.js +13 -0
- package/dist/lint/post-synth/otel106.js +13 -0
- package/dist/lint/post-synth/otel107.js +13 -0
- package/dist/lint/post-synth/otel108.js +13 -0
- package/dist/lint/post-synth/otel109.js +13 -0
- package/dist/lint/post-synth/otel112.js +13 -0
- package/dist/lint/post-synth/otel113.js +13 -0
- package/dist/lint/post-synth/otel114.js +13 -0
- package/dist/lint/post-synth/otel115.js +13 -0
- package/dist/lint/post-synth/otel116.js +13 -0
- package/dist/lint/post-synth/otel117.js +13 -0
- package/dist/lint/post-synth/otel118.js +13 -0
- package/dist/lint/post-synth/otel119.js +13 -0
- package/dist/lint/post-synth/otel120.js +13 -0
- package/dist/lint/post-synth/otel121.js +13 -0
- package/dist/lint/post-synth/otel122.js +13 -0
- package/dist/lint/post-synth/otel123.js +13 -0
- package/dist/lint/post-synth/otel124.js +13 -0
- package/dist/lint/post-synth/otel125.js +13 -0
- package/dist/lint/post-synth/otel126.js +13 -0
- package/dist/lint/post-synth/otel127.js +13 -0
- package/dist/lint/rules/component-id-syntax.js +66 -0
- package/dist/lint/rules/index.js +6 -0
- package/dist/lint/rules/literal-credential.js +91 -0
- package/dist/lint/rules/otel-ast.js +30 -0
- package/dist/lsp/completions.js +11 -0
- package/dist/lsp/hover.js +23 -0
- package/dist/manifest.json +1 -1
- package/dist/metric-names.js +244 -0
- package/dist/model.js +90 -0
- package/dist/op/activities/collector-audit.js +213 -0
- package/dist/op/activities/collector-health.js +176 -0
- package/dist/op/activities/exec.js +16 -0
- package/dist/op/activities/github.js +110 -0
- package/dist/op/activities/index.js +16 -0
- package/dist/op/activities/otelcol.js +173 -0
- package/dist/op/activity-contracts.js +64 -0
- package/dist/op/audit-op.js +33 -0
- package/dist/op/builders.js +38 -0
- package/dist/package-cli.js +14 -0
- package/dist/pipeline.js +31 -0
- package/dist/platform.js +144 -0
- package/dist/plugin.js +126 -0
- package/dist/semconv.js +50 -0
- package/dist/serializer.js +26 -0
- package/dist/skill-defs.js +34 -0
- package/dist/topology.js +104 -0
- package/dist/validate-cli.js +7 -0
- package/dist/validate-config.js +706 -0
- package/dist/validate.js +85 -0
- package/dist/yaml.js +157 -0
- package/package.json +8 -8
- package/src/codegen/package.ts +2 -2
package/dist/define.js
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `defineComponent()`, the one way a collector component type enters this
|
|
3
|
+
* lexicon.
|
|
4
|
+
*
|
|
5
|
+
* The built-in receivers, processors, exporters, connectors and extensions are
|
|
6
|
+
* defined through it, and so is a component a team or plugin adds for something
|
|
7
|
+
* chant doesn't ship (a vendor exporter, an in-house processor). Both produce the
|
|
8
|
+
* same kind of class, register in the same table, serialize through the same
|
|
9
|
+
* code and are checked by the same post-synth checks, so there is no second
|
|
10
|
+
* path for a custom component to fall off.
|
|
11
|
+
*
|
|
12
|
+
* ## Schema pinning
|
|
13
|
+
*
|
|
14
|
+
* Every definition carries a `pin`: the source its config type was written
|
|
15
|
+
* against and the version of that source. Built-ins share `COLLECTOR_PIN`,
|
|
16
|
+
* which moves only when this package does, so the chant lexicon version pins
|
|
17
|
+
* them. A custom definition must name its own pin, typically the npm package
|
|
18
|
+
* (or Go module) that ships the component and the release its type follows,
|
|
19
|
+
* optionally with a digest of the schema document. chant records the pin; it
|
|
20
|
+
* does not fetch or verify the schema. The pin shows up in three places:
|
|
21
|
+
*
|
|
22
|
+
* - `collectorTopology()` reports it for every component, built-in or not.
|
|
23
|
+
* - The serializer writes a `# chant:` comment line per custom component at
|
|
24
|
+
* the top of the emitted YAML, so the file says which schema each
|
|
25
|
+
* non-built-in component was checked against. The collector ignores it.
|
|
26
|
+
* - OTEL109 fails a build whose custom component has no usable pin.
|
|
27
|
+
*
|
|
28
|
+
* Semantic-convention pins (`SEMCONV_PIN`, `GENAI_SEMCONV_PIN`) record which version of an
|
|
29
|
+
* attribute vocabulary a preset's keys follow. They are not tied to a
|
|
30
|
+
* component type, so `collectorTopology()` reports them under `semconv` for
|
|
31
|
+
* each component whose config uses that vocabulary, and the serializer writes
|
|
32
|
+
* one `# chant: semconv` line for them.
|
|
33
|
+
*/
|
|
34
|
+
import { createResource } from "@intentius/chant/runtime";
|
|
35
|
+
import { canonicalComponentType, componentId } from "./model.js";
|
|
36
|
+
/**
|
|
37
|
+
* The collector distribution the built-in config types follow. Bumping it is a
|
|
38
|
+
* lexicon change like any other, released with this package.
|
|
39
|
+
*/
|
|
40
|
+
export const COLLECTOR_PIN = Object.freeze({
|
|
41
|
+
source: "github.com/open-telemetry/opentelemetry-collector-contrib",
|
|
42
|
+
version: "v0.130.0",
|
|
43
|
+
});
|
|
44
|
+
/**
|
|
45
|
+
* The semantic-conventions release this package's other attribute keys
|
|
46
|
+
* follow, today the `k8s.*` keys `NodeAgent` writes. v1.27.0 is the newest
|
|
47
|
+
* release the Kubernetes components of contrib v0.130.0 import:
|
|
48
|
+
* `go.opentelemetry.io/otel/semconv/v1.27.0` in the kubeletstats, k8sobjects
|
|
49
|
+
* and k8sevents receivers. The k8sattributes processor still imports v1.6.1
|
|
50
|
+
* and v1.8.0, and v1.27.0 keeps the `k8s.*` keys it writes. Like
|
|
51
|
+
* `COLLECTOR_PIN`, it moves only when this package does, and
|
|
52
|
+
* `collectorTopology()` reports it for every component whose config names a
|
|
53
|
+
* `k8s.` attribute.
|
|
54
|
+
*/
|
|
55
|
+
export const SEMCONV_PIN = Object.freeze({
|
|
56
|
+
source: "github.com/open-telemetry/semantic-conventions",
|
|
57
|
+
version: "v1.27.0",
|
|
58
|
+
});
|
|
59
|
+
/**
|
|
60
|
+
* The OpenTelemetry GenAI semantic conventions the GenAI preset
|
|
61
|
+
* (`genAiPipeline()`) follows: which attributes carry prompt and completion
|
|
62
|
+
* content, and which name the operation, model, tool and token usage.
|
|
63
|
+
*
|
|
64
|
+
* v1.41.1 is the last semantic-conventions release that defines `gen_ai.*`
|
|
65
|
+
* itself. From v1.42.0 the GenAI conventions live in
|
|
66
|
+
* github.com/open-telemetry/semantic-conventions-genai, which had published no
|
|
67
|
+
* release when this pin was set; move the pin there once it does. Like
|
|
68
|
+
* `COLLECTOR_PIN`, it moves only when this package does, and
|
|
69
|
+
* `collectorTopology()` reports it for every component whose config names a
|
|
70
|
+
* `gen_ai.` attribute.
|
|
71
|
+
*/
|
|
72
|
+
export const GENAI_SEMCONV_PIN = Object.freeze({
|
|
73
|
+
source: "github.com/open-telemetry/semantic-conventions",
|
|
74
|
+
version: "v1.41.1",
|
|
75
|
+
});
|
|
76
|
+
const KIND_SEGMENT = {
|
|
77
|
+
receiver: "Receiver",
|
|
78
|
+
processor: "Processor",
|
|
79
|
+
exporter: "Exporter",
|
|
80
|
+
connector: "Connector",
|
|
81
|
+
extension: "Extension",
|
|
82
|
+
};
|
|
83
|
+
/** The chant entity type for a component, e.g. `OTel::Exporter::otlp`. */
|
|
84
|
+
export function componentEntityType(kind, type) {
|
|
85
|
+
return `OTel::${KIND_SEGMENT[kind]}::${type}`;
|
|
86
|
+
}
|
|
87
|
+
// One table per process, keyed by entity type. Held on globalThis so a second
|
|
88
|
+
// copy of this module (a test runner and a built dist, say) shares it.
|
|
89
|
+
const REGISTRY_KEY = Symbol.for("chant.otel.componentDefinitions");
|
|
90
|
+
function registry() {
|
|
91
|
+
const g = globalThis;
|
|
92
|
+
let table = g[REGISTRY_KEY];
|
|
93
|
+
if (!table) {
|
|
94
|
+
table = new Map();
|
|
95
|
+
g[REGISTRY_KEY] = table;
|
|
96
|
+
}
|
|
97
|
+
return table;
|
|
98
|
+
}
|
|
99
|
+
/** The definition behind an entity type, if one has been registered in this process. */
|
|
100
|
+
export function definitionFor(entityType) {
|
|
101
|
+
return registry().get(entityType);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The definition for a collector `kind` + `type`, e.g. the built-in
|
|
105
|
+
* `exporter` `otlp`. A renamed built-in's new name (`otlp_grpc`) finds the
|
|
106
|
+
* built-in unless a component is registered under the new name itself.
|
|
107
|
+
*/
|
|
108
|
+
export function definitionOf(kind, type) {
|
|
109
|
+
const reg = registry();
|
|
110
|
+
return reg.get(componentEntityType(kind, type)) ?? reg.get(componentEntityType(kind, canonicalComponentType(kind, type)));
|
|
111
|
+
}
|
|
112
|
+
/** Every registered definition, built-ins first in registration order. */
|
|
113
|
+
export function registeredDefinitions() {
|
|
114
|
+
return [...registry().values()];
|
|
115
|
+
}
|
|
116
|
+
const TYPE_PATTERN = /^[A-Za-z0-9_]+$/;
|
|
117
|
+
function makeClass(def) {
|
|
118
|
+
if (!TYPE_PATTERN.test(def.type)) {
|
|
119
|
+
throw new Error(`otel: component type "${def.type}" is not a collector type (letters, digits and _ only)`);
|
|
120
|
+
}
|
|
121
|
+
const entityType = componentEntityType(def.kind, def.type);
|
|
122
|
+
const existing = registry().get(entityType);
|
|
123
|
+
if (existing?.builtin && !def.builtin) {
|
|
124
|
+
throw new Error(`otel: ${def.kind} "${def.type}" is built in. Declare an instance with a name (${def.type}/<name>) instead of defining it again.`);
|
|
125
|
+
}
|
|
126
|
+
registry().set(entityType, def);
|
|
127
|
+
const Base = createResource(entityType, "otel", {});
|
|
128
|
+
const Cls = function (props) {
|
|
129
|
+
const p = props ?? {};
|
|
130
|
+
Base.call(this, p);
|
|
131
|
+
const name = typeof p.name === "string" ? p.name : undefined;
|
|
132
|
+
Object.defineProperty(this, "componentKind", { value: def.kind, enumerable: false });
|
|
133
|
+
Object.defineProperty(this, "componentType", { value: def.type, enumerable: false });
|
|
134
|
+
Object.defineProperty(this, "componentId", { value: componentId(def.type, name), enumerable: false });
|
|
135
|
+
};
|
|
136
|
+
Object.defineProperty(Cls, "name", { value: `${def.type}${KIND_SEGMENT[def.kind]}` });
|
|
137
|
+
Object.defineProperty(Cls, "definition", { value: def, enumerable: false });
|
|
138
|
+
return Cls;
|
|
139
|
+
}
|
|
140
|
+
/** Internal: how the built-ins in `./components` are defined. */
|
|
141
|
+
export function defineBuiltin(def) {
|
|
142
|
+
return makeClass({ ...def, pin: COLLECTOR_PIN, builtin: true });
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Define a collector component chant doesn't ship.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```ts
|
|
149
|
+
* interface DatadogExporterConfig {
|
|
150
|
+
* api: { key: string; site?: string };
|
|
151
|
+
* traces?: { span_name_as_resource_name?: boolean };
|
|
152
|
+
* }
|
|
153
|
+
*
|
|
154
|
+
* export const DatadogExporter = defineComponent<DatadogExporterConfig>()({
|
|
155
|
+
* kind: "exporter",
|
|
156
|
+
* type: "datadog",
|
|
157
|
+
* pin: { source: "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter", version: "v0.130.0" },
|
|
158
|
+
* validate: (c) => (c.api.key.startsWith("${env:") ? [] : ["api.key should come from ${env:...}"]),
|
|
159
|
+
* endpoints: (c) => [`https://api.${c.api.site ?? "datadoghq.com"}`],
|
|
160
|
+
* });
|
|
161
|
+
*
|
|
162
|
+
* export const dd = new DatadogExporter({ api: { key: "${env:DD_API_KEY}" } });
|
|
163
|
+
* ```
|
|
164
|
+
*
|
|
165
|
+
* The curried form lets you name the config type while `kind` and `type` are
|
|
166
|
+
* still inferred from the literal you pass.
|
|
167
|
+
*/
|
|
168
|
+
export function defineComponent() {
|
|
169
|
+
return function (options) {
|
|
170
|
+
return makeClass({ ...options, builtin: false });
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/** True when `value` is a declared collector component (built-in or custom). */
|
|
174
|
+
export function isOTelComponent(value) {
|
|
175
|
+
return (typeof value === "object" &&
|
|
176
|
+
value !== null &&
|
|
177
|
+
typeof value.componentKind === "string" &&
|
|
178
|
+
typeof value.componentId === "string" &&
|
|
179
|
+
value.lexicon === "otel");
|
|
180
|
+
}
|
|
181
|
+
/** Run a definition's validator, normalising both validator forms to a list of messages. */
|
|
182
|
+
export function runValidator(validator, config) {
|
|
183
|
+
if (!validator)
|
|
184
|
+
return [];
|
|
185
|
+
if (typeof validator === "function")
|
|
186
|
+
return validator(config);
|
|
187
|
+
const result = validator.safeParse(config);
|
|
188
|
+
if (result.success)
|
|
189
|
+
return [];
|
|
190
|
+
const issues = result.error?.issues ?? [];
|
|
191
|
+
if (issues.length === 0)
|
|
192
|
+
return [result.error?.message ?? "config does not match its schema"];
|
|
193
|
+
return issues.map((i) => {
|
|
194
|
+
const path = (i.path ?? []).map(String).join(".");
|
|
195
|
+
return path ? `${path}: ${i.message}` : i.message;
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
/** A pin is usable when it names a source and a version. */
|
|
199
|
+
export function isUsablePin(pin) {
|
|
200
|
+
if (typeof pin !== "object" || pin === null)
|
|
201
|
+
return false;
|
|
202
|
+
const p = pin;
|
|
203
|
+
return typeof p.source === "string" && p.source.trim() !== "" && typeof p.version === "string" && p.version.trim() !== "";
|
|
204
|
+
}
|
package/dist/detect.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template detection for the otel lexicon: a parsed document is a collector
|
|
3
|
+
* config when it has `service.pipelines` and a receivers or exporters
|
|
4
|
+
* section. Kept free of the plugin and the TypeScript compiler so it bundles
|
|
5
|
+
* for edge runtimes, like the other lexicons' `detect` modules.
|
|
6
|
+
*/
|
|
7
|
+
import { looksLikeCollectorConfig } from "./model.js";
|
|
8
|
+
export function detectTemplate(data) {
|
|
9
|
+
return looksLikeCollectorConfig(data) || isObjectConfigOffer(data);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The `{ config, header }` document a host offers for a config it holds as an
|
|
13
|
+
* object, such as an OpenTelemetryCollector's `spec.config` (#3367). `chant
|
|
14
|
+
* import` asks this module which lexicons own what a host offered, so the
|
|
15
|
+
* wrapper has to be recognised here as well as by the importer.
|
|
16
|
+
*/
|
|
17
|
+
function isObjectConfigOffer(data) {
|
|
18
|
+
if (typeof data !== "object" || data === null || Array.isArray(data))
|
|
19
|
+
return false;
|
|
20
|
+
const keys = Object.keys(data);
|
|
21
|
+
return keys.includes("config") && keys.every((k) => k === "config" || k === "header") && looksLikeCollectorConfig(data.config);
|
|
22
|
+
}
|