@intentius/chant-lexicon-otel 0.97.0 → 0.99.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.
Files changed (54) hide show
  1. package/README.md +5 -0
  2. package/dist/codegen/docs.d.ts.map +1 -1
  3. package/dist/components/common.d.ts +7 -2
  4. package/dist/components/common.d.ts.map +1 -1
  5. package/dist/components/filtering.d.ts +58 -1
  6. package/dist/components/filtering.d.ts.map +1 -1
  7. package/dist/components/processors.d.ts +10 -0
  8. package/dist/components/processors.d.ts.map +1 -1
  9. package/dist/components/receivers.d.ts +87 -7
  10. package/dist/components/receivers.d.ts.map +1 -1
  11. package/dist/import/embedded.d.ts +12 -0
  12. package/dist/import/embedded.d.ts.map +1 -0
  13. package/dist/import/generator.d.ts +39 -0
  14. package/dist/import/generator.d.ts.map +1 -0
  15. package/dist/import/parser.d.ts +61 -0
  16. package/dist/import/parser.d.ts.map +1 -0
  17. package/dist/integrity.json +4 -4
  18. package/dist/lint/rules/literal-credential.d.ts.map +1 -1
  19. package/dist/manifest.json +1 -1
  20. package/dist/plugin.d.ts.map +1 -1
  21. package/dist/rules/literal-credential.ts +46 -17
  22. package/dist/skills/chant-otel.md +11 -0
  23. package/package.json +2 -2
  24. package/src/codegen/docs.ts +2 -1
  25. package/src/components/common.ts +7 -2
  26. package/src/components/filtering.test.ts +27 -0
  27. package/src/components/filtering.ts +65 -2
  28. package/src/components/processors.ts +4 -0
  29. package/src/components/receivers.ts +88 -4
  30. package/src/import/embedded.test.ts +56 -0
  31. package/src/import/embedded.ts +41 -0
  32. package/src/import/generated-types.e2e.test.ts +110 -0
  33. package/src/import/generator.test.ts +165 -0
  34. package/src/import/generator.ts +509 -0
  35. package/src/import/parser.test.ts +174 -0
  36. package/src/import/parser.ts +236 -0
  37. package/src/import/roundtrip.test.ts +365 -0
  38. package/src/import/testdata/agent-observability-agent.yaml +54 -0
  39. package/src/import/testdata/agent-observability-gateway.yaml +128 -0
  40. package/src/import/testdata/fixtures.ts +274 -0
  41. package/src/import/testdata/gateway.yaml +153 -0
  42. package/src/import/testdata/upstream/couchbase.yaml +150 -0
  43. package/src/import/testdata/upstream/fault-tolerant-logs.yaml +27 -0
  44. package/src/import/testdata/upstream/kubernetes-filelog.yaml +86 -0
  45. package/src/import/testdata/upstream/loadbalancing-agent.yaml +38 -0
  46. package/src/import/testdata/upstream/loadbalancing-backend.yaml +27 -0
  47. package/src/import/testdata/upstream/logline-filter-in.yaml +20 -0
  48. package/src/import/testdata/upstream/logline-filter-out.yaml +20 -0
  49. package/src/import/testdata/upstream/secure-tracing.yaml +26 -0
  50. package/src/import/testdata/upstream/servicegraph-nop.yaml +28 -0
  51. package/src/lint/rules/literal-credential.ts +46 -17
  52. package/src/lint/rules/rules.test.ts +16 -0
  53. package/src/plugin.ts +15 -0
  54. package/src/skills/chant-otel.md +11 -0
@@ -0,0 +1,274 @@
1
+ /**
2
+ * Fixtures shared by the import round-trip tests (roundtrip.test.ts) and the
3
+ * type-check of the generated source (generated-types.e2e.test.ts).
4
+ */
5
+ import { readdirSync, readFileSync, statSync } from "fs";
6
+ import { join, resolve } from "path";
7
+ import { build } from "@intentius/chant/build";
8
+ import type { SerializerResult } from "@intentius/chant/serializer";
9
+ import type { Declarable } from "@intentius/chant/declarable";
10
+ import { otelSerializer } from "../../serializer";
11
+ import { Pipeline, Service } from "../../pipeline";
12
+ import * as c from "../../components";
13
+
14
+ export const pkgDir = resolve(import.meta.dirname, "../../..");
15
+ export const repoRoot = resolve(pkgDir, "../..");
16
+ export const read = (...p: string[]) => readFileSync(join(import.meta.dirname, ...p), "utf-8");
17
+
18
+ export function primary(out: string | SerializerResult | undefined): string {
19
+ if (out === undefined) return "";
20
+ return typeof out === "string" ? out : out.primary;
21
+ }
22
+
23
+ /** Each otel example's `chant build` output. */
24
+ export async function exampleOutputs(): Promise<Array<[string, string]>> {
25
+ const examplesDir = join(pkgDir, "examples");
26
+ const out: Array<[string, string]> = [];
27
+ for (const name of readdirSync(examplesDir).sort()) {
28
+ const srcDir = join(examplesDir, name, "src");
29
+ try {
30
+ if (!statSync(srcDir).isDirectory()) continue;
31
+ } catch {
32
+ continue;
33
+ }
34
+ const result = await build(srcDir, [otelSerializer]);
35
+ if (result.errors.length > 0) throw new Error(`${name}: ${result.errors.map(String).join("; ")}`);
36
+ out.push([name, primary(result.outputs.get("otel"))]);
37
+ }
38
+ return out;
39
+ }
40
+
41
+ export const UPSTREAM_BUILTIN_ONLY = [
42
+ "kubernetes-filelog.yaml",
43
+ "logline-filter-in.yaml",
44
+ "logline-filter-out.yaml",
45
+ "secure-tracing.yaml",
46
+ "loadbalancing-backend.yaml",
47
+ ];
48
+
49
+ /** One instance of every built-in, each using its typed fields, wired into pipelines the connectors accept. */
50
+ export function everyBuiltin(): Declarable[] {
51
+ const otlp = new c.OtlpReceiver({
52
+ protocols: {
53
+ grpc: { endpoint: "0.0.0.0:4317", max_recv_msg_size_mib: 16, keepalive: { server_parameters: { time: "30s" } } },
54
+ http: { endpoint: "0.0.0.0:4318", cors: { allowed_origins: ["https://*.example.com"] }, traces_url_path: "/v1/traces" },
55
+ },
56
+ });
57
+ const prometheusIn = new c.PrometheusReceiver({
58
+ name: "self",
59
+ config: {
60
+ global: { scrape_interval: "30s" },
61
+ scrape_configs: [{ job_name: "collector", scrape_interval: "10s", static_configs: [{ targets: ["localhost:8888"], labels: { tier: "gw" } }] }],
62
+ },
63
+ trim_metric_suffixes: true,
64
+ });
65
+ const hostmetrics = new c.HostMetricsReceiver({
66
+ collection_interval: "30s",
67
+ root_path: "/hostfs",
68
+ scrapers: { cpu: {}, memory: {}, filesystem: { exclude_mount_points: { match_type: "regexp", mount_points: ["/dev/.*"] } } },
69
+ });
70
+ const filelog = new c.FileLogReceiver({
71
+ include: ["/var/log/pods/*/*/*.log"],
72
+ exclude: ["/var/log/pods/*/otel-collector/*.log"],
73
+ start_at: "end",
74
+ include_file_path: true,
75
+ storage: "file_storage",
76
+ operators: [{ type: "container", id: "container-parser" }],
77
+ retry_on_failure: { enabled: true, initial_interval: "1s" },
78
+ });
79
+ const cluster = new c.K8sClusterReceiver({
80
+ auth_type: "serviceAccount",
81
+ collection_interval: "30s",
82
+ node_conditions_to_report: ["Ready", "MemoryPressure"],
83
+ allocatable_types_to_report: ["cpu", "memory"],
84
+ metrics: { "k8s.pod.phase": { enabled: false } },
85
+ });
86
+ const kubelet = new c.KubeletStatsReceiver({
87
+ auth_type: "serviceAccount",
88
+ endpoint: "https://${env:K8S_NODE_NAME}:10250",
89
+ insecure_skip_verify: true,
90
+ metric_groups: ["node", "pod", "container"],
91
+ extra_metadata_labels: ["container.id"],
92
+ });
93
+
94
+ const batch = new c.BatchProcessor({ timeout: "5s", send_batch_size: 1024, send_batch_max_size: 2048, metadata_keys: ["tenant"] });
95
+ const memoryLimiter = new c.MemoryLimiterProcessor({ check_interval: "1s", limit_mib: 1024, spike_limit_mib: 256 });
96
+ const resource = new c.ResourceProcessor({
97
+ attributes: [
98
+ { key: "deployment.environment", value: "${env:DEPLOY_ENV}", action: "upsert" },
99
+ { key: "host.id", action: "delete" },
100
+ ],
101
+ });
102
+ const attributes = new c.AttributesProcessor({
103
+ name: "scrub",
104
+ actions: [
105
+ { key: "user.email", action: "hash" },
106
+ { key: "http.status_code", action: "convert", converted_type: "int" },
107
+ ],
108
+ include: { match_type: "strict", services: ["checkout"] },
109
+ });
110
+ const k8sattributes = new c.K8sAttributesProcessor({
111
+ auth_type: "serviceAccount",
112
+ passthrough: false,
113
+ filter: { node_from_env_var: "K8S_NODE_NAME" },
114
+ extract: { metadata: ["k8s.pod.name", "k8s.namespace.name"], labels: [{ tag_name: "app", key: "app.kubernetes.io/name", from: "pod" }] },
115
+ pod_association: [{ sources: [{ from: "resource_attribute", name: "k8s.pod.ip" }] }, { sources: [{ from: "connection" }] }],
116
+ });
117
+ const resourcedetection = new c.ResourceDetectionProcessor({
118
+ detectors: ["env", "system", "gcp"],
119
+ timeout: "2s",
120
+ override: false,
121
+ system: { hostname_sources: ["os"] },
122
+ });
123
+ const filter = new c.FilterProcessor({
124
+ name: "health",
125
+ error_mode: "ignore",
126
+ traces: { span: ['attributes["http.route"] == "/healthz"'] },
127
+ metrics: { datapoint: ['metric.name == "up" and value_int == 1'] },
128
+ logs: { log_record: ["severity_number < SEVERITY_NUMBER_INFO"] },
129
+ });
130
+ const transform = new c.TransformProcessor({
131
+ error_mode: "ignore",
132
+ trace_statements: [{ context: "span", conditions: ["kind == SPAN_KIND_SERVER"], statements: ['set(attributes["tier"], "edge")'] }],
133
+ metric_statements: ['delete_key(datapoint.attributes, "pod_ip")'],
134
+ log_statements: [{ context: "log", statements: ['set(severity_text, "WARN") where severity_number == 13'] }],
135
+ });
136
+ const redaction = new c.RedactionProcessor({
137
+ allow_all_keys: true,
138
+ blocked_key_patterns: ["^gen_ai\\.(prompt|completion)"],
139
+ blocked_values: ["4[0-9]{12}(?:[0-9]{3})?"],
140
+ hash_function: "sha3",
141
+ summary: "silent",
142
+ });
143
+ const tailSampling = new c.TailSamplingProcessor({
144
+ decision_wait: "10s",
145
+ num_traces: 50000,
146
+ sample_on_first_match: true,
147
+ policies: [
148
+ { name: "errors", type: "status_code", status_code: { status_codes: ["ERROR"] } },
149
+ { name: "slow", type: "latency", latency: { threshold_ms: 1000, upper_threshold_ms: 60000 } },
150
+ { name: "vip", type: "boolean_attribute", boolean_attribute: { key: "vip", value: true } },
151
+ { name: "sized", type: "span_count", span_count: { min_spans: 2, max_spans: 500 } },
152
+ { name: "both", type: "and", and: { and_sub_policy: [{ name: "a", type: "rate_limiting", rate_limiting: { spans_per_second: 100 } }, { name: "b", type: "always_sample" }] } },
153
+ { name: "rest", type: "probabilistic", probabilistic: { sampling_percentage: 5, hash_salt: "s" } },
154
+ ],
155
+ });
156
+ const probabilistic = new c.ProbabilisticSamplerProcessor({ sampling_percentage: 12.5, mode: "proportional", sampling_precision: 4 });
157
+
158
+ const otlpOut = new c.OtlpExporter({
159
+ name: "backend",
160
+ endpoint: "backend:4317",
161
+ compression: "zstd",
162
+ headers: { "x-api-key": "${env:BACKEND_KEY}" },
163
+ tls: { insecure: false, ca_file: "/etc/ca.pem", min_version: "1.3" },
164
+ balancer_name: "round_robin",
165
+ timeout: "10s",
166
+ retry_on_failure: { enabled: true, max_elapsed_time: "2m" },
167
+ sending_queue: { enabled: true, num_consumers: 4, queue_size: 2000, sizer: "requests" },
168
+ });
169
+ const otlphttp = new c.OtlpHttpExporter({ endpoint: "https://otlp.example.com", encoding: "json", logs_endpoint: "https://logs.example.com/v1/logs" });
170
+ const debug = new c.DebugExporter({ verbosity: "detailed", sampling_initial: 5, sampling_thereafter: 200 });
171
+ const prometheusOut = new c.PrometheusExporter({
172
+ endpoint: "0.0.0.0:8889",
173
+ namespace: "otel",
174
+ const_labels: { cluster: "prod" },
175
+ metric_expiration: "5m",
176
+ resource_to_telemetry_conversion: { enabled: true },
177
+ });
178
+ const googlecloud = new c.GoogleCloudExporter({
179
+ project: "my-project",
180
+ metric: { prefix: "custom.googleapis.com", resource_filters: [{ prefix: "k8s." }] },
181
+ trace: { attribute_mappings: [{ key: "http.route", replacement: "/http/route" }] },
182
+ log: { default_log_name: "otel" },
183
+ });
184
+ const loadbalancing = new c.LoadBalancingExporter({
185
+ routing_key: "service",
186
+ protocol: { otlp: { timeout: "1s", tls: { insecure: true } } },
187
+ resolver: { k8s: { service: "sampling.observability", ports: [4317], return_hostnames: true } },
188
+ });
189
+
190
+ const spanmetrics = new c.SpanMetricsConnector({
191
+ namespace: "span.metrics",
192
+ dimensions: [{ name: "http.route" }, { name: "env", default: "dev" }],
193
+ histogram: { unit: "s", exponential: { max_size: 160 } },
194
+ exemplars: { enabled: true, max_per_data_point: 5 },
195
+ metrics_flush_interval: "15s",
196
+ aggregation_temporality: "AGGREGATION_TEMPORALITY_DELTA",
197
+ });
198
+ const servicegraph = new c.ServiceGraphConnector({
199
+ latency_histogram_buckets: ["10ms", "100ms", "1s"],
200
+ dimensions: ["k8s.cluster.name"],
201
+ store: { ttl: "2s", max_items: 1000 },
202
+ virtual_node_peer_attributes: ["db.name"],
203
+ });
204
+ const routing = new c.RoutingConnector({
205
+ table: [{ context: "resource", condition: 'attributes["tenant"] == "acme"', pipelines: ["traces/acme"] }],
206
+ default_pipelines: ["traces/rest"],
207
+ error_mode: "ignore",
208
+ });
209
+ const forward = new c.ForwardConnector({});
210
+ const count = new c.CountConnector({
211
+ spans: { "span.count": { description: "Spans by service", attributes: [{ key: "service.name", default_value: "unknown" }] } },
212
+ });
213
+ const sum = new c.SumConnector({
214
+ spans: { "span.bytes": { source_attribute: "bytes", description: "Bytes by route", conditions: ['attributes["bytes"] != nil'] } },
215
+ });
216
+
217
+ const health = new c.HealthCheckExtension({ endpoint: "0.0.0.0:13133", path: "/health", response_body: { healthy: "ok" } });
218
+ const pprof = new c.PprofExtension({ endpoint: "localhost:1777", block_profile_fraction: 3 });
219
+ const zpages = new c.ZPagesExtension({ endpoint: "localhost:55679" });
220
+
221
+ return [
222
+ otlp,
223
+ prometheusIn,
224
+ hostmetrics,
225
+ filelog,
226
+ cluster,
227
+ kubelet,
228
+ batch,
229
+ memoryLimiter,
230
+ resource,
231
+ attributes,
232
+ k8sattributes,
233
+ resourcedetection,
234
+ filter,
235
+ transform,
236
+ redaction,
237
+ tailSampling,
238
+ probabilistic,
239
+ otlpOut,
240
+ otlphttp,
241
+ debug,
242
+ prometheusOut,
243
+ googlecloud,
244
+ loadbalancing,
245
+ spanmetrics,
246
+ servicegraph,
247
+ routing,
248
+ forward,
249
+ count,
250
+ sum,
251
+ health,
252
+ pprof,
253
+ zpages,
254
+ new Pipeline({
255
+ signal: "traces",
256
+ receivers: [otlp],
257
+ processors: [memoryLimiter, k8sattributes, resourcedetection, resource, attributes, filter, transform, redaction, probabilistic],
258
+ exporters: [spanmetrics, servicegraph, count, sum, forward, routing, loadbalancing],
259
+ }),
260
+ new Pipeline({ signal: "traces", name: "acme", receivers: [routing], processors: [tailSampling, batch], exporters: [otlpOut] }),
261
+ new Pipeline({ signal: "traces", name: "rest", receivers: [routing, forward], processors: [batch], exporters: [googlecloud, debug] }),
262
+ new Pipeline({
263
+ signal: "metrics",
264
+ receivers: [otlp, prometheusIn, hostmetrics, cluster, kubelet, spanmetrics, servicegraph, count, sum],
265
+ processors: [memoryLimiter, filter, batch],
266
+ exporters: [prometheusOut, otlphttp],
267
+ }),
268
+ new Pipeline({ signal: "logs", receivers: [otlp, filelog], processors: [memoryLimiter, redaction, batch], exporters: [otlphttp, debug] }),
269
+ new Service({
270
+ extensions: [health, zpages, pprof],
271
+ telemetry: { logs: { level: "warn", encoding: "json" }, metrics: { level: "normal" }, resource: { "service.name": "gw" } },
272
+ }),
273
+ ];
274
+ }
@@ -0,0 +1,153 @@
1
+ # A two-tier trace gateway in one file. The front tier spreads spans across
2
+ # the sampling tier by trace id with the loadbalancing exporter; the sampling
3
+ # tier keeps whole traces with tail_sampling and derives RED metrics from
4
+ # every span with spanmetrics before sampling drops any.
5
+
6
+ receivers:
7
+ otlp:
8
+ protocols:
9
+ grpc:
10
+ endpoint: 0.0.0.0:4317
11
+ http:
12
+ endpoint: 0.0.0.0:4318
13
+ otlp/sampling:
14
+ protocols:
15
+ grpc:
16
+ endpoint: 0.0.0.0:14317
17
+
18
+ processors:
19
+ memory_limiter:
20
+ check_interval: 1s
21
+ limit_percentage: 75
22
+ spike_limit_percentage: 15
23
+ batch:
24
+ timeout: 5s
25
+ send_batch_size: 8192
26
+ tail_sampling:
27
+ decision_wait: 10s
28
+ num_traces: 100000
29
+ expected_new_traces_per_sec: 2000
30
+ decision_cache:
31
+ sampled_cache_size: 100000
32
+ policies:
33
+ - name: errors
34
+ type: status_code
35
+ status_code:
36
+ status_codes: [ERROR]
37
+ - name: slow
38
+ type: latency
39
+ latency:
40
+ threshold_ms: 1500
41
+ - name: checkout
42
+ type: string_attribute
43
+ string_attribute:
44
+ key: service.name
45
+ values: [checkout, payments]
46
+ - name: noisy-health
47
+ type: drop
48
+ drop:
49
+ drop_sub_policy:
50
+ - name: health-route
51
+ type: string_attribute
52
+ string_attribute:
53
+ key: http.route
54
+ values: [/healthz, /readyz]
55
+ - name: budget
56
+ type: composite
57
+ composite:
58
+ max_total_spans_per_second: 1000
59
+ policy_order: [errors-first, rest]
60
+ composite_sub_policy:
61
+ - name: errors-first
62
+ type: status_code
63
+ status_code:
64
+ status_codes: [ERROR]
65
+ - name: rest
66
+ type: always_sample
67
+ rate_allocation:
68
+ - policy: errors-first
69
+ percent: 60
70
+ - policy: rest
71
+ percent: 40
72
+
73
+ exporters:
74
+ loadbalancing:
75
+ routing_key: traceID
76
+ protocol:
77
+ otlp:
78
+ timeout: 2s
79
+ tls:
80
+ insecure: true
81
+ resolver:
82
+ dns:
83
+ hostname: otel-sampling-headless.observability.svc.cluster.local
84
+ port: "14317"
85
+ otlp/tempo:
86
+ endpoint: tempo.observability:4317
87
+ headers:
88
+ authorization: "Bearer ${env:TEMPO_TOKEN}"
89
+ tls:
90
+ insecure: false
91
+ ca_file: /etc/tls/ca.pem
92
+ sending_queue:
93
+ enabled: true
94
+ queue_size: 10000
95
+ retry_on_failure:
96
+ enabled: true
97
+ max_elapsed_time: 5m
98
+ prometheus:
99
+ endpoint: "0.0.0.0:8889"
100
+ namespace: gateway
101
+ resource_to_telemetry_conversion:
102
+ enabled: true
103
+
104
+ connectors:
105
+ spanmetrics:
106
+ namespace: traces.span.metrics
107
+ dimensions:
108
+ - name: http.route
109
+ - name: deployment.environment
110
+ default: "${env:DEPLOY_ENV}"
111
+ histogram:
112
+ explicit:
113
+ buckets: [10ms, 50ms, 100ms, 250ms, 1s, 5s]
114
+ exemplars:
115
+ enabled: true
116
+ metrics_flush_interval: 15s
117
+
118
+ extensions:
119
+ health_check:
120
+ endpoint: 0.0.0.0:13133
121
+ pprof:
122
+ endpoint: localhost:1777
123
+ zpages: {}
124
+
125
+ service:
126
+ extensions: [zpages, health_check]
127
+ telemetry:
128
+ logs:
129
+ level: info
130
+ encoding: json
131
+ metrics:
132
+ level: detailed
133
+ readers:
134
+ - pull:
135
+ exporter:
136
+ prometheus:
137
+ host: 0.0.0.0
138
+ port: 8888
139
+ resource:
140
+ service.name: otel-gateway
141
+ pipelines:
142
+ traces:
143
+ receivers: [otlp]
144
+ processors: [memory_limiter]
145
+ exporters: [loadbalancing]
146
+ traces/sampling:
147
+ receivers: [otlp/sampling]
148
+ processors: [memory_limiter, tail_sampling, batch]
149
+ exporters: [otlp/tempo, spanmetrics]
150
+ metrics/red:
151
+ receivers: [spanmetrics]
152
+ processors: [batch]
153
+ exporters: [prometheus]
@@ -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]