@intentius/chant-lexicon-otel 0.124.31 → 0.124.32

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.
Files changed (96) hide show
  1. package/dist/attribution.js +391 -0
  2. package/dist/catalog.js +42 -0
  3. package/dist/codegen/docs-cli.js +3 -0
  4. package/dist/codegen/docs.js +101 -0
  5. package/dist/codegen/generate-cli.js +7 -0
  6. package/dist/codegen/generate.js +43 -0
  7. package/dist/codegen/package.js +28 -0
  8. package/dist/collector.js +150 -0
  9. package/dist/components/common.js +50 -0
  10. package/dist/components/connectors.js +242 -0
  11. package/dist/components/exporters.js +57 -0
  12. package/dist/components/extensions.js +58 -0
  13. package/dist/components/filtering.js +106 -0
  14. package/dist/components/index.js +9 -0
  15. package/dist/components/k8s-receivers.js +36 -0
  16. package/dist/components/processors.js +103 -0
  17. package/dist/components/receivers.js +61 -0
  18. package/dist/components/sampling.js +257 -0
  19. package/dist/composites/catalog.js +368 -0
  20. package/dist/composites/genai-pipeline.js +28 -0
  21. package/dist/composites/index.js +8 -0
  22. package/dist/composites/node-agent.js +156 -0
  23. package/dist/composites/otlp-collector.js +57 -0
  24. package/dist/composites/red-metrics.js +95 -0
  25. package/dist/composites/tail-sampling-tier.js +132 -0
  26. package/dist/config-hygiene.js +464 -0
  27. package/dist/configmap.js +86 -0
  28. package/dist/define.js +204 -0
  29. package/dist/detect.js +22 -0
  30. package/dist/genai.js +569 -0
  31. package/dist/import/embedded.js +57 -0
  32. package/dist/import/generator.js +459 -0
  33. package/dist/import/parser.js +199 -0
  34. package/dist/index.js +34 -0
  35. package/dist/init-templates.js +119 -0
  36. package/dist/integrity.json +2 -2
  37. package/dist/lint/audit-catalog.js +49 -0
  38. package/dist/lint/post-synth/index.js +52 -0
  39. package/dist/lint/post-synth/otel-helpers.js +103 -0
  40. package/dist/lint/post-synth/otel101.js +13 -0
  41. package/dist/lint/post-synth/otel102.js +13 -0
  42. package/dist/lint/post-synth/otel103.js +13 -0
  43. package/dist/lint/post-synth/otel104.js +13 -0
  44. package/dist/lint/post-synth/otel105.js +13 -0
  45. package/dist/lint/post-synth/otel106.js +13 -0
  46. package/dist/lint/post-synth/otel107.js +13 -0
  47. package/dist/lint/post-synth/otel108.js +13 -0
  48. package/dist/lint/post-synth/otel109.js +13 -0
  49. package/dist/lint/post-synth/otel112.js +13 -0
  50. package/dist/lint/post-synth/otel113.js +13 -0
  51. package/dist/lint/post-synth/otel114.js +13 -0
  52. package/dist/lint/post-synth/otel115.js +13 -0
  53. package/dist/lint/post-synth/otel116.js +13 -0
  54. package/dist/lint/post-synth/otel117.js +13 -0
  55. package/dist/lint/post-synth/otel118.js +13 -0
  56. package/dist/lint/post-synth/otel119.js +13 -0
  57. package/dist/lint/post-synth/otel120.js +13 -0
  58. package/dist/lint/post-synth/otel121.js +13 -0
  59. package/dist/lint/post-synth/otel122.js +13 -0
  60. package/dist/lint/post-synth/otel123.js +13 -0
  61. package/dist/lint/post-synth/otel124.js +13 -0
  62. package/dist/lint/post-synth/otel125.js +13 -0
  63. package/dist/lint/post-synth/otel126.js +13 -0
  64. package/dist/lint/post-synth/otel127.js +13 -0
  65. package/dist/lint/rules/component-id-syntax.js +66 -0
  66. package/dist/lint/rules/index.js +6 -0
  67. package/dist/lint/rules/literal-credential.js +91 -0
  68. package/dist/lint/rules/otel-ast.js +30 -0
  69. package/dist/lsp/completions.js +11 -0
  70. package/dist/lsp/hover.js +23 -0
  71. package/dist/manifest.json +1 -1
  72. package/dist/metric-names.js +244 -0
  73. package/dist/model.js +90 -0
  74. package/dist/op/activities/collector-audit.js +213 -0
  75. package/dist/op/activities/collector-health.js +176 -0
  76. package/dist/op/activities/exec.js +16 -0
  77. package/dist/op/activities/github.js +110 -0
  78. package/dist/op/activities/index.js +16 -0
  79. package/dist/op/activities/otelcol.js +173 -0
  80. package/dist/op/activity-contracts.js +64 -0
  81. package/dist/op/audit-op.js +33 -0
  82. package/dist/op/builders.js +38 -0
  83. package/dist/package-cli.js +14 -0
  84. package/dist/pipeline.js +31 -0
  85. package/dist/platform.js +144 -0
  86. package/dist/plugin.js +126 -0
  87. package/dist/semconv.js +50 -0
  88. package/dist/serializer.js +26 -0
  89. package/dist/skill-defs.js +34 -0
  90. package/dist/topology.js +104 -0
  91. package/dist/validate-cli.js +7 -0
  92. package/dist/validate-config.js +706 -0
  93. package/dist/validate.js +85 -0
  94. package/dist/yaml.js +157 -0
  95. package/package.json +8 -8
  96. 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
+ }