@intentius/chant-lexicon-otel 0.97.0 → 0.98.0
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 +5 -0
- package/dist/codegen/docs.d.ts.map +1 -1
- package/dist/import/generator.d.ts +39 -0
- package/dist/import/generator.d.ts.map +1 -0
- package/dist/import/parser.d.ts +61 -0
- package/dist/import/parser.d.ts.map +1 -0
- package/dist/integrity.json +4 -4
- package/dist/lint/rules/literal-credential.d.ts.map +1 -1
- package/dist/manifest.json +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/rules/literal-credential.ts +46 -17
- package/dist/skills/chant-otel.md +11 -0
- package/package.json +2 -2
- package/src/codegen/docs.ts +2 -1
- package/src/import/generated-types.e2e.test.ts +75 -0
- package/src/import/generator.test.ts +165 -0
- package/src/import/generator.ts +509 -0
- package/src/import/parser.test.ts +174 -0
- package/src/import/parser.ts +236 -0
- package/src/import/roundtrip.test.ts +365 -0
- package/src/import/testdata/agent-observability-agent.yaml +54 -0
- package/src/import/testdata/agent-observability-gateway.yaml +128 -0
- package/src/import/testdata/fixtures.ts +274 -0
- package/src/import/testdata/gateway.yaml +153 -0
- package/src/import/testdata/upstream/couchbase.yaml +150 -0
- package/src/import/testdata/upstream/fault-tolerant-logs.yaml +27 -0
- package/src/import/testdata/upstream/kubernetes-filelog.yaml +86 -0
- package/src/import/testdata/upstream/loadbalancing-agent.yaml +38 -0
- package/src/import/testdata/upstream/loadbalancing-backend.yaml +27 -0
- package/src/import/testdata/upstream/logline-filter-in.yaml +20 -0
- package/src/import/testdata/upstream/logline-filter-out.yaml +20 -0
- package/src/import/testdata/upstream/secure-tracing.yaml +26 -0
- package/src/import/testdata/upstream/servicegraph-nop.yaml +28 -0
- package/src/lint/rules/literal-credential.ts +46 -17
- package/src/lint/rules/rules.test.ts +16 -0
- package/src/plugin.ts +10 -0
- package/src/skills/chant-otel.md +11 -0
|
@@ -0,0 +1,150 @@
|
|
|
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/examples/couchbase/otel-collector-config.yaml
|
|
3
|
+
|
|
4
|
+
receivers:
|
|
5
|
+
prometheus/couchbase:
|
|
6
|
+
config:
|
|
7
|
+
scrape_configs:
|
|
8
|
+
- job_name: 'couchbase'
|
|
9
|
+
scrape_interval: 5s
|
|
10
|
+
static_configs:
|
|
11
|
+
- targets: ['couchbase:8091']
|
|
12
|
+
basic_auth:
|
|
13
|
+
username: 'otelu'
|
|
14
|
+
password: 'otelpassword'
|
|
15
|
+
metric_relabel_configs:
|
|
16
|
+
# Include only a few key metrics
|
|
17
|
+
- source_labels: [ __name__ ]
|
|
18
|
+
regex: "(kv_ops)|\
|
|
19
|
+
(kv_vb_curr_items)|\
|
|
20
|
+
(kv_num_vbuckets)|\
|
|
21
|
+
(kv_ep_cursor_memory_freed_bytes)|\
|
|
22
|
+
(kv_total_memory_used_bytes)|\
|
|
23
|
+
(kv_ep_num_value_ejects)|\
|
|
24
|
+
(kv_ep_mem_high_wat)|\
|
|
25
|
+
(kv_ep_mem_low_wat)|\
|
|
26
|
+
(kv_ep_tmp_oom_errors)|\
|
|
27
|
+
(kv_ep_oom_errors)"
|
|
28
|
+
action: keep
|
|
29
|
+
|
|
30
|
+
processors:
|
|
31
|
+
filter/couchbase:
|
|
32
|
+
# Filter out prometheus scraping meta-metrics.
|
|
33
|
+
metrics:
|
|
34
|
+
exclude:
|
|
35
|
+
match_type: strict
|
|
36
|
+
metric_names:
|
|
37
|
+
- scrape_samples_post_metric_relabeling
|
|
38
|
+
- scrape_series_added
|
|
39
|
+
- scrape_duration_seconds
|
|
40
|
+
- scrape_samples_scraped
|
|
41
|
+
- up
|
|
42
|
+
|
|
43
|
+
metricstransform/couchbase:
|
|
44
|
+
transforms:
|
|
45
|
+
# Rename from prometheus metric name to OTel metric name.
|
|
46
|
+
# We cannot do this with metric_relabel_configs, as the prometheus receiver does not
|
|
47
|
+
# allow metric renames at this time.
|
|
48
|
+
- include: kv_ops
|
|
49
|
+
match_type: strict
|
|
50
|
+
action: update
|
|
51
|
+
new_name: "couchbase.bucket.operation.count"
|
|
52
|
+
- include: kv_vb_curr_items
|
|
53
|
+
match_type: strict
|
|
54
|
+
action: update
|
|
55
|
+
new_name: "couchbase.bucket.item.count"
|
|
56
|
+
- include: kv_num_vbuckets
|
|
57
|
+
match_type: strict
|
|
58
|
+
action: update
|
|
59
|
+
new_name: "couchbase.bucket.vbucket.count"
|
|
60
|
+
- include: kv_ep_cursor_memory_freed_bytes
|
|
61
|
+
match_type: strict
|
|
62
|
+
action: update
|
|
63
|
+
new_name: "couchbase.bucket.memory.usage.free"
|
|
64
|
+
- include: kv_total_memory_used_bytes
|
|
65
|
+
match_type: strict
|
|
66
|
+
action: update
|
|
67
|
+
new_name: "couchbase.bucket.memory.usage.used"
|
|
68
|
+
- include: kv_ep_num_value_ejects
|
|
69
|
+
match_type: strict
|
|
70
|
+
action: update
|
|
71
|
+
new_name: "couchbase.bucket.item.ejection.count"
|
|
72
|
+
- include: kv_ep_mem_high_wat
|
|
73
|
+
match_type: strict
|
|
74
|
+
action: update
|
|
75
|
+
new_name: "couchbase.bucket.memory.high_water_mark.limit"
|
|
76
|
+
- include: kv_ep_mem_low_wat
|
|
77
|
+
match_type: strict
|
|
78
|
+
action: update
|
|
79
|
+
new_name: "couchbase.bucket.memory.low_water_mark.limit"
|
|
80
|
+
- include: kv_ep_tmp_oom_errors
|
|
81
|
+
match_type: strict
|
|
82
|
+
action: update
|
|
83
|
+
new_name: "couchbase.bucket.error.oom.count.recoverable"
|
|
84
|
+
- include: kv_ep_oom_errors
|
|
85
|
+
match_type: strict
|
|
86
|
+
action: update
|
|
87
|
+
new_name: "couchbase.bucket.error.oom.count.unrecoverable"
|
|
88
|
+
# Combine couchbase.bucket.error.oom.count.x and couchbase.bucket.memory.usage.x
|
|
89
|
+
# metrics.
|
|
90
|
+
- include: '^couchbase\.bucket\.error\.oom\.count\.(?P<error_type>unrecoverable|recoverable)$$'
|
|
91
|
+
match_type: regexp
|
|
92
|
+
action: combine
|
|
93
|
+
new_name: "couchbase.bucket.error.oom.count"
|
|
94
|
+
- include: '^couchbase\.bucket\.memory\.usage\.(?P<state>free|used)$$'
|
|
95
|
+
match_type: regexp
|
|
96
|
+
action: combine
|
|
97
|
+
new_name: "couchbase.bucket.memory.usage"
|
|
98
|
+
# Aggregate "result" label on operation count to keep label sets consistent across the metric datapoints
|
|
99
|
+
- include: 'couchbase.bucket.operation.count'
|
|
100
|
+
match_type: strict
|
|
101
|
+
action: update
|
|
102
|
+
operations:
|
|
103
|
+
- action: aggregate_labels
|
|
104
|
+
label_set: ["bucket", "op"]
|
|
105
|
+
aggregation_type: sum
|
|
106
|
+
|
|
107
|
+
transform/couchbase:
|
|
108
|
+
metric_statements:
|
|
109
|
+
- context: datapoint
|
|
110
|
+
statements:
|
|
111
|
+
- convert_gauge_to_sum("cumulative", true) where metric.name == "couchbase.bucket.operation.count"
|
|
112
|
+
- set(metric.description, "Number of operations on the bucket.") where metric.name == "couchbase.bucket.operation.count"
|
|
113
|
+
- set(metric.unit, "{operations}") where metric.name == "couchbase.bucket.operation.count"
|
|
114
|
+
|
|
115
|
+
- convert_gauge_to_sum("cumulative", false) where metric.name == "couchbase.bucket.item.count"
|
|
116
|
+
- set(metric.description, "Number of items that belong to the bucket.") where metric.name == "couchbase.bucket.item.count"
|
|
117
|
+
- set(metric.unit, "{items}") where metric.name == "couchbase.bucket.item.count"
|
|
118
|
+
|
|
119
|
+
- convert_gauge_to_sum("cumulative", false) where metric.name == "couchbase.bucket.vbucket.count"
|
|
120
|
+
- set(metric.description, "Number of non-resident vBuckets.") where metric.name == "couchbase.bucket.vbucket.count"
|
|
121
|
+
- set(metric.unit, "{vbuckets}") where metric.name == "couchbase.bucket.vbucket.count"
|
|
122
|
+
|
|
123
|
+
- convert_gauge_to_sum("cumulative", false) where metric.name == "couchbase.bucket.memory.usage"
|
|
124
|
+
- set(metric.description, "Usage of total memory available to the bucket.") where metric.name == "couchbase.bucket.memory.usage"
|
|
125
|
+
- set(metric.unit, "By") where metric.name == "couchbase.bucket.memory.usage"
|
|
126
|
+
|
|
127
|
+
- convert_gauge_to_sum("cumulative", true) where metric.name == "couchbase.bucket.item.ejection.count"
|
|
128
|
+
- set(metric.description, "Number of item value ejections from memory to disk.") where metric.name == "couchbase.bucket.item.ejection.count"
|
|
129
|
+
- set(metric.unit, "{ejections}") where metric.name == "couchbase.bucket.item.ejection.count"
|
|
130
|
+
|
|
131
|
+
- convert_gauge_to_sum("cumulative", true) where metric.name == "couchbase.bucket.error.oom.count"
|
|
132
|
+
- set(metric.description, "Number of out of memory errors.") where metric.name == "couchbase.bucket.error.oom.count"
|
|
133
|
+
- set(metric.unit, "{errors}") where metric.name == "couchbase.bucket.error.oom.count"
|
|
134
|
+
|
|
135
|
+
- set(metric.description, "The memory usage at which items will be ejected.") where metric.name == "couchbase.bucket.memory.high_water_mark.limit"
|
|
136
|
+
- set(metric.unit, "By") where metric.name == "couchbase.bucket.memory.high_water_mark.limit"
|
|
137
|
+
|
|
138
|
+
- set(metric.description, "The memory usage at which ejections will stop that were previously triggered by a high water mark breach.") where metric.name == "couchbase.bucket.memory.low_water_mark.limit"
|
|
139
|
+
- set(metric.unit, "By") where metric.name == "couchbase.bucket.memory.low_water_mark.limit"
|
|
140
|
+
|
|
141
|
+
exporters:
|
|
142
|
+
prometheus:
|
|
143
|
+
endpoint: "0.0.0.0:9123"
|
|
144
|
+
|
|
145
|
+
service:
|
|
146
|
+
pipelines:
|
|
147
|
+
metrics/couchbase:
|
|
148
|
+
receivers: [prometheus/couchbase]
|
|
149
|
+
processors: [filter/couchbase, metricstransform/couchbase, transform/couchbase]
|
|
150
|
+
exporters: [prometheus]
|
|
@@ -0,0 +1,27 @@
|
|
|
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/examples/fault-tolerant-logs-collection/otel-col-config.yaml
|
|
3
|
+
|
|
4
|
+
receivers:
|
|
5
|
+
filelog:
|
|
6
|
+
include: [/var/log/busybox/simple.log]
|
|
7
|
+
storage: file_storage/filelogreceiver
|
|
8
|
+
|
|
9
|
+
extensions:
|
|
10
|
+
file_storage/filelogreceiver:
|
|
11
|
+
directory: /var/lib/otelcol/file_storage/receiver
|
|
12
|
+
file_storage/otlpoutput:
|
|
13
|
+
directory: /var/lib/otelcol/file_storage/output
|
|
14
|
+
|
|
15
|
+
service:
|
|
16
|
+
extensions: [file_storage/filelogreceiver, file_storage/otlpoutput]
|
|
17
|
+
pipelines:
|
|
18
|
+
logs:
|
|
19
|
+
receivers: [filelog]
|
|
20
|
+
exporters: [otlp/custom]
|
|
21
|
+
processors: []
|
|
22
|
+
|
|
23
|
+
exporters:
|
|
24
|
+
otlp/custom:
|
|
25
|
+
endpoint: http://0.0.0.0:4242
|
|
26
|
+
sending_queue:
|
|
27
|
+
storage: file_storage/otlpoutput
|
|
@@ -0,0 +1,86 @@
|
|
|
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/examples/kubernetes/otel-collector-config.yml
|
|
3
|
+
|
|
4
|
+
receivers:
|
|
5
|
+
filelog:
|
|
6
|
+
include:
|
|
7
|
+
- /var/log/pods/*/*/*.log
|
|
8
|
+
exclude:
|
|
9
|
+
# Exclude logs from all containers named otel-collector
|
|
10
|
+
- /var/log/pods/*/otel-collector/*.log
|
|
11
|
+
start_at: end
|
|
12
|
+
include_file_path: true
|
|
13
|
+
include_file_name: false
|
|
14
|
+
operators:
|
|
15
|
+
# Find out which format is used by kubernetes
|
|
16
|
+
- type: router
|
|
17
|
+
id: get-format
|
|
18
|
+
routes:
|
|
19
|
+
- output: parser-docker
|
|
20
|
+
expr: 'body matches "^\\{"'
|
|
21
|
+
- output: parser-crio
|
|
22
|
+
expr: 'body matches "^[^ Z]+ "'
|
|
23
|
+
- output: parser-containerd
|
|
24
|
+
expr: 'body matches "^[^ Z]+Z"'
|
|
25
|
+
# Parse CRI-O format
|
|
26
|
+
- type: regex_parser
|
|
27
|
+
id: parser-crio
|
|
28
|
+
regex: '^(?P<time>[^ Z]+) (?P<stream>stdout|stderr) (?P<logtag>[^ ]*) ?(?P<log>.*)$'
|
|
29
|
+
output: extract_metadata_from_filepath
|
|
30
|
+
timestamp:
|
|
31
|
+
parse_from: attributes.time
|
|
32
|
+
layout_type: gotime
|
|
33
|
+
layout: '2006-01-02T15:04:05.999999999Z07:00'
|
|
34
|
+
# Parse CRI-Containerd format
|
|
35
|
+
- type: regex_parser
|
|
36
|
+
id: parser-containerd
|
|
37
|
+
regex: '^(?P<time>[^ ^Z]+Z) (?P<stream>stdout|stderr) (?P<logtag>[^ ]*) ?(?P<log>.*)$'
|
|
38
|
+
output: extract_metadata_from_filepath
|
|
39
|
+
timestamp:
|
|
40
|
+
parse_from: attributes.time
|
|
41
|
+
layout: '%Y-%m-%dT%H:%M:%S.%LZ'
|
|
42
|
+
# Parse Docker format
|
|
43
|
+
- type: json_parser
|
|
44
|
+
id: parser-docker
|
|
45
|
+
output: extract_metadata_from_filepath
|
|
46
|
+
timestamp:
|
|
47
|
+
parse_from: attributes.time
|
|
48
|
+
layout: '%Y-%m-%dT%H:%M:%S.%LZ'
|
|
49
|
+
# Extract metadata from file path
|
|
50
|
+
- type: regex_parser
|
|
51
|
+
id: extract_metadata_from_filepath
|
|
52
|
+
regex: '^.*\/(?P<namespace>[^_]+)_(?P<pod_name>[^_]+)_(?P<uid>[a-f0-9\-]{36})\/(?P<container_name>[^\._]+)\/(?P<restart_count>\d+)\.log$'
|
|
53
|
+
parse_from: attributes["log.file.path"]
|
|
54
|
+
cache:
|
|
55
|
+
size: 128 # default maximum amount of Pods per Node is 110
|
|
56
|
+
# Update body field after finishing all parsing
|
|
57
|
+
- type: move
|
|
58
|
+
from: attributes.log
|
|
59
|
+
to: body
|
|
60
|
+
# Rename attributes
|
|
61
|
+
- type: move
|
|
62
|
+
from: attributes.stream
|
|
63
|
+
to: attributes["log.iostream"]
|
|
64
|
+
- type: move
|
|
65
|
+
from: attributes.container_name
|
|
66
|
+
to: resource["k8s.container.name"]
|
|
67
|
+
- type: move
|
|
68
|
+
from: attributes.namespace
|
|
69
|
+
to: resource["k8s.namespace.name"]
|
|
70
|
+
- type: move
|
|
71
|
+
from: attributes.pod_name
|
|
72
|
+
to: resource["k8s.pod.name"]
|
|
73
|
+
- type: move
|
|
74
|
+
from: attributes.restart_count
|
|
75
|
+
to: resource["k8s.container.restart_count"]
|
|
76
|
+
- type: move
|
|
77
|
+
from: attributes.uid
|
|
78
|
+
to: resource["k8s.pod.uid"]
|
|
79
|
+
exporters:
|
|
80
|
+
debug:
|
|
81
|
+
verbosity: detailed
|
|
82
|
+
service:
|
|
83
|
+
pipelines:
|
|
84
|
+
logs:
|
|
85
|
+
receivers: [filelog]
|
|
86
|
+
exporters: [debug]
|
|
@@ -0,0 +1,38 @@
|
|
|
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/loadbalancingexporter/example/otel-agent-config.yaml
|
|
3
|
+
|
|
4
|
+
receivers:
|
|
5
|
+
fluentforward:
|
|
6
|
+
endpoint: 0.0.0.0:24224
|
|
7
|
+
|
|
8
|
+
processors:
|
|
9
|
+
batch:
|
|
10
|
+
|
|
11
|
+
exporters:
|
|
12
|
+
debug:
|
|
13
|
+
verbosity: detailed
|
|
14
|
+
loadbalancing:
|
|
15
|
+
protocol:
|
|
16
|
+
otlp:
|
|
17
|
+
timeout: 1s
|
|
18
|
+
tls:
|
|
19
|
+
insecure: true
|
|
20
|
+
resolver:
|
|
21
|
+
static:
|
|
22
|
+
hostnames:
|
|
23
|
+
- otel-collector-1:4317
|
|
24
|
+
- otel-collector-2:4317
|
|
25
|
+
- otel-collector-3:4317
|
|
26
|
+
|
|
27
|
+
extensions:
|
|
28
|
+
health_check:
|
|
29
|
+
pprof:
|
|
30
|
+
zpages:
|
|
31
|
+
|
|
32
|
+
service:
|
|
33
|
+
extensions: [pprof, zpages, health_check]
|
|
34
|
+
pipelines:
|
|
35
|
+
logs:
|
|
36
|
+
receivers: [fluentforward]
|
|
37
|
+
processors: [batch]
|
|
38
|
+
exporters: [loadbalancing, debug]
|
|
@@ -0,0 +1,27 @@
|
|
|
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/loadbalancingexporter/example/otel-collector-config.yaml
|
|
3
|
+
|
|
4
|
+
receivers:
|
|
5
|
+
otlp:
|
|
6
|
+
protocols:
|
|
7
|
+
grpc:
|
|
8
|
+
|
|
9
|
+
processors:
|
|
10
|
+
batch:
|
|
11
|
+
|
|
12
|
+
exporters:
|
|
13
|
+
debug:
|
|
14
|
+
verbosity: detailed
|
|
15
|
+
|
|
16
|
+
extensions:
|
|
17
|
+
health_check:
|
|
18
|
+
pprof:
|
|
19
|
+
zpages:
|
|
20
|
+
|
|
21
|
+
service:
|
|
22
|
+
extensions: [pprof, zpages, health_check]
|
|
23
|
+
pipelines:
|
|
24
|
+
logs:
|
|
25
|
+
receivers: [otlp]
|
|
26
|
+
processors: [batch]
|
|
27
|
+
exporters: [debug]
|
|
@@ -0,0 +1,20 @@
|
|
|
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/examples/logline-filtering/otel-col-config-filter-in-logs.yaml
|
|
3
|
+
|
|
4
|
+
receivers:
|
|
5
|
+
filelog:
|
|
6
|
+
include: [/var/log/busybox/simple.log]
|
|
7
|
+
operators:
|
|
8
|
+
- type: filter
|
|
9
|
+
expr: 'body not matches "^WARN:"'
|
|
10
|
+
|
|
11
|
+
service:
|
|
12
|
+
pipelines:
|
|
13
|
+
logs:
|
|
14
|
+
receivers: [filelog]
|
|
15
|
+
exporters: [otlp/custom]
|
|
16
|
+
processors: []
|
|
17
|
+
|
|
18
|
+
exporters:
|
|
19
|
+
otlp/custom:
|
|
20
|
+
endpoint: http://0.0.0.0:4242
|
|
@@ -0,0 +1,20 @@
|
|
|
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/examples/logline-filtering/otel-col-config-filter-out-logs.yaml
|
|
3
|
+
|
|
4
|
+
receivers:
|
|
5
|
+
filelog:
|
|
6
|
+
include: [/var/log/busybox/simple.log]
|
|
7
|
+
operators:
|
|
8
|
+
- type: filter
|
|
9
|
+
expr: 'body matches "^INFO:"'
|
|
10
|
+
|
|
11
|
+
service:
|
|
12
|
+
pipelines:
|
|
13
|
+
logs:
|
|
14
|
+
receivers: [filelog]
|
|
15
|
+
exporters: [otlp/custom]
|
|
16
|
+
processors: []
|
|
17
|
+
|
|
18
|
+
exporters:
|
|
19
|
+
otlp/custom:
|
|
20
|
+
endpoint: http://0.0.0.0:4242
|
|
@@ -0,0 +1,26 @@
|
|
|
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/examples/secure-tracing/otel-collector-config.yaml
|
|
3
|
+
|
|
4
|
+
receivers:
|
|
5
|
+
otlp:
|
|
6
|
+
protocols:
|
|
7
|
+
grpc:
|
|
8
|
+
endpoint: 0.0.0.0:55690
|
|
9
|
+
tls:
|
|
10
|
+
cert_file: /etc/otel-collector.crt
|
|
11
|
+
key_file: /etc/otel-collector.key
|
|
12
|
+
|
|
13
|
+
processors:
|
|
14
|
+
batch:
|
|
15
|
+
|
|
16
|
+
exporters:
|
|
17
|
+
debug:
|
|
18
|
+
verbosity: detailed
|
|
19
|
+
|
|
20
|
+
service:
|
|
21
|
+
pipelines:
|
|
22
|
+
traces:
|
|
23
|
+
receivers: [otlp]
|
|
24
|
+
processors: [batch]
|
|
25
|
+
exporters: [debug]
|
|
26
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
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/connector/servicegraphconnector/testdata/service-graph-connector-config.yaml
|
|
3
|
+
|
|
4
|
+
receivers:
|
|
5
|
+
nop:
|
|
6
|
+
|
|
7
|
+
exporters:
|
|
8
|
+
nop:
|
|
9
|
+
|
|
10
|
+
connectors:
|
|
11
|
+
servicegraph:
|
|
12
|
+
latency_histogram_buckets: [1,2,3,4,5]
|
|
13
|
+
dimensions:
|
|
14
|
+
- dimension-1
|
|
15
|
+
- dimension-2
|
|
16
|
+
store:
|
|
17
|
+
ttl: 1s
|
|
18
|
+
max_items: 10
|
|
19
|
+
database_name_attributes: [db.name]
|
|
20
|
+
|
|
21
|
+
service:
|
|
22
|
+
pipelines:
|
|
23
|
+
traces:
|
|
24
|
+
receivers: [nop]
|
|
25
|
+
exporters: [servicegraph]
|
|
26
|
+
metrics:
|
|
27
|
+
receivers: [servicegraph]
|
|
28
|
+
exporters: [nop]
|
|
@@ -25,25 +25,54 @@ export const literalCredentialRule: LintRule = {
|
|
|
25
25
|
const diagnostics: LintDiagnostic[] = [];
|
|
26
26
|
const source = context.sourceFile;
|
|
27
27
|
|
|
28
|
+
// `const x = { ... }` (or `[...]`, or a string) anywhere in the file, so a
|
|
29
|
+
// config value lifted out of the constructor into a named const, the way
|
|
30
|
+
// COR001 asks, is scanned where it is used.
|
|
31
|
+
const consts = new Map<string, ts.Expression>();
|
|
32
|
+
const collect = (node: ts.Node) => {
|
|
33
|
+
if (ts.isVariableDeclarationList(node) && node.flags & ts.NodeFlags.Const) {
|
|
34
|
+
for (const d of node.declarations) {
|
|
35
|
+
if (ts.isIdentifier(d.name) && d.initializer) consts.set(d.name.text, d.initializer);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
ts.forEachChild(node, collect);
|
|
39
|
+
};
|
|
40
|
+
collect(source);
|
|
41
|
+
|
|
42
|
+
const flag = (key: string, node: ts.Node) =>
|
|
43
|
+
diagnostics.push({
|
|
44
|
+
ruleId: "OTEL002",
|
|
45
|
+
severity: "error",
|
|
46
|
+
message: `\`${key}\` is a literal credential; write "\${env:NAME}" (or "\${file:/path}") and let the collector read it at start-up`,
|
|
47
|
+
file: context.filePath,
|
|
48
|
+
...position(source, node),
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const scanned = new Set<ts.Node>();
|
|
52
|
+
const scanValue = (key: string | undefined, value: ts.Expression) => {
|
|
53
|
+
let init: ts.Expression = value;
|
|
54
|
+
if (ts.isIdentifier(init)) {
|
|
55
|
+
const resolved = consts.get(init.text);
|
|
56
|
+
if (!resolved) return;
|
|
57
|
+
init = resolved;
|
|
58
|
+
}
|
|
59
|
+
if (ts.isObjectLiteralExpression(init) || ts.isArrayLiteralExpression(init)) {
|
|
60
|
+
if (scanned.has(init)) return;
|
|
61
|
+
scanned.add(init);
|
|
62
|
+
if (ts.isObjectLiteralExpression(init)) scan(init);
|
|
63
|
+
else for (const el of init.elements) scanValue(undefined, el as ts.Expression);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (!key || !SECRET_KEY.test(key) || /_file$/i.test(key)) return;
|
|
67
|
+
const text = literalText(init);
|
|
68
|
+
if (text === undefined || text === "" || text.includes("${")) return;
|
|
69
|
+
flag(key, value);
|
|
70
|
+
};
|
|
71
|
+
|
|
28
72
|
const scan = (obj: ts.ObjectLiteralExpression) => {
|
|
29
73
|
for (const prop of obj.properties) {
|
|
30
|
-
if (
|
|
31
|
-
|
|
32
|
-
const init = prop.initializer;
|
|
33
|
-
if (ts.isObjectLiteralExpression(init)) {
|
|
34
|
-
scan(init);
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
if (!key || !SECRET_KEY.test(key) || /_file$/i.test(key)) continue;
|
|
38
|
-
const text = literalText(init);
|
|
39
|
-
if (text === undefined || text === "" || text.includes("${")) continue;
|
|
40
|
-
diagnostics.push({
|
|
41
|
-
ruleId: "OTEL002",
|
|
42
|
-
severity: "error",
|
|
43
|
-
message: `\`${key}\` is a literal credential; write "\${env:NAME}" (or "\${file:/path}") and let the collector read it at start-up`,
|
|
44
|
-
file: context.filePath,
|
|
45
|
-
...position(source, init),
|
|
46
|
-
});
|
|
74
|
+
if (ts.isShorthandPropertyAssignment(prop)) scanValue(prop.name.text, prop.name);
|
|
75
|
+
else if (ts.isPropertyAssignment(prop)) scanValue(propertyName(prop), prop.initializer);
|
|
47
76
|
}
|
|
48
77
|
};
|
|
49
78
|
|
|
@@ -67,4 +67,20 @@ describe("OTEL002 literal credential", () => {
|
|
|
67
67
|
);
|
|
68
68
|
expect(diags).toEqual([]);
|
|
69
69
|
});
|
|
70
|
+
|
|
71
|
+
test("follows config lifted into named consts, and looks inside lists", () => {
|
|
72
|
+
const diags = literalCredentialRule.check(
|
|
73
|
+
ctx(`
|
|
74
|
+
const headers: OtlpExporterConfig["headers"] = { authorization: "Bearer abc123" };
|
|
75
|
+
const safe = { authorization: "Bearer \${env:TOKEN}" };
|
|
76
|
+
const token = "literal";
|
|
77
|
+
const config = { scrape_configs: [{ job_name: "x", basic_auth: { username: "u", password: "p" } }] };
|
|
78
|
+
new OtlpExporter({ endpoint: "x:4317", headers });
|
|
79
|
+
new OtlpExporter({ name: "b", endpoint: "x:4317", headers: safe });
|
|
80
|
+
new SplunkHecExporter({ token, endpoint: "https://hec" });
|
|
81
|
+
new PrometheusReceiver({ config });
|
|
82
|
+
`),
|
|
83
|
+
);
|
|
84
|
+
expect(diags.map((d) => d.message.split("`")[1])).toEqual(["authorization", "token", "password"]);
|
|
85
|
+
});
|
|
70
86
|
});
|
package/src/plugin.ts
CHANGED
|
@@ -9,6 +9,8 @@ import { otelAuditCatalog } from "./lint/audit-catalog";
|
|
|
9
9
|
import { completions } from "./lsp/completions";
|
|
10
10
|
import { hover } from "./lsp/hover";
|
|
11
11
|
import { detectTemplate } from "./detect";
|
|
12
|
+
import { OtelCollectorParser } from "./import/parser";
|
|
13
|
+
import { OtelCollectorGenerator } from "./import/generator";
|
|
12
14
|
import { otelSkills } from "./skill-defs";
|
|
13
15
|
import { BUILTIN_CATALOG } from "./catalog";
|
|
14
16
|
import { COLLECTOR_PIN } from "./define";
|
|
@@ -96,6 +98,14 @@ export const otelPlugin: LexiconPlugin = {
|
|
|
96
98
|
return detectTemplate(data);
|
|
97
99
|
},
|
|
98
100
|
|
|
101
|
+
templateParser() {
|
|
102
|
+
return new OtelCollectorParser();
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
templateGenerator() {
|
|
106
|
+
return new OtelCollectorGenerator();
|
|
107
|
+
},
|
|
108
|
+
|
|
99
109
|
completionProvider(ctx: CompletionContext) {
|
|
100
110
|
return completions(ctx);
|
|
101
111
|
},
|
package/src/skills/chant-otel.md
CHANGED
|
@@ -78,6 +78,17 @@ It deletes prompt, completion, system-instruction and tool-call content from spa
|
|
|
78
78
|
- Every pipeline needs at least one receiver and one exporter (OTEL102). A declared component no pipeline uses is a warning (OTEL103).
|
|
79
79
|
- Declared extensions are enabled in declaration order unless a `Service` lists `extensions` itself.
|
|
80
80
|
|
|
81
|
+
## Starting from an existing config
|
|
82
|
+
|
|
83
|
+
When the user already has a collector config file, import it rather than retyping it:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
chant import otel-collector-config.yaml --output src
|
|
87
|
+
chant build src --lexicon otel -o collector.yaml # the same config back
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The importer writes `receivers.ts`, `processors.ts`, `exporters.ts`, `connectors.ts`, `extensions.ts`, `pipelines.ts`, and `service.ts` when extensions or telemetry need a `Service`. A component type with no built-in class lands in `custom-components.ts` as a `defineComponent` whose config is untyped data; offer to give it a config interface. Settings outside a built-in's config type still import and build, but `tsc` flags them. Read the warnings `chant import` prints: they name anything the lexicon has no place for.
|
|
91
|
+
|
|
81
92
|
## Reading the result
|
|
82
93
|
|
|
83
94
|
`collectorTopologyOf(entities)` returns the pipelines, each component's endpoints and schema pin, for each exporter the signals it carries, the connector `edges` between pipelines, and under `semconv` the semantic-conventions version (`GENAI_SEMCONV_PIN`) the config's `gen_ai.` keys follow, as plain data.
|