@primafuture/telemetry-stack 0.1.0 → 0.2.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
CHANGED
|
@@ -195,10 +195,24 @@ curl -sS -X POST http://localhost:4318/v1/logs \
|
|
|
195
195
|
\"timeUnixNano\": \"${TS}\",
|
|
196
196
|
\"severityText\": \"INFO\",
|
|
197
197
|
\"body\": {\"stringValue\": \"hello from telemetry-stack smoke test\"},
|
|
198
|
-
\"attributes\": [
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
198
|
+
\"attributes\": [
|
|
199
|
+
{
|
|
200
|
+
\"key\": \"log_type\",
|
|
201
|
+
\"value\": {\"stringValue\": \"smoke_test\"}
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
\"key\": \"route\",
|
|
205
|
+
\"value\": {\"stringValue\": \"/smoke\"}
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
\"key\": \"count\",
|
|
209
|
+
\"value\": {\"intValue\": \"3\"}
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
\"key\": \"parallel\",
|
|
213
|
+
\"value\": {\"boolValue\": true}
|
|
214
|
+
}
|
|
215
|
+
]
|
|
202
216
|
}]
|
|
203
217
|
}]
|
|
204
218
|
}]
|
|
@@ -208,8 +222,75 @@ curl -sS -X POST http://localhost:4318/v1/logs \
|
|
|
208
222
|
Query it from Loki:
|
|
209
223
|
|
|
210
224
|
```bash
|
|
211
|
-
curl -G 'http://localhost:3100/loki/api/v1/
|
|
212
|
-
--data-urlencode 'query={
|
|
225
|
+
curl -G 'http://localhost:3100/loki/api/v1/query_range' \
|
|
226
|
+
--data-urlencode 'query={loki_service_name="telemetry-smoke-test"}' \
|
|
227
|
+
--data-urlencode 'limit=5'
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
For Grafana trace-to-logs compatibility, the same log is also indexed by the
|
|
231
|
+
legacy `service_name` label:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
curl -G 'http://localhost:3100/loki/api/v1/query_range' \
|
|
235
|
+
--data-urlencode 'query={service_name="telemetry-smoke-test"}' \
|
|
236
|
+
--data-urlencode 'limit=5'
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The returned log should expose application metadata under `app_*`, for example
|
|
240
|
+
`app_log_type`, `app_route`, `app_count`, and `app_parallel`. OpenTelemetry
|
|
241
|
+
metadata should be under `otel_*`, for example `otel_resource_service_name` and
|
|
242
|
+
`otel_scope_name`.
|
|
243
|
+
|
|
244
|
+
## Log Metadata in Loki
|
|
245
|
+
|
|
246
|
+
Applications can log plain metadata such as `count`, `parallel`, or `route`.
|
|
247
|
+
Alloy normalizes those fields before Loki receives them, so application code does
|
|
248
|
+
not need to add prefixes itself.
|
|
249
|
+
|
|
250
|
+
The stack uses these names:
|
|
251
|
+
|
|
252
|
+
```text
|
|
253
|
+
app_* application log attributes
|
|
254
|
+
otel_resource_* OpenTelemetry resource attributes
|
|
255
|
+
otel_scope_* OpenTelemetry instrumentation scope attributes
|
|
256
|
+
otel_log_* OpenTelemetry log record fields
|
|
257
|
+
loki_* explicit Loki index labels
|
|
258
|
+
service_name legacy compatibility label for Grafana trace-to-logs
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Examples:
|
|
262
|
+
|
|
263
|
+
```text
|
|
264
|
+
count -> app_count
|
|
265
|
+
route -> app_route
|
|
266
|
+
service.name -> otel_resource_service_name
|
|
267
|
+
instrumentation scope -> otel_scope_name
|
|
268
|
+
trace id -> otel_log_trace_id
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Loki indexes only the low-cardinality resource labels configured in
|
|
272
|
+
`loki.yaml`, such as `loki_service_name` and the compatibility `service_name`.
|
|
273
|
+
Application and OpenTelemetry detail fields are stored as structured metadata,
|
|
274
|
+
not as index labels. Query them after selecting a stream:
|
|
275
|
+
|
|
276
|
+
```logql
|
|
277
|
+
{loki_service_name="telemetry-dice-roller-example"}
|
|
278
|
+
| trace_id="0242ac120002"
|
|
279
|
+
| app_route="/roll"
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Current Loki versions return structured metadata merged into the `stream` labels
|
|
283
|
+
map in `query_range` responses. This is a Loki API behavior: the fields are still
|
|
284
|
+
not index labels. Use `/loki/api/v1/labels` or `/loki/api/v1/series` to see the
|
|
285
|
+
real indexed labels.
|
|
286
|
+
|
|
287
|
+
If a query response is too noisy, reduce returned fields at query time without
|
|
288
|
+
changing stored data:
|
|
289
|
+
|
|
290
|
+
```logql
|
|
291
|
+
{service_name="telemetry-dice-roller-example"}
|
|
292
|
+
| trace_id="0242ac120002"
|
|
293
|
+
| keep service_name, loki_service_name, trace_id, span_id
|
|
213
294
|
```
|
|
214
295
|
|
|
215
296
|
## Useful URLs
|
package/package.json
CHANGED
|
@@ -1,13 +1,49 @@
|
|
|
1
1
|
// Main Alloy pipeline for application telemetry.
|
|
2
2
|
// It receives OTLP traces, metrics, and logs from apps and routes them to the stack.
|
|
3
3
|
|
|
4
|
-
//
|
|
4
|
+
// Normalize log metadata before Loki stores it as labels/structured metadata.
|
|
5
|
+
// App-provided log attributes stay queryable under app.* and OTel/system data under otel.*.
|
|
5
6
|
otelcol.processor.transform "loki_labels" {
|
|
7
|
+
error_mode = "ignore"
|
|
8
|
+
|
|
6
9
|
log_statements {
|
|
7
10
|
context = "log"
|
|
8
11
|
statements = [
|
|
9
|
-
|
|
10
|
-
`
|
|
12
|
+
// Copy application log attributes into app.* without requiring apps to prefix anything themselves.
|
|
13
|
+
`merge_maps(log.cache, log.attributes, "upsert")`,
|
|
14
|
+
`flatten(log.cache, "app", resolveConflicts=true)`,
|
|
15
|
+
`merge_maps(log.attributes, log.cache, "upsert")`,
|
|
16
|
+
`delete_matching_keys(log.cache, ".*")`,
|
|
17
|
+
|
|
18
|
+
// Copy original resource attributes into otel.resource.* before resource labels are rewritten for Loki.
|
|
19
|
+
`merge_maps(log.cache, resource.attributes, "upsert")`,
|
|
20
|
+
`flatten(log.cache, "otel.resource", resolveConflicts=true)`,
|
|
21
|
+
`merge_maps(log.attributes, log.cache, "upsert")`,
|
|
22
|
+
`delete_matching_keys(log.cache, ".*")`,
|
|
23
|
+
|
|
24
|
+
// Copy instrumentation scope data into otel.scope.*.
|
|
25
|
+
`merge_maps(log.cache, instrumentation_scope.attributes, "upsert")`,
|
|
26
|
+
`flatten(log.cache, "otel.scope.attributes", resolveConflicts=true)`,
|
|
27
|
+
`merge_maps(log.attributes, log.cache, "upsert")`,
|
|
28
|
+
`delete_matching_keys(log.cache, ".*")`,
|
|
29
|
+
`set(log.attributes["otel.scope.name"], instrumentation_scope.name) where instrumentation_scope.name != ""`,
|
|
30
|
+
`set(log.attributes["otel.scope.version"], instrumentation_scope.version) where instrumentation_scope.version != ""`,
|
|
31
|
+
|
|
32
|
+
// Duplicate intrinsic log fields into otel.log.* while leaving native trace/span fields intact for Grafana links.
|
|
33
|
+
`set(log.attributes["otel.log.severity_text"], log.severity_text) where log.severity_text != ""`,
|
|
34
|
+
`set(log.attributes["otel.log.severity_number"], log.severity_number)`,
|
|
35
|
+
`set(log.attributes["otel.log.trace_id"], log.trace_id.string) where log.trace_id.string != ""`,
|
|
36
|
+
`set(log.attributes["otel.log.span_id"], log.span_id.string) where log.span_id.string != ""`,
|
|
37
|
+
`set(log.attributes["otel.log.flags"], log.flags)`,
|
|
38
|
+
|
|
39
|
+
// Build explicit Loki labels from original values. Loki will normalize dots to underscores.
|
|
40
|
+
`set(resource.attributes["loki.service.name"], resource.attributes["service.name"]) where resource.attributes["service.name"] != nil`,
|
|
41
|
+
`set(resource.attributes["loki.log.type"], log.attributes["log_type"]) where log.attributes["log_type"] != nil`,
|
|
42
|
+
`set(resource.attributes["loki.log.file.path"], log.attributes["log.file.path"]) where log.attributes["log.file.path"] != nil`,
|
|
43
|
+
|
|
44
|
+
// Keep only namespaced structured metadata, explicit Loki label resource attributes, and the legacy service.name label.
|
|
45
|
+
`keep_matching_keys(log.attributes, "^(app|otel)[.]")`,
|
|
46
|
+
`keep_matching_keys(resource.attributes, "^(loki[.].*|service[.]name)$")`,
|
|
11
47
|
]
|
|
12
48
|
}
|
|
13
49
|
output {
|
|
@@ -12,7 +12,7 @@ datasources:
|
|
|
12
12
|
url: http://prometheus:9090
|
|
13
13
|
basicAuth: false
|
|
14
14
|
isDefault: false
|
|
15
|
-
version:
|
|
15
|
+
version: 2
|
|
16
16
|
editable: true
|
|
17
17
|
jsonData:
|
|
18
18
|
httpMethod: GET
|
|
@@ -28,7 +28,7 @@ datasources:
|
|
|
28
28
|
url: http://mimir:9009/prometheus
|
|
29
29
|
basicAuth: false
|
|
30
30
|
isDefault: false
|
|
31
|
-
version:
|
|
31
|
+
version: 2
|
|
32
32
|
editable: true
|
|
33
33
|
jsonData:
|
|
34
34
|
httpMethod: GET
|
|
@@ -41,7 +41,7 @@ datasources:
|
|
|
41
41
|
url: http://loki:3100
|
|
42
42
|
basicAuth: false
|
|
43
43
|
isDefault: false
|
|
44
|
-
version:
|
|
44
|
+
version: 2
|
|
45
45
|
editable: true
|
|
46
46
|
jsonData:
|
|
47
47
|
httpMethod: GET
|
|
@@ -66,7 +66,7 @@ datasources:
|
|
|
66
66
|
url: http://tempo:3200
|
|
67
67
|
basicAuth: false
|
|
68
68
|
isDefault: true
|
|
69
|
-
version:
|
|
69
|
+
version: 2
|
|
70
70
|
editable: true
|
|
71
71
|
apiVersion: 1
|
|
72
72
|
uid: tempo-streaming-enabled
|
|
@@ -77,6 +77,16 @@ datasources:
|
|
|
77
77
|
streamingEnabled:
|
|
78
78
|
search: true
|
|
79
79
|
metrics: true
|
|
80
|
+
tracesToLogsV2:
|
|
81
|
+
customQuery: false
|
|
82
|
+
datasourceUid: loki
|
|
83
|
+
filterBySpanID: true
|
|
84
|
+
filterByTraceID: true
|
|
85
|
+
spanEndTimeShift: 10s
|
|
86
|
+
spanStartTimeShift: "-10s"
|
|
87
|
+
tags:
|
|
88
|
+
- key: service.name
|
|
89
|
+
value: loki_service_name
|
|
80
90
|
# This Tempo datasource keeps streaming disabled for links that need stable TraceQL behavior.
|
|
81
91
|
- name: Tempo (no streaming)
|
|
82
92
|
type: tempo
|
|
@@ -85,7 +95,7 @@ datasources:
|
|
|
85
95
|
url: http://tempo:3200
|
|
86
96
|
basicAuth: false
|
|
87
97
|
isDefault: false
|
|
88
|
-
version:
|
|
98
|
+
version: 2
|
|
89
99
|
editable: true
|
|
90
100
|
apiVersion: 1
|
|
91
101
|
uid: tempo-streaming-disabled
|
|
@@ -102,4 +112,4 @@ datasources:
|
|
|
102
112
|
spanStartTimeShift: "-10s"
|
|
103
113
|
tags:
|
|
104
114
|
- key: service.name
|
|
105
|
-
value:
|
|
115
|
+
value: loki_service_name
|
|
@@ -52,12 +52,16 @@ compactor:
|
|
|
52
52
|
# Keep demo logs for 7 days.
|
|
53
53
|
limits_config:
|
|
54
54
|
retention_period: 168h
|
|
55
|
+
# Keep synthetic Loki metadata out of the way; Alloy already namespaces these values.
|
|
56
|
+
discover_service_name: []
|
|
57
|
+
discover_log_levels: false
|
|
55
58
|
|
|
56
59
|
# OTLP logs arrive with resource attributes. This list chooses which attributes
|
|
57
60
|
# Loki indexes as labels; dots are converted to underscores in Loki/Grafana.
|
|
58
61
|
distributor:
|
|
59
62
|
otlp_config:
|
|
60
63
|
default_resource_attributes_as_index_labels:
|
|
64
|
+
- loki.service.name
|
|
61
65
|
- service.name
|
|
62
|
-
-
|
|
63
|
-
- log.file.path
|
|
66
|
+
- loki.log.type
|
|
67
|
+
- loki.log.file.path
|