@intentius/chant-lexicon-otel 0.124.46 → 0.124.48
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/README.md +2 -2
- package/dist/build/capability-plugin.d.ts +10 -0
- package/dist/build/capability-plugin.d.ts.map +1 -0
- package/dist/build/capability-plugin.js +19 -0
- package/dist/build/ocb-build.d.ts +38 -0
- package/dist/build/ocb-build.d.ts.map +1 -0
- package/dist/build/ocb-build.js +49 -0
- package/dist/clickhouse-tables.d.ts +73 -0
- package/dist/clickhouse-tables.d.ts.map +1 -0
- package/dist/clickhouse-tables.js +199 -0
- package/dist/codegen/docs.d.ts.map +1 -1
- package/dist/codegen/docs.js +4 -2
- package/dist/codegen/generate.d.ts +29 -10
- package/dist/codegen/generate.d.ts.map +1 -1
- package/dist/codegen/generate.js +82 -17
- package/dist/components/common.d.ts +3 -1
- package/dist/components/common.d.ts.map +1 -1
- package/dist/components/common.js +2 -0
- package/dist/components/connectors.d.ts +25 -90
- package/dist/components/connectors.d.ts.map +1 -1
- package/dist/components/connectors.js +3 -0
- package/dist/components/exporters.d.ts +78 -34
- package/dist/components/exporters.d.ts.map +1 -1
- package/dist/components/exporters.js +26 -1
- package/dist/components/extensions.d.ts +16 -33
- package/dist/components/extensions.d.ts.map +1 -1
- package/dist/components/filtering.d.ts +13 -60
- package/dist/components/filtering.d.ts.map +1 -1
- package/dist/components/k8s-receivers.d.ts +5 -53
- package/dist/components/k8s-receivers.d.ts.map +1 -1
- package/dist/components/overlay.d.ts +25 -0
- package/dist/components/overlay.d.ts.map +1 -0
- package/dist/components/overlay.js +19 -0
- package/dist/components/processors.d.ts +18 -79
- package/dist/components/processors.d.ts.map +1 -1
- package/dist/components/receivers.d.ts +17 -71
- package/dist/components/receivers.d.ts.map +1 -1
- package/dist/components/receivers.js +3 -1
- package/dist/components/sampling.d.ts +19 -35
- package/dist/components/sampling.d.ts.map +1 -1
- package/dist/config-hygiene.d.ts +10 -8
- package/dist/config-hygiene.d.ts.map +1 -1
- package/dist/config-hygiene.js +36 -13
- package/dist/coverage.d.ts +50 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/coverage.js +92 -0
- package/dist/define.d.ts +8 -5
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +10 -6
- package/dist/distribution.d.ts +125 -0
- package/dist/distribution.d.ts.map +1 -0
- package/dist/distribution.js +227 -0
- package/dist/generated/index.d.ts +4234 -0
- package/dist/generated/index.d.ts.map +1 -0
- package/dist/generated/index.js +23 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/init-templates.js +2 -2
- package/dist/integrity.json +11 -9
- package/dist/lint/audit-catalog.d.ts +3 -0
- package/dist/lint/audit-catalog.d.ts.map +1 -1
- package/dist/lint/audit-catalog.js +5 -0
- package/dist/lint/post-synth/index.d.ts.map +1 -1
- package/dist/lint/post-synth/index.js +4 -0
- package/dist/lint/post-synth/otel-helpers.d.ts +2 -1
- package/dist/lint/post-synth/otel-helpers.d.ts.map +1 -1
- package/dist/lint/post-synth/otel-helpers.js +1 -1
- package/dist/lint/post-synth/otel119.d.ts +1 -1
- package/dist/lint/post-synth/otel119.js +1 -1
- package/dist/lint/post-synth/otel125.d.ts +1 -1
- package/dist/lint/post-synth/otel125.js +1 -1
- package/dist/lint/post-synth/otel126.d.ts +1 -1
- package/dist/lint/post-synth/otel126.js +1 -1
- package/dist/lint/post-synth/otel127.d.ts +1 -1
- package/dist/lint/post-synth/otel127.js +1 -1
- package/dist/lint/post-synth/otel128.d.ts +8 -0
- package/dist/lint/post-synth/otel128.d.ts.map +1 -0
- package/dist/lint/post-synth/otel128.js +17 -0
- package/dist/lint/post-synth/otel129.d.ts +15 -0
- package/dist/lint/post-synth/otel129.d.ts.map +1 -0
- package/dist/lint/post-synth/otel129.js +92 -0
- package/dist/lsp/completions.d.ts +10 -1
- package/dist/lsp/completions.d.ts.map +1 -1
- package/dist/lsp/completions.js +29 -1
- package/dist/lsp/hover.d.ts +5 -1
- package/dist/lsp/hover.d.ts.map +1 -1
- package/dist/lsp/hover.js +16 -3
- package/dist/lsp/properties.d.ts +34 -0
- package/dist/lsp/properties.d.ts.map +1 -0
- package/dist/lsp/properties.js +135 -0
- package/dist/manifest.json +1 -1
- package/dist/meta.json +5 -0
- package/dist/metric-names.d.ts +36 -8
- package/dist/metric-names.d.ts.map +1 -1
- package/dist/metric-names.js +42 -9
- package/dist/model.d.ts +1 -1
- package/dist/model.js +1 -1
- package/dist/okf/index.md +3 -0
- package/dist/okf/rules/OTEL128.md +11 -0
- package/dist/okf/rules/OTEL129.md +11 -0
- package/dist/okf/types/ClickHouseExporter.md +9 -0
- package/dist/op/activities/collector-audit.d.ts +18 -6
- package/dist/op/activities/collector-audit.d.ts.map +1 -1
- package/dist/op/activities/collector-audit.js +37 -21
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +51 -8
- package/dist/rules/otel-helpers.ts +1 -1
- package/dist/rules/otel119.ts +1 -1
- package/dist/rules/otel125.ts +1 -1
- package/dist/rules/otel126.ts +1 -1
- package/dist/rules/otel127.ts +1 -1
- package/dist/rules/otel128.ts +22 -0
- package/dist/rules/otel129.ts +99 -0
- package/dist/serializer.d.ts +3 -0
- package/dist/serializer.d.ts.map +1 -1
- package/dist/serializer.js +12 -2
- package/dist/spec/builtins.d.ts +17 -0
- package/dist/spec/builtins.d.ts.map +1 -0
- package/dist/spec/builtins.js +45 -0
- package/dist/spec/fetch.d.ts +120 -0
- package/dist/spec/fetch.d.ts.map +1 -0
- package/dist/spec/fetch.js +282 -0
- package/dist/spec/parse.d.ts +77 -0
- package/dist/spec/parse.d.ts.map +1 -0
- package/dist/spec/parse.js +337 -0
- package/dist/spec/pin.d.ts +82 -0
- package/dist/spec/pin.d.ts.map +1 -0
- package/dist/spec/pin.js +126 -0
- package/dist/spec/snapshot-cli.d.ts +13 -0
- package/dist/spec/snapshot-cli.d.ts.map +1 -0
- package/dist/spec/snapshot-cli.js +31 -0
- package/dist/spec/snapshot.d.ts +9 -0
- package/dist/spec/snapshot.d.ts.map +1 -0
- package/dist/spec/snapshot.js +14 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/validate-config.d.ts +1 -1
- package/dist/validate-config.d.ts.map +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +1 -0
- package/dist/workspace-links.d.ts +25 -0
- package/dist/workspace-links.d.ts.map +1 -0
- package/dist/workspace-links.js +49 -0
- package/package.json +3 -2
- package/src/build/capability-plugin.ts +30 -0
- package/src/build/ocb-build.ts +73 -0
- package/src/clickhouse-exporter.e2e.test.ts +208 -0
- package/src/clickhouse-tables.test.ts +216 -0
- package/src/clickhouse-tables.ts +223 -0
- package/src/codegen/docs.ts +4 -2
- package/src/codegen/generate.ts +95 -19
- package/src/components/common.ts +4 -2
- package/src/components/connectors.ts +30 -77
- package/src/components/exporters.ts +128 -61
- package/src/components/extensions.ts +22 -36
- package/src/components/filtering.ts +17 -58
- package/src/components/k8s-receivers.test.ts +1 -1
- package/src/components/k8s-receivers.ts +3 -45
- package/src/components/overlay.ts +24 -0
- package/src/components/processors.ts +18 -63
- package/src/components/receivers.ts +20 -60
- package/src/components/sampling.ts +24 -37
- package/src/config-hygiene.ts +36 -13
- package/src/coverage.test.ts +37 -0
- package/src/coverage.ts +121 -0
- package/src/define.test.ts +2 -0
- package/src/define.ts +10 -6
- package/src/distribution.test.ts +250 -0
- package/src/distribution.ts +305 -0
- package/src/generated/index.ts +4576 -0
- package/src/generated/lexicon-otel.json +5 -0
- package/src/generated/properties.json +1 -0
- package/src/import/roundtrip.test.ts +16 -0
- package/src/import/testdata/clickhouse.yaml +37 -0
- package/src/import/testdata/fixtures.ts +17 -2
- package/src/import/testdata/upstream/clickhouse-exporter.yaml +60 -0
- package/src/index.ts +69 -0
- package/src/init-templates.ts +2 -2
- package/src/lint/audit-catalog.ts +15 -0
- package/src/lint/post-synth/index.ts +4 -0
- package/src/lint/post-synth/otel-helpers.ts +1 -1
- package/src/lint/post-synth/otel119.ts +1 -1
- package/src/lint/post-synth/otel125.ts +1 -1
- package/src/lint/post-synth/otel126.ts +1 -1
- package/src/lint/post-synth/otel127.ts +1 -1
- package/src/lint/post-synth/otel128.ts +22 -0
- package/src/lint/post-synth/otel129.ts +99 -0
- package/src/lsp/completions.ts +30 -1
- package/src/lsp/hover.ts +14 -3
- package/src/lsp/properties.test.ts +72 -0
- package/src/lsp/properties.ts +141 -0
- package/src/metric-names.test.ts +11 -0
- package/src/metric-names.ts +64 -16
- package/src/model.ts +1 -1
- package/src/op/activities/collector-audit.test.ts +29 -22
- package/src/op/activities/collector-audit.ts +38 -18
- package/src/plugin.test.ts +2 -0
- package/src/plugin.ts +57 -6
- package/src/serializer.ts +11 -2
- package/src/spec/builtins.ts +56 -0
- package/src/spec/fetch.ts +332 -0
- package/src/spec/otel-schemas.snapshot.json +13932 -0
- package/src/spec/parse.ts +364 -0
- package/src/spec/pin.ts +155 -0
- package/src/spec/snapshot-cli.ts +32 -0
- package/src/spec/snapshot.ts +19 -0
- package/src/spec/spec.test.ts +144 -0
- package/src/validate-config.ts +4 -3
- package/src/validate.ts +1 -0
- package/src/workspace-links.e2e.test.ts +91 -0
- package/src/workspace-links.ts +50 -0
|
@@ -217,6 +217,22 @@ describe("YAML -> TypeScript -> YAML", () => {
|
|
|
217
217
|
expect(out.warnings).toEqual([]);
|
|
218
218
|
});
|
|
219
219
|
|
|
220
|
+
test("a clickhouse exporter imports to the typed class (#4397)", async () => {
|
|
221
|
+
const out = await expectRoundTrip(read("clickhouse.yaml"));
|
|
222
|
+
expect(out.source).toContain("new ClickHouseExporter(");
|
|
223
|
+
expect(out.source).not.toContain("defineComponent");
|
|
224
|
+
expect(out.source).toContain("create_schema: false");
|
|
225
|
+
expect(out.warnings).toEqual([]);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
test("collector-contrib v0.130.0: the clickhouse exporter's own example (#4397)", async () => {
|
|
229
|
+
// fluentforward is not a built-in, so it alone goes through defineComponent; the example's literal password is reported.
|
|
230
|
+
const out = await expectRoundTrip(read("upstream", "clickhouse-exporter.yaml"), { lintRules: ["OTEL002"] });
|
|
231
|
+
expect(out.source).toContain("new ClickHouseExporter(");
|
|
232
|
+
expect(out.source).toMatch(/type: "fluentforward"/);
|
|
233
|
+
expect(out.source).not.toMatch(/type: "clickhouse"/);
|
|
234
|
+
});
|
|
235
|
+
|
|
220
236
|
test("the collector configs of examples/agent-observability", async () => {
|
|
221
237
|
for (const file of ["agent-observability-agent.yaml", "agent-observability-gateway.yaml"]) {
|
|
222
238
|
await expectRoundTrip(read(file));
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# A collector writing every signal to ClickHouse tables the sql lexicon manages (#4397).
|
|
2
|
+
receivers:
|
|
3
|
+
otlp:
|
|
4
|
+
protocols:
|
|
5
|
+
grpc:
|
|
6
|
+
endpoint: 0.0.0.0:4317
|
|
7
|
+
processors:
|
|
8
|
+
batch: {}
|
|
9
|
+
exporters:
|
|
10
|
+
clickhouse:
|
|
11
|
+
endpoint: tcp://clickhouse:9000
|
|
12
|
+
database: otel
|
|
13
|
+
username: ${env:CLICKHOUSE_USER}
|
|
14
|
+
password: ${env:CLICKHOUSE_PASSWORD}
|
|
15
|
+
create_schema: false
|
|
16
|
+
logs_table_name: app_logs
|
|
17
|
+
metrics_tables:
|
|
18
|
+
exponential_histogram:
|
|
19
|
+
name: app_exp_histogram
|
|
20
|
+
sending_queue:
|
|
21
|
+
queue_size: 1000
|
|
22
|
+
retry_on_failure:
|
|
23
|
+
enabled: true
|
|
24
|
+
service:
|
|
25
|
+
pipelines:
|
|
26
|
+
logs:
|
|
27
|
+
receivers: [otlp]
|
|
28
|
+
processors: [batch]
|
|
29
|
+
exporters: [clickhouse]
|
|
30
|
+
traces:
|
|
31
|
+
receivers: [otlp]
|
|
32
|
+
processors: [batch]
|
|
33
|
+
exporters: [clickhouse]
|
|
34
|
+
metrics:
|
|
35
|
+
receivers: [otlp]
|
|
36
|
+
processors: [batch]
|
|
37
|
+
exporters: [clickhouse]
|
|
@@ -183,6 +183,20 @@ export function everyBuiltin(): Declarable[] {
|
|
|
183
183
|
trace: { attribute_mappings: [{ key: "http.route", replacement: "/http/route" }] },
|
|
184
184
|
log: { default_log_name: "otel" },
|
|
185
185
|
});
|
|
186
|
+
const clickhouse = new c.ClickHouseExporter({
|
|
187
|
+
endpoint: "tcp://clickhouse:9000",
|
|
188
|
+
database: "otel",
|
|
189
|
+
username: "${env:CLICKHOUSE_USER}",
|
|
190
|
+
password: "${env:CLICKHOUSE_PASSWORD}",
|
|
191
|
+
create_schema: false,
|
|
192
|
+
ttl: "72h",
|
|
193
|
+
logs_table_name: "app_logs",
|
|
194
|
+
metrics_tables: { gauge: { name: "app_gauge" }, exponential_histogram: { name: "app_exp_histogram" } },
|
|
195
|
+
async_insert: true,
|
|
196
|
+
compress: "zstd",
|
|
197
|
+
timeout: "10s",
|
|
198
|
+
sending_queue: { queue_size: 1000 },
|
|
199
|
+
});
|
|
186
200
|
const loadbalancing = new c.LoadBalancingExporter({
|
|
187
201
|
routing_key: "service",
|
|
188
202
|
protocol: { otlp: { timeout: "1s", tls: { insecure: true } } },
|
|
@@ -266,6 +280,7 @@ export function everyBuiltin(): Declarable[] {
|
|
|
266
280
|
debug,
|
|
267
281
|
prometheusOut,
|
|
268
282
|
googlecloud,
|
|
283
|
+
clickhouse,
|
|
269
284
|
loadbalancing,
|
|
270
285
|
spanmetrics,
|
|
271
286
|
servicegraph,
|
|
@@ -290,13 +305,13 @@ export function everyBuiltin(): Declarable[] {
|
|
|
290
305
|
signal: "metrics",
|
|
291
306
|
receivers: [otlp, prometheusIn, hostmetrics, cluster, kubelet, spanmetrics, servicegraph, count, sum, signalToMetrics],
|
|
292
307
|
processors: [memoryLimiter, filter, deltaToCumulative, batch],
|
|
293
|
-
exporters: [prometheusOut, otlphttp],
|
|
308
|
+
exporters: [prometheusOut, otlphttp, clickhouse],
|
|
294
309
|
}),
|
|
295
310
|
new Pipeline({
|
|
296
311
|
signal: "logs",
|
|
297
312
|
receivers: [otlp, filelog],
|
|
298
313
|
processors: [memoryLimiter, redaction, batch],
|
|
299
|
-
exporters: [otlphttp, debug, signalToMetrics],
|
|
314
|
+
exporters: [otlphttp, debug, signalToMetrics, clickhouse],
|
|
300
315
|
}),
|
|
301
316
|
new Service({
|
|
302
317
|
extensions: [health, zpages, pprof, leaderElector],
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Vendored from opentelemetry-collector-contrib v0.130.0 (Apache-2.0), unchanged below this header:
|
|
2
|
+
# https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/v0.130.0/exporter/clickhouseexporter/example/otel-collector-config.yml
|
|
3
|
+
|
|
4
|
+
receivers:
|
|
5
|
+
fluentforward:
|
|
6
|
+
endpoint: 0.0.0.0:24224
|
|
7
|
+
otlp:
|
|
8
|
+
protocols:
|
|
9
|
+
grpc:
|
|
10
|
+
endpoint: 0.0.0.0:4317
|
|
11
|
+
processors:
|
|
12
|
+
batch:
|
|
13
|
+
send_batch_size: 100000
|
|
14
|
+
timeout: 5s
|
|
15
|
+
memory_limiter:
|
|
16
|
+
check_interval: 2s
|
|
17
|
+
limit_mib: 1800
|
|
18
|
+
spike_limit_mib: 500
|
|
19
|
+
resourcedetection/system:
|
|
20
|
+
detectors: [ "system" ]
|
|
21
|
+
system:
|
|
22
|
+
hostname_sources: [ "os" ]
|
|
23
|
+
resource:
|
|
24
|
+
attributes:
|
|
25
|
+
- key: service.name
|
|
26
|
+
value: "serviceName"
|
|
27
|
+
action: upsert
|
|
28
|
+
exporters:
|
|
29
|
+
clickhouse:
|
|
30
|
+
endpoint: tcp://clickhouse:9000
|
|
31
|
+
database: otel
|
|
32
|
+
logs_table_name: otel_logs
|
|
33
|
+
traces_table_name: otel_traces
|
|
34
|
+
ttl: 12h
|
|
35
|
+
timeout: 10s
|
|
36
|
+
sending_queue:
|
|
37
|
+
queue_size: 100
|
|
38
|
+
retry_on_failure:
|
|
39
|
+
enabled: true
|
|
40
|
+
initial_interval: 5s
|
|
41
|
+
max_interval: 30s
|
|
42
|
+
max_elapsed_time: 300s
|
|
43
|
+
username: default
|
|
44
|
+
password: default
|
|
45
|
+
extensions:
|
|
46
|
+
health_check:
|
|
47
|
+
pprof:
|
|
48
|
+
zpages:
|
|
49
|
+
|
|
50
|
+
service:
|
|
51
|
+
extensions: [ pprof, zpages, health_check ]
|
|
52
|
+
pipelines:
|
|
53
|
+
logs:
|
|
54
|
+
receivers: [ fluentforward, otlp ]
|
|
55
|
+
processors: [ memory_limiter, resourcedetection/system, resource, batch ]
|
|
56
|
+
exporters: [ clickhouse ]
|
|
57
|
+
traces:
|
|
58
|
+
receivers: [ otlp ]
|
|
59
|
+
processors: [ memory_limiter, resourcedetection/system, resource, batch ]
|
|
60
|
+
exporters: [ clickhouse ]
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,48 @@ export { otelSerializer } from "./serializer";
|
|
|
7
7
|
// Built-in components and their config types
|
|
8
8
|
export * from "./components";
|
|
9
9
|
|
|
10
|
+
// The config types generated from upstream config.schema.yaml at COLLECTOR_PIN
|
|
11
|
+
// (#3361), before any hand-written overlay. Each built-in's `<Class>Config`
|
|
12
|
+
// builds on its `<Class>SchemaConfig`.
|
|
13
|
+
export type {
|
|
14
|
+
AttributesProcessorSchemaConfig,
|
|
15
|
+
BatchProcessorSchemaConfig,
|
|
16
|
+
CountConnectorSchemaConfig,
|
|
17
|
+
DebugExporterSchemaConfig,
|
|
18
|
+
DeltaToCumulativeProcessorSchemaConfig,
|
|
19
|
+
FileLogReceiverSchemaConfig,
|
|
20
|
+
FilterProcessorSchemaConfig,
|
|
21
|
+
GoogleCloudExporterSchemaConfig,
|
|
22
|
+
HealthCheckExtensionSchemaConfig,
|
|
23
|
+
HostMetricsReceiverSchemaConfig,
|
|
24
|
+
K8sAttributesProcessorSchemaConfig,
|
|
25
|
+
K8sClusterReceiverSchemaConfig,
|
|
26
|
+
K8sLeaderElectorExtensionSchemaConfig,
|
|
27
|
+
KubeletStatsReceiverSchemaConfig,
|
|
28
|
+
LoadBalancingExporterSchemaConfig,
|
|
29
|
+
MemoryLimiterProcessorSchemaConfig,
|
|
30
|
+
OtlpExporterSchemaConfig,
|
|
31
|
+
OtlpHttpExporterSchemaConfig,
|
|
32
|
+
OtlpReceiverSchemaConfig,
|
|
33
|
+
PprofExtensionSchemaConfig,
|
|
34
|
+
ProbabilisticSamplerProcessorSchemaConfig,
|
|
35
|
+
PrometheusExporterSchemaConfig,
|
|
36
|
+
PrometheusReceiverSchemaConfig,
|
|
37
|
+
RedactionProcessorSchemaConfig,
|
|
38
|
+
ResourceDetectionProcessorSchemaConfig,
|
|
39
|
+
ResourceProcessorSchemaConfig,
|
|
40
|
+
RoutingConnectorSchemaConfig,
|
|
41
|
+
ServiceGraphConnectorSchemaConfig,
|
|
42
|
+
SignalToMetricsConnectorSchemaConfig,
|
|
43
|
+
SpanMetricsConnectorSchemaConfig,
|
|
44
|
+
SumConnectorSchemaConfig,
|
|
45
|
+
TailSamplingProcessorSchemaConfig,
|
|
46
|
+
TransformProcessorSchemaConfig,
|
|
47
|
+
ZPagesExtensionSchemaConfig,
|
|
48
|
+
} from "./generated/index";
|
|
49
|
+
export { coverageReport, formatCoverage, type OtelCoverageReport, type DistributionCoverage } from "./coverage";
|
|
50
|
+
export { OTELCOL_CONTRIB_VERSION, OTELCOL_K8S_VERSION, OTEL_SPEC_PIN, type OtelSpecPin } from "./spec/pin";
|
|
51
|
+
|
|
10
52
|
// Pipelines and the service block
|
|
11
53
|
export {
|
|
12
54
|
Pipeline,
|
|
@@ -168,6 +210,8 @@ export {
|
|
|
168
210
|
type SpanMetricsNames,
|
|
169
211
|
type SpanMetricsNamingConfig,
|
|
170
212
|
type PrometheusNaming,
|
|
213
|
+
type PrometheusTranslationStrategy,
|
|
214
|
+
exporterNaming,
|
|
171
215
|
promSelector,
|
|
172
216
|
promSumRate,
|
|
173
217
|
promErrorRatio,
|
|
@@ -188,3 +232,28 @@ export {
|
|
|
188
232
|
// `@intentius/chant-lexicon-otel/op/activities`.
|
|
189
233
|
export { otelcolValidate, otelcolComponents, collectorHealthObserve, collectorAudit } from "./op/builders";
|
|
190
234
|
export { CollectorAuditOp, type CollectorAuditOpConfig, type CollectorAuditOpResources } from "./op/audit-op";
|
|
235
|
+
|
|
236
|
+
// A custom collector built with ocb (#3374): the builder manifest as an
|
|
237
|
+
// entity, the `ocb-build` build verb, and the check that a config uses only
|
|
238
|
+
// what the distribution builds (OTEL128).
|
|
239
|
+
export {
|
|
240
|
+
Distribution,
|
|
241
|
+
DISTRIBUTION_TYPE,
|
|
242
|
+
DISTRIBUTION_MANIFEST_FILE,
|
|
243
|
+
BUILTIN_MODULES,
|
|
244
|
+
isDistributionEntity,
|
|
245
|
+
distributionManifest,
|
|
246
|
+
distributionYaml,
|
|
247
|
+
distributionComponents,
|
|
248
|
+
distributionIssues,
|
|
249
|
+
componentModule,
|
|
250
|
+
moduleComponentType,
|
|
251
|
+
type DistributionProps,
|
|
252
|
+
type DistributionDist,
|
|
253
|
+
type DistributionModule,
|
|
254
|
+
type DistributionComponent,
|
|
255
|
+
type DistributionEntity,
|
|
256
|
+
type DistributionComponents,
|
|
257
|
+
} from "./distribution";
|
|
258
|
+
export { otelCapabilityPlugin, OTEL_VERB_FAMILIES, ocbBuild } from "./build/capability-plugin";
|
|
259
|
+
export { createOcbBuildCapability, ocbBuildCapability, ocbOutputPath, type OcbBuildInput, type OcbBuildOutput } from "./build/ocb-build";
|
package/src/init-templates.ts
CHANGED
|
@@ -78,8 +78,8 @@ const retry: RetrySettings = { enabled: true, max_elapsed_time: "300s" };
|
|
|
78
78
|
const gateway = new OtlpExporter({ name: "gateway", endpoint: "otel-gateway.observability.svc:4317", tls: inCluster, retry_on_failure: retry });
|
|
79
79
|
|
|
80
80
|
// Resource attributes (k8s.namespace.name, k8s.pod.name, ...) become metric labels.
|
|
81
|
-
const asLabels = {
|
|
82
|
-
const scrape = new PrometheusExporter({ endpoint: "0.0.0.0:8889",
|
|
81
|
+
const asLabels = { included: ["*"] };
|
|
82
|
+
const scrape = new PrometheusExporter({ endpoint: "0.0.0.0:8889", resource_constant_labels: asLabels });
|
|
83
83
|
|
|
84
84
|
export { gateway, scrape };
|
|
85
85
|
`;
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
* OTEL101-OTEL106, OTEL112-OTEL117 and OTEL119-OTEL127 read the emitted collector YAML, so they are
|
|
6
6
|
* `yamlBased`. OTEL118 reads it too, but only in a build that stamps
|
|
7
7
|
* telemetry attribution, so it is not.
|
|
8
|
+
* OTEL128 reads both: the emitted config and the declared `Distribution`.
|
|
9
|
+
* OTEL129 reads both too: the emitted config and the sql lexicon's declared
|
|
10
|
+
* ClickHouse tables.
|
|
8
11
|
* OTEL107-OTEL109 read the declared entities (a component's definition, its
|
|
9
12
|
* schema pin), which a standalone YAML file does not carry, so they are
|
|
10
13
|
* constructed with `yamlBased: false`. The two source-level lint rules are
|
|
@@ -233,4 +236,16 @@ export const otelAuditCatalog: Record<string, RuleMeta> = {
|
|
|
233
236
|
"Name detectors as the processor registers them (elastic_beanstalk, not elasticbeanstalk), or remove the entry.",
|
|
234
237
|
{ category: "correctness" },
|
|
235
238
|
),
|
|
239
|
+
OTEL128: entityRule(
|
|
240
|
+
"OTEL128",
|
|
241
|
+
"correctness",
|
|
242
|
+
"Collector config uses a component the declared Distribution does not build",
|
|
243
|
+
"Add the component to the Distribution's list for its kind, or remove it from the collector config.",
|
|
244
|
+
),
|
|
245
|
+
OTEL129: entityRule(
|
|
246
|
+
"OTEL129",
|
|
247
|
+
"correctness",
|
|
248
|
+
"A clickhouse exporter writes a table or column the sql build in the same root does not declare",
|
|
249
|
+
"Declare the exporter's tables with OtelTables from the sql lexicon, or point the exporter's table names at declared tables, and set create_schema: false.",
|
|
250
|
+
),
|
|
236
251
|
};
|
|
@@ -25,6 +25,8 @@ import { otel124 } from "./otel124";
|
|
|
25
25
|
import { otel125 } from "./otel125";
|
|
26
26
|
import { otel126 } from "./otel126";
|
|
27
27
|
import { otel127 } from "./otel127";
|
|
28
|
+
import { otel128 } from "./otel128";
|
|
29
|
+
import { otel129 } from "./otel129";
|
|
28
30
|
|
|
29
31
|
export const postSynthChecks: PostSynthCheck[] = [
|
|
30
32
|
otel101,
|
|
@@ -52,4 +54,6 @@ export const postSynthChecks: PostSynthCheck[] = [
|
|
|
52
54
|
otel125,
|
|
53
55
|
otel126,
|
|
54
56
|
otel127,
|
|
57
|
+
otel128,
|
|
58
|
+
otel129,
|
|
55
59
|
];
|
|
@@ -68,7 +68,7 @@ export function collectorConfigs(ctx: PostSynthContext): FoundCollectorConfig[]
|
|
|
68
68
|
return out;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
function toDiagnostic(issue: CollectorIssue, found?: Omit<FoundCollectorConfig, "config">): PostSynthDiagnostic {
|
|
71
|
+
export function toDiagnostic(issue: CollectorIssue, found?: Omit<FoundCollectorConfig, "config">): PostSynthDiagnostic {
|
|
72
72
|
const where = found?.configMap
|
|
73
73
|
? describeConfigMapConfig(found.configMap)
|
|
74
74
|
: found?.operator
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OTEL119: A collector config sets a field deprecated at or before the pinned release
|
|
3
3
|
*
|
|
4
|
-
* `invert_match: true` in a `tail_sampling` policy (inverted decisions are deprecated in collector-contrib v0.126.0 for a `drop` policy), `service.telemetry.metrics.address` (deprecated in collector v0.111.0 for `readers`), and `dimensions_cache_size` on `spanmetrics` (deprecated in collector-contrib v0.125.0 for `aggregation_cardinality_limit`). The collector still
|
|
4
|
+
* `invert_match: true` in a `tail_sampling` policy (inverted decisions are deprecated in collector-contrib v0.126.0 for a `drop` policy, and v0.155.0 removed the gate that kept them), `service.telemetry.metrics.address` (deprecated in collector v0.111.0 for `readers`), and `dimensions_cache_size` on `spanmetrics` (deprecated in collector-contrib v0.125.0 for `aggregation_cardinality_limit`). The collector still parses each at v0.162.0, and a later release drops it.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OTEL125: A pipeline sends to a remote otlp or otlphttp exporter without batching
|
|
3
3
|
*
|
|
4
|
-
* No `batch` processor in the pipeline, and the `otlp` or `otlphttp` exporter (non-loopback endpoint) sets no `sending_queue.batch`. At v0.
|
|
4
|
+
* No `batch` processor in the pipeline, and the `otlp` or `otlphttp` exporter (non-loopback endpoint) sets no `sending_queue.batch`. At v0.162.0 neither exporter batches by default, so each small request goes out on its own. Other exporters may batch themselves and are not checked.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OTEL126: k8sattributes extracts a metadata field it does not support
|
|
3
3
|
*
|
|
4
|
-
* Each name in a `k8sattributes` processor's `extract.metadata` must be one `Config.Validate` accepts at collector-contrib v0.
|
|
4
|
+
* Each name in a `k8sattributes` processor's `extract.metadata` must be one `Config.Validate` accepts at collector-contrib v0.162.0 (`K8S_ATTRIBUTES_METADATA`); the collector refuses any other.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OTEL127: resourcedetection lists a detector that does not exist
|
|
3
3
|
*
|
|
4
|
-
* Each name in a started `resourcedetection` processor's `detectors` must be one the processor registers at collector-contrib v0.
|
|
4
|
+
* Each name in a started `resourcedetection` processor's `detectors` must be one the processor registers at collector-contrib v0.162.0 (`RESOURCE_DETECTORS`); any other fails the processor's build and the collector exits.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OTEL128: The collector config uses a component the declared Distribution does not build
|
|
3
|
+
*
|
|
4
|
+
* When a project declares a `Distribution` (an ocb builder manifest), every component a collector config declares must be one the distribution builds; a collector built from it fails at start with "unknown type" otherwise. A project without a `Distribution` is not checked.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
8
|
+
import { distributionIssues, isDistributionEntity } from "../../distribution";
|
|
9
|
+
import { collectorConfigs, toDiagnostic } from "./otel-helpers";
|
|
10
|
+
|
|
11
|
+
export const otel128: PostSynthCheck = {
|
|
12
|
+
id: "OTEL128",
|
|
13
|
+
description: "The collector config uses a component the declared Distribution does not build",
|
|
14
|
+
|
|
15
|
+
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
16
|
+
const dist = [...(ctx.entities?.values() ?? [])].find(isDistributionEntity);
|
|
17
|
+
if (!dist) return [];
|
|
18
|
+
return collectorConfigs(ctx).flatMap(({ config, ...found }) =>
|
|
19
|
+
distributionIssues(config, dist).map((i) => toDiagnostic(i, found)),
|
|
20
|
+
);
|
|
21
|
+
},
|
|
22
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OTEL129: A clickhouse exporter writes a table the sql build in the same root does not declare
|
|
3
|
+
*
|
|
4
|
+
* When the build root also declares ClickHouse tables with the sql lexicon, every table a `clickhouse` exporter writes (for the signals whose pipelines use it) must be one of them, in the database the exporter writes to, with every column the exporter's insert statement names. A renamed or dropped table fails here instead of at the exporter's first insert. When `create_schema` is true (the exporter's default) for tables the build declares, it warns: the exporter would run its own `CREATE TABLE IF NOT EXISTS` beside the sql lexicon's plan. A build root with no sql ClickHouse tables is not checked. Sees one build root at a time (#1939); across workspace members the otel lexicon's workspace links check the same tables (#3931).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
8
|
+
import type { Declarable } from "@intentius/chant/declarable";
|
|
9
|
+
import { clickhouseExportersOf } from "../../clickhouse-tables";
|
|
10
|
+
import { collectorConfigs } from "./otel-helpers";
|
|
11
|
+
|
|
12
|
+
/** The sql lexicon's ClickHouse table entity type, matched by name so otel needs no dependency on the sql lexicon. */
|
|
13
|
+
const CLICKHOUSE_TABLE = "ClickHouse::Table";
|
|
14
|
+
|
|
15
|
+
interface DeclaredTable {
|
|
16
|
+
columns: Set<string>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Every ClickHouse table the build declares, by `database.name`. */
|
|
20
|
+
export function declaredClickHouseTables(entities: Iterable<Declarable>): Map<string, DeclaredTable> {
|
|
21
|
+
const out = new Map<string, DeclaredTable>();
|
|
22
|
+
for (const e of entities) {
|
|
23
|
+
if (e.entityType !== CLICKHOUSE_TABLE) continue;
|
|
24
|
+
const props = (e as unknown as { props?: { name?: unknown; database?: unknown; columns?: unknown } }).props;
|
|
25
|
+
if (typeof props?.name !== "string") continue;
|
|
26
|
+
const database = typeof props.database === "string" && props.database !== "" ? props.database : "default";
|
|
27
|
+
const columns = new Set<string>();
|
|
28
|
+
for (const c of Array.isArray(props.columns) ? props.columns : []) {
|
|
29
|
+
const name = (c as { name?: unknown })?.name;
|
|
30
|
+
if (typeof name === "string") columns.add(name);
|
|
31
|
+
}
|
|
32
|
+
out.set(`${database}.${props.name}`, { columns });
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** A column the insert names is declared as itself, or as the flattened fields of a Nested column (`Events.Timestamp`). */
|
|
38
|
+
function hasColumn(declared: Set<string>, column: string): boolean {
|
|
39
|
+
if (declared.has(column)) return true;
|
|
40
|
+
for (const c of declared) if (c.startsWith(`${column}.`)) return true;
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const otel129: PostSynthCheck = {
|
|
45
|
+
id: "OTEL129",
|
|
46
|
+
description: "A clickhouse exporter writes a table the sql build in the same root does not declare",
|
|
47
|
+
|
|
48
|
+
check(ctx: PostSynthContext): PostSynthDiagnostic[] {
|
|
49
|
+
const declared = declaredClickHouseTables(ctx.entities?.values() ?? []);
|
|
50
|
+
if (declared.size === 0) return [];
|
|
51
|
+
const known = [...declared.keys()].sort();
|
|
52
|
+
const diagnostics: PostSynthDiagnostic[] = [];
|
|
53
|
+
for (const { config } of collectorConfigs(ctx)) {
|
|
54
|
+
for (const exp of clickhouseExportersOf(config)) {
|
|
55
|
+
const createsDeclared: string[] = [];
|
|
56
|
+
for (const t of exp.tables) {
|
|
57
|
+
const qualified = `${exp.database}.${t.name}`;
|
|
58
|
+
const table = declared.get(qualified);
|
|
59
|
+
if (!table) {
|
|
60
|
+
diagnostics.push({
|
|
61
|
+
checkId: "OTEL129",
|
|
62
|
+
severity: "error",
|
|
63
|
+
message:
|
|
64
|
+
`exporter ${exp.id} writes ${t.signal} to ${qualified} (${t.key}), which the sql build does not declare. ` +
|
|
65
|
+
`Declare it (OtelTables from @intentius/chant-lexicon-sql/clickhouse declares the exporter's tables) or point ${t.key} at a declared table. ` +
|
|
66
|
+
`Declared ClickHouse tables: ${known.join(", ")}`,
|
|
67
|
+
entity: exp.id,
|
|
68
|
+
lexicon: "otel",
|
|
69
|
+
});
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const missing = t.columns.filter((c) => !hasColumn(table.columns, c));
|
|
73
|
+
if (missing.length > 0) {
|
|
74
|
+
diagnostics.push({
|
|
75
|
+
checkId: "OTEL129",
|
|
76
|
+
severity: "error",
|
|
77
|
+
message: `exporter ${exp.id} inserts ${t.signal} into ${qualified} with column${missing.length === 1 ? "" : "s"} ${missing.join(", ")}, which the declared table does not have; the insert would fail`,
|
|
78
|
+
entity: exp.id,
|
|
79
|
+
lexicon: "otel",
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
createsDeclared.push(qualified);
|
|
83
|
+
}
|
|
84
|
+
if (exp.createSchema && createsDeclared.length > 0) {
|
|
85
|
+
diagnostics.push({
|
|
86
|
+
checkId: "OTEL129",
|
|
87
|
+
severity: "warning",
|
|
88
|
+
message:
|
|
89
|
+
`exporter ${exp.id} has create_schema true (the default), so at start it runs CREATE TABLE IF NOT EXISTS for ${createsDeclared.join(", ")}, which the sql build declares. ` +
|
|
90
|
+
`Set create_schema: false so the sql lexicon alone manages them`,
|
|
91
|
+
entity: exp.id,
|
|
92
|
+
lexicon: "otel",
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return diagnostics;
|
|
98
|
+
},
|
|
99
|
+
};
|
package/src/lsp/completions.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { CompletionContext, CompletionItem } from "@intentius/chant/lsp/types";
|
|
2
2
|
import { LexiconIndex, lexiconCompletions } from "@intentius/chant/lsp/lexicon-providers";
|
|
3
3
|
import { lexiconRegistry } from "../catalog";
|
|
4
|
+
import { propertiesAt, propertyMarkdown, propertyPosition } from "./properties";
|
|
4
5
|
|
|
5
6
|
let cachedIndex: LexiconIndex | null = null;
|
|
6
7
|
|
|
@@ -9,7 +10,35 @@ function getIndex(): LexiconIndex {
|
|
|
9
10
|
return cachedIndex;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
/**
|
|
13
|
+
/** The text of `content` before the cursor. */
|
|
14
|
+
export function textBefore(content: string, position: { line: number; character: number }): string {
|
|
15
|
+
const lines = content.split("\n");
|
|
16
|
+
return [...lines.slice(0, position.line), (lines[position.line] ?? "").slice(0, position.character)].join("\n");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Completions for the otel entity classes after `new`, and inside a built-in's
|
|
21
|
+
* constructor, the config properties at the cursor's depth, with upstream's
|
|
22
|
+
* descriptions (#3361).
|
|
23
|
+
*/
|
|
13
24
|
export function completions(ctx: CompletionContext): CompletionItem[] {
|
|
25
|
+
if (ctx?.content && ctx.position && !/\bnew\s+\w*$/.test(ctx.linePrefix ?? "")) {
|
|
26
|
+
const position = propertyPosition(textBefore(ctx.content, ctx.position));
|
|
27
|
+
const props = position && propertiesAt(position);
|
|
28
|
+
if (position && props) {
|
|
29
|
+
const prefix = (ctx.wordAtCursor ?? "").toLowerCase();
|
|
30
|
+
return Object.entries(props)
|
|
31
|
+
.filter(([name]) => name.toLowerCase().startsWith(prefix))
|
|
32
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
33
|
+
.map(([name, doc]) => ({
|
|
34
|
+
label: name,
|
|
35
|
+
insertText: name,
|
|
36
|
+
kind: "property" as const,
|
|
37
|
+
detail: doc.type,
|
|
38
|
+
documentation: propertyMarkdown(name, doc, position.className),
|
|
39
|
+
...(doc.deprecated ? { deprecated: true } : {}),
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
14
43
|
return lexiconCompletions(ctx, getIndex(), "OpenTelemetry Collector entity");
|
|
15
44
|
}
|
package/src/lsp/hover.ts
CHANGED
|
@@ -2,6 +2,8 @@ import type { HoverContext, HoverInfo } from "@intentius/chant/lsp/types";
|
|
|
2
2
|
import { LexiconIndex, lexiconHover, type LexiconEntry } from "@intentius/chant/lsp/lexicon-providers";
|
|
3
3
|
import { BUILTIN_CATALOG, lexiconRegistry } from "../catalog";
|
|
4
4
|
import { COLLECTOR_PIN } from "../define";
|
|
5
|
+
import { propertiesAt, propertyMarkdown, propertyPosition } from "./properties";
|
|
6
|
+
import { textBefore } from "./completions";
|
|
5
7
|
|
|
6
8
|
let cachedIndex: LexiconIndex | null = null;
|
|
7
9
|
|
|
@@ -10,9 +12,18 @@ function getIndex(): LexiconIndex {
|
|
|
10
12
|
return cachedIndex;
|
|
11
13
|
}
|
|
12
14
|
|
|
13
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* Hover for otel entity classes (what the component does and its collector
|
|
17
|
+
* id), and for a config property inside a built-in's constructor (upstream's
|
|
18
|
+
* description, #3361).
|
|
19
|
+
*/
|
|
14
20
|
export function hover(ctx: HoverContext): HoverInfo | undefined {
|
|
15
|
-
|
|
21
|
+
const entity = lexiconHover(ctx, getIndex(), resourceHover);
|
|
22
|
+
if (entity) return entity;
|
|
23
|
+
if (!ctx?.content || !ctx.position || !ctx.word) return undefined;
|
|
24
|
+
const position = propertyPosition(textBefore(ctx.content, ctx.position));
|
|
25
|
+
const doc = position && propertiesAt(position)?.[ctx.word];
|
|
26
|
+
return position && doc ? { contents: propertyMarkdown(ctx.word, doc, position.className) } : undefined;
|
|
16
27
|
}
|
|
17
28
|
|
|
18
29
|
function resourceHover(className: string, entry: LexiconEntry): HoverInfo | undefined {
|
|
@@ -23,7 +34,7 @@ function resourceHover(className: string, entry: LexiconEntry): HoverInfo | unde
|
|
|
23
34
|
lines.push(
|
|
24
35
|
"",
|
|
25
36
|
`Collector id \`${cat.type}\`, or \`${cat.type}/<name>\` with \`name\` set. ` +
|
|
26
|
-
`Config typed
|
|
37
|
+
`Config typed from upstream config.schema.yaml at ${COLLECTOR_PIN.source} ${COLLECTOR_PIN.version}.`,
|
|
27
38
|
);
|
|
28
39
|
}
|
|
29
40
|
return { contents: lines.join("\n") };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { afterEach, describe, expect, test } from "vitest";
|
|
2
|
+
import { propertiesAt, propertyPosition, setPropertyTrees } from "./properties";
|
|
3
|
+
import { completions } from "./completions";
|
|
4
|
+
import { hover } from "./hover";
|
|
5
|
+
|
|
6
|
+
const TREES = {
|
|
7
|
+
OtlpReceiver: {
|
|
8
|
+
protocols: {
|
|
9
|
+
type: "object",
|
|
10
|
+
description: "Protocols is the configuration for the supported protocols.",
|
|
11
|
+
properties: {
|
|
12
|
+
grpc: { type: "object", properties: { endpoint: { type: "string", description: "Endpoint to listen on." } } },
|
|
13
|
+
http: { type: "object" },
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
TailSamplingProcessor: {
|
|
18
|
+
decision_wait: { type: "duration" },
|
|
19
|
+
policies: { type: "object[]", properties: { name: { type: "string" }, latency: { type: "object", properties: { threshold_ms: { type: "number" } } } } },
|
|
20
|
+
num_traces: { type: "number", deprecated: true },
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
afterEach(() => setPropertyTrees(undefined));
|
|
25
|
+
|
|
26
|
+
describe("property positions", () => {
|
|
27
|
+
test("the keys of the objects around the cursor, through lists", () => {
|
|
28
|
+
expect(propertyPosition("new OtlpReceiver({ ")).toEqual({ className: "OtlpReceiver", path: [] });
|
|
29
|
+
expect(propertyPosition("new OtlpReceiver({ protocols: { grpc: { ")).toEqual({ className: "OtlpReceiver", path: ["protocols", "grpc"] });
|
|
30
|
+
expect(propertyPosition('new OtlpReceiver({ protocols: { http: {}, "grpc": { ')).toEqual({ className: "OtlpReceiver", path: ["protocols", "grpc"] });
|
|
31
|
+
expect(propertyPosition('new TailSamplingProcessor({ policies: [{ name: "a" }, { latency: { ')).toEqual({
|
|
32
|
+
className: "TailSamplingProcessor",
|
|
33
|
+
path: ["policies", "latency"],
|
|
34
|
+
});
|
|
35
|
+
expect(propertyPosition("new OtlpReceiver({ protocols: {} });\nconst x = { ")).toBeUndefined();
|
|
36
|
+
expect(propertyPosition("const x = { ")).toBeUndefined();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("the properties at a path", () => {
|
|
40
|
+
setPropertyTrees(TREES);
|
|
41
|
+
expect(Object.keys(propertiesAt({ className: "OtlpReceiver", path: ["protocols"] })!)).toEqual(["grpc", "http"]);
|
|
42
|
+
expect(propertiesAt({ className: "OtlpReceiver", path: ["nope"] })).toBeUndefined();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
describe("completion and hover", () => {
|
|
47
|
+
const at = (content: string, word = "") => {
|
|
48
|
+
const lines = content.split("\n");
|
|
49
|
+
return { uri: "file:///c.ts", content, position: { line: lines.length - 1, character: lines[lines.length - 1].length }, wordAtCursor: word, linePrefix: lines[lines.length - 1] };
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
test("offers the properties at the cursor's depth, with upstream's description", () => {
|
|
53
|
+
setPropertyTrees(TREES);
|
|
54
|
+
const items = completions(at("const r = new OtlpReceiver({ protocols: { grpc: { "));
|
|
55
|
+
expect(items.map((i) => i.label)).toEqual(["endpoint"]);
|
|
56
|
+
expect(items[0].documentation).toContain("Endpoint to listen on.");
|
|
57
|
+
const top = completions(at("new TailSamplingProcessor({ num", "num"));
|
|
58
|
+
expect(top).toEqual([expect.objectContaining({ label: "num_traces", detail: "number", deprecated: true })]);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("still offers the classes after new", () => {
|
|
62
|
+
setPropertyTrees(TREES);
|
|
63
|
+
expect(completions(at("const r = new Otlp", "Otlp")).map((i) => i.label)).toContain("OtlpReceiver");
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("hovers a property with its description", () => {
|
|
67
|
+
setPropertyTrees(TREES);
|
|
68
|
+
const content = "new OtlpReceiver({ protocols";
|
|
69
|
+
const info = hover({ uri: "file:///c.ts", content, position: { line: 0, character: 19 }, word: "protocols", lineText: content });
|
|
70
|
+
expect(info?.contents).toContain("Protocols is the configuration for the supported protocols.");
|
|
71
|
+
});
|
|
72
|
+
});
|