@superblocksteam/telemetry 2.0.93 → 2.0.94-next.1
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 +59 -44
- package/dist/browser/index.d.ts +2 -2
- package/dist/browser/resilient-exporter.d.ts.map +1 -1
- package/dist/browser/resilient-exporter.js.map +1 -1
- package/dist/common/contracts/tier2-traces.d.ts +62 -50
- package/dist/common/contracts/tier2-traces.d.ts.map +1 -1
- package/dist/common/contracts/tier2-traces.js +484 -138
- package/dist/common/contracts/tier2-traces.js.map +1 -1
- package/dist/common/guardrails.d.ts +2 -2
- package/dist/common/guardrails.d.ts.map +1 -1
- package/dist/common/guardrails.js +7 -7
- package/dist/common/guardrails.js.map +1 -1
- package/dist/common/log-sanitizer.d.ts +88 -0
- package/dist/common/log-sanitizer.d.ts.map +1 -1
- package/dist/common/log-sanitizer.js +304 -6
- package/dist/common/log-sanitizer.js.map +1 -1
- package/dist/common/resource.d.ts +4 -1
- package/dist/common/resource.d.ts.map +1 -1
- package/dist/common/resource.js +4 -2
- package/dist/common/resource.js.map +1 -1
- package/dist/common/trace-sanitizer.d.ts +82 -0
- package/dist/common/trace-sanitizer.d.ts.map +1 -0
- package/dist/common/trace-sanitizer.js +230 -0
- package/dist/common/trace-sanitizer.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -8
- package/dist/index.js.map +1 -1
- package/dist/lint/forbidden-attributes.d.ts +2 -2
- package/dist/lint/forbidden-attributes.d.ts.map +1 -1
- package/dist/lint/forbidden-attributes.js +41 -40
- package/dist/lint/forbidden-attributes.js.map +1 -1
- package/dist/lint/index.d.ts +1 -1
- package/dist/llmobs/index.d.ts +2 -2
- package/dist/llmobs/tier1-exporter.d.ts +2 -2
- package/dist/llmobs/tier1-exporter.d.ts.map +1 -1
- package/dist/llmobs/tier1-exporter.js +17 -14
- package/dist/llmobs/tier1-exporter.js.map +1 -1
- package/dist/llmobs/tier2-summarizer.d.ts.map +1 -1
- package/dist/llmobs/tier2-summarizer.js +10 -4
- package/dist/llmobs/tier2-summarizer.js.map +1 -1
- package/dist/node/exporters/resilient-exporter.d.ts +14 -0
- package/dist/node/exporters/resilient-exporter.d.ts.map +1 -1
- package/dist/node/exporters/resilient-exporter.js +8 -1
- package/dist/node/exporters/resilient-exporter.js.map +1 -1
- package/dist/node/index.d.ts +2 -1
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +7 -2
- package/dist/node/index.js.map +1 -1
- package/dist/node/init.d.ts.map +1 -1
- package/dist/node/init.js +61 -12
- package/dist/node/init.js.map +1 -1
- package/dist/node/log-processor.d.ts +41 -6
- package/dist/node/log-processor.d.ts.map +1 -1
- package/dist/node/log-processor.js +152 -61
- package/dist/node/log-processor.js.map +1 -1
- package/dist/node/metrics-client.d.ts.map +1 -1
- package/dist/node/metrics-client.js.map +1 -1
- package/dist/node/safe-logger.d.ts +55 -0
- package/dist/node/safe-logger.d.ts.map +1 -0
- package/dist/node/safe-logger.js +158 -0
- package/dist/node/safe-logger.js.map +1 -0
- package/dist/node/sanitizing-processor.d.ts +56 -0
- package/dist/node/sanitizing-processor.d.ts.map +1 -0
- package/dist/node/sanitizing-processor.js +124 -0
- package/dist/node/sanitizing-processor.js.map +1 -0
- package/dist/node/traced-socket.d.ts +47 -3
- package/dist/node/traced-socket.d.ts.map +1 -1
- package/dist/node/traced-socket.js +96 -19
- package/dist/node/traced-socket.js.map +1 -1
- package/dist/testing/in-memory-exporter.d.ts +3 -3
- package/dist/testing/in-memory-exporter.d.ts.map +1 -1
- package/dist/testing/in-memory-exporter.js +3 -1
- package/dist/testing/in-memory-exporter.js.map +1 -1
- package/dist/testing/index.d.ts +2 -2
- package/dist/types/index.d.ts +28 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist-esm/browser/index.d.ts +2 -2
- package/dist-esm/browser/index.js +2 -2
- package/dist-esm/browser/resilient-exporter.d.ts.map +1 -1
- package/dist-esm/browser/resilient-exporter.js.map +1 -1
- package/dist-esm/common/contracts/tier2-traces.d.ts +62 -50
- package/dist-esm/common/contracts/tier2-traces.d.ts.map +1 -1
- package/dist-esm/common/contracts/tier2-traces.js +480 -137
- package/dist-esm/common/contracts/tier2-traces.js.map +1 -1
- package/dist-esm/common/guardrails.d.ts +2 -2
- package/dist-esm/common/guardrails.d.ts.map +1 -1
- package/dist-esm/common/guardrails.js +9 -9
- package/dist-esm/common/guardrails.js.map +1 -1
- package/dist-esm/common/log-sanitizer.d.ts +88 -0
- package/dist-esm/common/log-sanitizer.d.ts.map +1 -1
- package/dist-esm/common/log-sanitizer.js +294 -5
- package/dist-esm/common/log-sanitizer.js.map +1 -1
- package/dist-esm/common/resource.d.ts +4 -1
- package/dist-esm/common/resource.d.ts.map +1 -1
- package/dist-esm/common/resource.js +3 -1
- package/dist-esm/common/resource.js.map +1 -1
- package/dist-esm/common/trace-sanitizer.d.ts +82 -0
- package/dist-esm/common/trace-sanitizer.d.ts.map +1 -0
- package/dist-esm/common/trace-sanitizer.js +226 -0
- package/dist-esm/common/trace-sanitizer.js.map +1 -0
- package/dist-esm/index.d.ts +2 -1
- package/dist-esm/index.d.ts.map +1 -1
- package/dist-esm/index.js +2 -1
- package/dist-esm/index.js.map +1 -1
- package/dist-esm/lint/forbidden-attributes.d.ts +2 -2
- package/dist-esm/lint/forbidden-attributes.d.ts.map +1 -1
- package/dist-esm/lint/forbidden-attributes.js +43 -42
- package/dist-esm/lint/forbidden-attributes.js.map +1 -1
- package/dist-esm/lint/index.d.ts +1 -1
- package/dist-esm/lint/index.js +1 -1
- package/dist-esm/llmobs/index.d.ts +2 -2
- package/dist-esm/llmobs/index.js +2 -2
- package/dist-esm/llmobs/tier1-exporter.d.ts +2 -2
- package/dist-esm/llmobs/tier1-exporter.d.ts.map +1 -1
- package/dist-esm/llmobs/tier1-exporter.js +18 -15
- package/dist-esm/llmobs/tier1-exporter.js.map +1 -1
- package/dist-esm/llmobs/tier2-summarizer.d.ts.map +1 -1
- package/dist-esm/llmobs/tier2-summarizer.js +10 -4
- package/dist-esm/llmobs/tier2-summarizer.js.map +1 -1
- package/dist-esm/node/exporters/resilient-exporter.d.ts +14 -0
- package/dist-esm/node/exporters/resilient-exporter.d.ts.map +1 -1
- package/dist-esm/node/exporters/resilient-exporter.js +8 -1
- package/dist-esm/node/exporters/resilient-exporter.js.map +1 -1
- package/dist-esm/node/index.d.ts +2 -1
- package/dist-esm/node/index.d.ts.map +1 -1
- package/dist-esm/node/index.js +2 -1
- package/dist-esm/node/index.js.map +1 -1
- package/dist-esm/node/init.d.ts.map +1 -1
- package/dist-esm/node/init.js +61 -12
- package/dist-esm/node/init.js.map +1 -1
- package/dist-esm/node/log-processor.d.ts +41 -6
- package/dist-esm/node/log-processor.d.ts.map +1 -1
- package/dist-esm/node/log-processor.js +151 -62
- package/dist-esm/node/log-processor.js.map +1 -1
- package/dist-esm/node/metrics-client.d.ts.map +1 -1
- package/dist-esm/node/metrics-client.js.map +1 -1
- package/dist-esm/node/safe-logger.d.ts +55 -0
- package/dist-esm/node/safe-logger.d.ts.map +1 -0
- package/dist-esm/node/safe-logger.js +154 -0
- package/dist-esm/node/safe-logger.js.map +1 -0
- package/dist-esm/node/sanitizing-processor.d.ts +56 -0
- package/dist-esm/node/sanitizing-processor.d.ts.map +1 -0
- package/dist-esm/node/sanitizing-processor.js +120 -0
- package/dist-esm/node/sanitizing-processor.js.map +1 -0
- package/dist-esm/node/traced-socket.d.ts +47 -3
- package/dist-esm/node/traced-socket.d.ts.map +1 -1
- package/dist-esm/node/traced-socket.js +96 -19
- package/dist-esm/node/traced-socket.js.map +1 -1
- package/dist-esm/testing/in-memory-exporter.d.ts +3 -3
- package/dist-esm/testing/in-memory-exporter.d.ts.map +1 -1
- package/dist-esm/testing/in-memory-exporter.js +4 -2
- package/dist-esm/testing/in-memory-exporter.js.map +1 -1
- package/dist-esm/testing/index.d.ts +2 -2
- package/dist-esm/testing/index.js +2 -2
- package/dist-esm/types/index.d.ts +28 -1
- package/dist-esm/types/index.d.ts.map +1 -1
- package/dist-esm/types/index.js +1 -1
- package/package.json +17 -18
|
@@ -1,177 +1,520 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Tier 2 Traces Contract
|
|
2
|
+
* Tier 2 Traces Contract (v0.2.0)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* -
|
|
6
|
-
* - Hashed attributes (pseudonymized by Collector)
|
|
7
|
-
* - Dropped attributes (removed by Collector)
|
|
8
|
-
* - Forbidden value patterns (for lint-time detection)
|
|
4
|
+
* Single source of truth for Tier 2 sanitized trace telemetry.
|
|
5
|
+
* Mirrors: engineering/projects/o11y-refactor/contracts/tier2-traces.v0.2.0.json
|
|
9
6
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* -
|
|
13
|
-
* -
|
|
7
|
+
* Used by:
|
|
8
|
+
* - trace-sanitizer (SDK: which spans/attributes to export)
|
|
9
|
+
* - lint/forbidden-attributes (ESLint)
|
|
10
|
+
* - guardrails (dev-time warnings)
|
|
14
11
|
* - Collector config generation
|
|
15
12
|
*
|
|
16
|
-
*
|
|
17
|
-
* Source of truth: engineering/projects/o11y-refactor/contracts/tier2-traces.v0.3.0.json
|
|
13
|
+
* "request handler *" is a local extension for Express instrumentation (not in JSON).
|
|
18
14
|
*/
|
|
15
|
+
import { DeploymentTypeEnum } from "@superblocksteam/shared";
|
|
16
|
+
export function getAttributeName(attr) {
|
|
17
|
+
return typeof attr === "string" ? attr : attr.name;
|
|
18
|
+
}
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* The Collector strips these entirely (not hashed, not present in Tier 2).
|
|
20
|
+
* Span patterns from tier2-traces.v0.2.0.json.
|
|
21
|
+
* Suffix wildcard only: "HTTP POST *" matches "HTTP POST /api/..." or "POST /api/...".
|
|
23
22
|
*/
|
|
24
|
-
export const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
23
|
+
export const TIER_2_TRACE_CONTRACT = [
|
|
24
|
+
{
|
|
25
|
+
name: "HTTP GET *",
|
|
26
|
+
allowedAttributes: [
|
|
27
|
+
"http.method",
|
|
28
|
+
{ name: "http.route", maxCardinality: 150 },
|
|
29
|
+
"http.status_code",
|
|
30
|
+
"http.response_content_length",
|
|
31
|
+
{ name: "http.flavor", allowedValues: ["1.0", "1.1", "2.0", "3.0"] },
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: "HTTP POST *",
|
|
36
|
+
allowedAttributes: [
|
|
37
|
+
"http.method",
|
|
38
|
+
{ name: "http.route", maxCardinality: 150 },
|
|
39
|
+
"http.status_code",
|
|
40
|
+
"http.response_content_length",
|
|
41
|
+
"http.request_content_length",
|
|
42
|
+
{ name: "http.flavor", allowedValues: ["1.0", "1.1", "2.0", "3.0"] },
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: "HTTP PUT *",
|
|
47
|
+
allowedAttributes: [
|
|
48
|
+
"http.method",
|
|
49
|
+
{ name: "http.route", maxCardinality: 150 },
|
|
50
|
+
"http.status_code",
|
|
51
|
+
"http.response_content_length",
|
|
52
|
+
"http.request_content_length",
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: "HTTP DELETE *",
|
|
57
|
+
allowedAttributes: [
|
|
58
|
+
"http.method",
|
|
59
|
+
{ name: "http.route", maxCardinality: 150 },
|
|
60
|
+
"http.status_code",
|
|
61
|
+
"http.response_content_length",
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: "HTTP PATCH *",
|
|
66
|
+
allowedAttributes: [
|
|
67
|
+
"http.method",
|
|
68
|
+
{ name: "http.route", maxCardinality: 150 },
|
|
69
|
+
"http.status_code",
|
|
70
|
+
"http.response_content_length",
|
|
71
|
+
"http.request_content_length",
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: "request handler *",
|
|
76
|
+
allowedAttributes: [
|
|
77
|
+
"http.method",
|
|
78
|
+
{ name: "http.route", maxCardinality: 150 },
|
|
79
|
+
"http.status_code",
|
|
80
|
+
"http.response_content_length",
|
|
81
|
+
"http.request_content_length",
|
|
82
|
+
{ name: "http.flavor", allowedValues: ["1.0", "1.1", "2.0", "3.0"] },
|
|
83
|
+
"express.route",
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: "WS SERVER *",
|
|
88
|
+
allowedAttributes: [
|
|
89
|
+
{ name: "messaging.system", allowedValues: ["ws", "websocket"] },
|
|
90
|
+
{ name: "messaging.destination_kind", allowedValues: ["websocket"] },
|
|
91
|
+
{ name: "ws.handler", maxCardinality: 80 },
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: "WS CLIENT *",
|
|
96
|
+
allowedAttributes: [
|
|
97
|
+
{ name: "messaging.system", allowedValues: ["ws", "websocket"] },
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: "WS HANDLER *",
|
|
102
|
+
allowedAttributes: [
|
|
103
|
+
{ name: "messaging.system", allowedValues: ["ws", "websocket"] },
|
|
104
|
+
{ name: "messaging.destination_kind", allowedValues: ["websocket"] },
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: "api.execute",
|
|
109
|
+
alwaysSample: true,
|
|
110
|
+
allowedAttributes: [
|
|
111
|
+
{ name: "view-mode", allowedValues: ["edit", "deployed", "preview"] },
|
|
112
|
+
{
|
|
113
|
+
name: "api.status",
|
|
114
|
+
allowedValues: ["success", "error", "timeout", "cancelled"],
|
|
115
|
+
},
|
|
116
|
+
{ name: "api.type", allowedValues: ["api", "workflow", "scheduled_job"] },
|
|
117
|
+
{ name: "api.step_count", type: "number" },
|
|
118
|
+
{ name: "api.duration_ms", type: "number" },
|
|
119
|
+
{ name: "remote", allowedValues: ["true", "false"] },
|
|
120
|
+
"otel.status_code",
|
|
121
|
+
"otel.status_description",
|
|
122
|
+
],
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
name: "api.step",
|
|
126
|
+
allowedAttributes: [
|
|
127
|
+
{ name: "step.type", maxCardinality: 50 },
|
|
128
|
+
{ name: "step.status", allowedValues: ["success", "error"] },
|
|
129
|
+
{ name: "step.duration_ms", type: "number" },
|
|
130
|
+
{ name: "step.retry_count", type: "number" },
|
|
131
|
+
"otel.status_code",
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: "api.block.*",
|
|
136
|
+
allowedAttributes: [
|
|
137
|
+
{ name: "block.type", maxCardinality: 30 },
|
|
138
|
+
{ name: "block.status", allowedValues: ["success", "error"] },
|
|
139
|
+
],
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: "plugin.*",
|
|
143
|
+
allowedAttributes: [
|
|
144
|
+
{ name: "plugin.name", maxCardinality: 80 },
|
|
145
|
+
{
|
|
146
|
+
name: "plugin.event",
|
|
147
|
+
allowedValues: ["execute", "test", "metadata", "pre_delete"],
|
|
148
|
+
},
|
|
149
|
+
{ name: "plugin.result", allowedValues: ["succeeded", "failed"] },
|
|
150
|
+
{ name: "plugin.duration_ms", type: "number" },
|
|
151
|
+
"otel.status_code",
|
|
152
|
+
],
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
name: "db.*",
|
|
156
|
+
allowedAttributes: [
|
|
157
|
+
{
|
|
158
|
+
name: "db.system",
|
|
159
|
+
allowedValues: [
|
|
160
|
+
"postgresql",
|
|
161
|
+
"mysql",
|
|
162
|
+
"mssql",
|
|
163
|
+
"mongodb",
|
|
164
|
+
"redis",
|
|
165
|
+
"snowflake",
|
|
166
|
+
"bigquery",
|
|
167
|
+
"databricks",
|
|
168
|
+
"dynamodb",
|
|
169
|
+
"sqlite",
|
|
170
|
+
],
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: "db.operation",
|
|
174
|
+
allowedValues: ["select", "insert", "update", "delete", "other"],
|
|
175
|
+
},
|
|
176
|
+
{ name: "db.name", maxCardinality: 50 },
|
|
177
|
+
"otel.status_code",
|
|
178
|
+
],
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
name: "llm.request",
|
|
182
|
+
allowedAttributes: [
|
|
183
|
+
{
|
|
184
|
+
name: "gen_ai.operation.name",
|
|
185
|
+
allowedValues: [
|
|
186
|
+
"chat",
|
|
187
|
+
"text_completion",
|
|
188
|
+
"embeddings",
|
|
189
|
+
"execute_tool",
|
|
190
|
+
"invoke_agent",
|
|
191
|
+
"generate_content",
|
|
192
|
+
],
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
name: "gen_ai.system",
|
|
196
|
+
allowedValues: [
|
|
197
|
+
"openai",
|
|
198
|
+
"anthropic",
|
|
199
|
+
"aws.bedrock",
|
|
200
|
+
"azure.ai.openai",
|
|
201
|
+
"azure.ai.inference",
|
|
202
|
+
"gcp.gemini",
|
|
203
|
+
"gcp.vertex_ai",
|
|
204
|
+
"cohere",
|
|
205
|
+
"mistral_ai",
|
|
206
|
+
"deepseek",
|
|
207
|
+
"groq",
|
|
208
|
+
],
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: "gen_ai.provider.name",
|
|
212
|
+
allowedValues: [
|
|
213
|
+
"openai",
|
|
214
|
+
"anthropic",
|
|
215
|
+
"aws.bedrock",
|
|
216
|
+
"azure.ai.openai",
|
|
217
|
+
"azure.ai.inference",
|
|
218
|
+
"gcp.gemini",
|
|
219
|
+
"gcp.vertex_ai",
|
|
220
|
+
"cohere",
|
|
221
|
+
"mistral_ai",
|
|
222
|
+
"deepseek",
|
|
223
|
+
"groq",
|
|
224
|
+
],
|
|
225
|
+
},
|
|
226
|
+
{ name: "gen_ai.request.model", maxCardinality: 50 },
|
|
227
|
+
{ name: "gen_ai.response.model", maxCardinality: 50 },
|
|
228
|
+
"llm.provider",
|
|
229
|
+
"llm.model",
|
|
230
|
+
"llm.status",
|
|
231
|
+
{
|
|
232
|
+
name: "llm.error_category",
|
|
233
|
+
allowedValues: [
|
|
234
|
+
"none",
|
|
235
|
+
"rate_limit",
|
|
236
|
+
"context_length",
|
|
237
|
+
"content_filter",
|
|
238
|
+
"quota",
|
|
239
|
+
"network",
|
|
240
|
+
"timeout",
|
|
241
|
+
"auth_error",
|
|
242
|
+
"api_error",
|
|
243
|
+
"validation_error",
|
|
244
|
+
"aborted",
|
|
245
|
+
"unknown",
|
|
246
|
+
],
|
|
247
|
+
},
|
|
248
|
+
"llm.duration_ms",
|
|
249
|
+
"gen_ai.usage.input_tokens",
|
|
250
|
+
"gen_ai.usage.output_tokens",
|
|
251
|
+
"llm.input_tokens",
|
|
252
|
+
"llm.output_tokens",
|
|
253
|
+
"llm.total_tokens",
|
|
254
|
+
"llm.reasoning_tokens",
|
|
255
|
+
"llm.cached_tokens",
|
|
256
|
+
"llm.cost_usd",
|
|
257
|
+
{ name: "gen_ai.client.time_to_first_token", type: "number" },
|
|
258
|
+
{ name: "llm.time_to_first_token_ms", type: "number" },
|
|
259
|
+
"gen_ai.response.finish_reasons",
|
|
260
|
+
"llm.finish_reason",
|
|
261
|
+
"otel.status_code",
|
|
262
|
+
],
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
name: "llm.tool_call",
|
|
266
|
+
allowedAttributes: [
|
|
267
|
+
{ name: "tool.name", maxCardinality: 50 },
|
|
268
|
+
{ name: "tool.status", allowedValues: ["success", "error"] },
|
|
269
|
+
{
|
|
270
|
+
name: "tool.error_category",
|
|
271
|
+
allowedValues: [
|
|
272
|
+
"none",
|
|
273
|
+
"timeout",
|
|
274
|
+
"execution_error",
|
|
275
|
+
"validation_error",
|
|
276
|
+
"permission_denied",
|
|
277
|
+
"not_found",
|
|
278
|
+
"unknown",
|
|
279
|
+
],
|
|
280
|
+
},
|
|
281
|
+
{ name: "tool.duration_ms", type: "number" },
|
|
282
|
+
"otel.status_code",
|
|
283
|
+
],
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
name: "ai.streamText",
|
|
287
|
+
allowedAttributes: [
|
|
288
|
+
"llm.provider",
|
|
289
|
+
"llm.model",
|
|
290
|
+
"llm.total_tokens",
|
|
291
|
+
"llm.step_count",
|
|
292
|
+
],
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
name: "ai.streamText.step",
|
|
296
|
+
allowedAttributes: [
|
|
297
|
+
{ name: "step.number", type: "number" },
|
|
298
|
+
{
|
|
299
|
+
name: "step.type",
|
|
300
|
+
allowedValues: ["text", "tool_call", "thinking", "reasoning"],
|
|
301
|
+
},
|
|
302
|
+
],
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
name: "clark.session",
|
|
306
|
+
allowedAttributes: [
|
|
307
|
+
"session.duration_ms",
|
|
308
|
+
"session.step_count",
|
|
309
|
+
"session.llm_call_count",
|
|
310
|
+
"session.tool_call_count",
|
|
311
|
+
"session.total_tokens",
|
|
312
|
+
{
|
|
313
|
+
name: "session.outcome",
|
|
314
|
+
allowedValues: ["success", "error", "aborted"],
|
|
315
|
+
},
|
|
316
|
+
],
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
name: "clark.debug_loop",
|
|
320
|
+
allowedAttributes: [
|
|
321
|
+
{ name: "loop.iteration", type: "number" },
|
|
322
|
+
{
|
|
323
|
+
name: "loop.reason",
|
|
324
|
+
allowedValues: ["error_recovery", "validation_failure", "retry"],
|
|
325
|
+
},
|
|
326
|
+
{ name: "loop.duration_ms", type: "number" },
|
|
327
|
+
],
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
name: "grpc.*",
|
|
331
|
+
allowedAttributes: [
|
|
332
|
+
{ name: "rpc.system", allowedValues: ["grpc"] },
|
|
333
|
+
{ name: "rpc.service", maxCardinality: 50 },
|
|
334
|
+
{ name: "rpc.method", maxCardinality: 100 },
|
|
335
|
+
{ name: "rpc.grpc.status_code", type: "number" },
|
|
336
|
+
],
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
name: "kafka.*",
|
|
340
|
+
allowedAttributes: [
|
|
341
|
+
{ name: "messaging.system", allowedValues: ["kafka"] },
|
|
342
|
+
{ name: "messaging.destination", maxCardinality: 50 },
|
|
343
|
+
{
|
|
344
|
+
name: "messaging.operation",
|
|
345
|
+
allowedValues: ["publish", "receive", "process"],
|
|
346
|
+
},
|
|
347
|
+
],
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
name: "redis.*",
|
|
351
|
+
allowedAttributes: [
|
|
352
|
+
{ name: "db.system", allowedValues: ["redis"] },
|
|
353
|
+
{ name: "db.operation", maxCardinality: 30 },
|
|
354
|
+
],
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
name: "fetch",
|
|
358
|
+
allowedAttributes: [
|
|
359
|
+
"http.method",
|
|
360
|
+
"http.status_code",
|
|
361
|
+
{ name: "http.host", maxCardinality: 200 },
|
|
362
|
+
],
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
name: "schedule.*",
|
|
366
|
+
allowedAttributes: [
|
|
367
|
+
{
|
|
368
|
+
name: "schedule.type",
|
|
369
|
+
allowedValues: ["cron", "interval", "one_time"],
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
name: "schedule.status",
|
|
373
|
+
allowedValues: ["success", "error", "skipped"],
|
|
374
|
+
},
|
|
375
|
+
],
|
|
376
|
+
},
|
|
377
|
+
];
|
|
73
378
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* Hashes enable aggregate analysis without exposing plaintext identifiers.
|
|
77
|
-
*
|
|
78
|
-
* Mapping:
|
|
79
|
-
* user-email, user.email, etc. → user.hash
|
|
80
|
-
* organization-id, organization_id → organization.hash
|
|
81
|
-
* application-id, application_id → application.hash
|
|
82
|
-
* session.id → session.hash
|
|
83
|
-
* enduser.id → enduser.pseudo.id
|
|
379
|
+
* Cloud trace contract: match-all span name ("*") so no spans are dropped by name.
|
|
380
|
+
* Attribute allowlist is not used when attributeAllowlistPassthrough is true.
|
|
84
381
|
*/
|
|
85
|
-
export const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
'user.email',
|
|
89
|
-
'user_email',
|
|
90
|
-
'user.id',
|
|
91
|
-
'enduser.email',
|
|
92
|
-
// Organization identity (hashed to organization.hash)
|
|
93
|
-
'organization-id',
|
|
94
|
-
'organization_id',
|
|
95
|
-
// Application identity (hashed to application.hash)
|
|
96
|
-
'application-id',
|
|
97
|
-
'application_id',
|
|
98
|
-
// Session/enduser identity
|
|
99
|
-
'session.id',
|
|
100
|
-
'enduser.id',
|
|
101
|
-
]);
|
|
382
|
+
export const CLOUD_TRACE_CONTRACT = [
|
|
383
|
+
{ name: "*", allowedAttributes: [] },
|
|
384
|
+
];
|
|
102
385
|
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
386
|
+
* Returns the trace contract (span definitions) for the given deployment type.
|
|
387
|
+
* Cloud: match-all so no traces are dropped by span name.
|
|
388
|
+
* Cloud-prem: Tier 2 contract (named spans only).
|
|
105
389
|
*/
|
|
106
|
-
export
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
390
|
+
export function getTraceContract(deploymentType) {
|
|
391
|
+
switch (deploymentType) {
|
|
392
|
+
case DeploymentTypeEnum.CLOUD:
|
|
393
|
+
return CLOUD_TRACE_CONTRACT;
|
|
394
|
+
case DeploymentTypeEnum.CLOUD_PREM:
|
|
395
|
+
default:
|
|
396
|
+
return TIER_2_TRACE_CONTRACT;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
// ---------------------------------------------------------------------------
|
|
400
|
+
// Forbidden / hashed / dropped attribute names (v0.2.0 JSON)
|
|
401
|
+
// ---------------------------------------------------------------------------
|
|
402
|
+
/** Forbidden in Tier 2 (forbiddenAttributes in contract). Collector strips these entirely. */
|
|
403
|
+
export const FORBIDDEN_TIER_2_SPAN_ATTRIBUTES = [
|
|
404
|
+
"llmobs.input",
|
|
405
|
+
"llmobs.output",
|
|
406
|
+
"prompt",
|
|
407
|
+
"code",
|
|
408
|
+
"tool_input",
|
|
409
|
+
"tool_output",
|
|
410
|
+
"file_path",
|
|
411
|
+
"file_content",
|
|
412
|
+
"db.statement",
|
|
413
|
+
"db.query_text",
|
|
414
|
+
"db.query.text",
|
|
415
|
+
"http.request.body",
|
|
416
|
+
"http.response.body",
|
|
417
|
+
"url.full",
|
|
418
|
+
"url.query",
|
|
419
|
+
"http.url",
|
|
420
|
+
"http.target",
|
|
421
|
+
"user-email",
|
|
422
|
+
"user.email",
|
|
423
|
+
"user_email",
|
|
424
|
+
"enduser.email",
|
|
425
|
+
"api-name",
|
|
426
|
+
"api_name",
|
|
427
|
+
"resource-name",
|
|
428
|
+
"resource_name",
|
|
429
|
+
"widget-type",
|
|
430
|
+
"branch",
|
|
431
|
+
"error.stack",
|
|
432
|
+
"exception.stacktrace",
|
|
433
|
+
"auth_token",
|
|
434
|
+
"api_key",
|
|
435
|
+
"authorization",
|
|
436
|
+
"cookie",
|
|
437
|
+
"x-api-key",
|
|
438
|
+
];
|
|
439
|
+
/** Hashed (keyed HMAC) for Tier 2 (hashedAttributes in contract). */
|
|
440
|
+
export const HASHED_TIER_2_SPAN_ATTRIBUTES = [];
|
|
441
|
+
/** Dropped — high cardinality, no hash value (droppedAttributes in contract). */
|
|
442
|
+
export const DROPPED_HIGH_CARDINALITY_ATTRIBUTES = ["binding_keys"];
|
|
443
|
+
// ---------------------------------------------------------------------------
|
|
444
|
+
// Set views (for lint, guardrails: fast .has() lookup)
|
|
445
|
+
// ---------------------------------------------------------------------------
|
|
446
|
+
export const TIER2_FORBIDDEN_ATTRIBUTES = new Set(FORBIDDEN_TIER_2_SPAN_ATTRIBUTES);
|
|
447
|
+
export const TIER2_HASHED_ATTRIBUTES = new Set(HASHED_TIER_2_SPAN_ATTRIBUTES);
|
|
448
|
+
export const TIER2_DROPPED_ATTRIBUTES = new Set(DROPPED_HIGH_CARDINALITY_ATTRIBUTES);
|
|
449
|
+
// ---------------------------------------------------------------------------
|
|
450
|
+
// Per-deployment attribute sets (for trace-sanitizer)
|
|
451
|
+
// ---------------------------------------------------------------------------
|
|
452
|
+
/** Empty set used for cloud (relaxed policy: no drop, no hash, no forbidden). */
|
|
453
|
+
const EMPTY_ATTRIBUTE_SET = new Set();
|
|
115
454
|
/**
|
|
116
|
-
*
|
|
455
|
+
* Returns the Tier 2 trace attribute sets and contract options for the given deployment type.
|
|
456
|
+
* Cloud: relaxed policy (no attributes dropped/hashed), match-all span names, pass-through attributes.
|
|
457
|
+
* Cloud-prem: full Tier 2 contract (forbidden/dropped/hashed), named spans only, pass-through attributes.
|
|
117
458
|
*/
|
|
118
|
-
export
|
|
119
|
-
|
|
120
|
-
|
|
459
|
+
export function getTraceSanitizerAttributeSets(deploymentType) {
|
|
460
|
+
const spanDefinitions = getTraceContract(deploymentType);
|
|
461
|
+
const attributeAllowlistPassthrough = true;
|
|
462
|
+
switch (deploymentType) {
|
|
463
|
+
case DeploymentTypeEnum.CLOUD:
|
|
464
|
+
return {
|
|
465
|
+
forbiddenAttributes: EMPTY_ATTRIBUTE_SET,
|
|
466
|
+
droppedAttributes: EMPTY_ATTRIBUTE_SET,
|
|
467
|
+
hashedAttributes: EMPTY_ATTRIBUTE_SET,
|
|
468
|
+
spanDefinitions,
|
|
469
|
+
attributeAllowlistPassthrough,
|
|
470
|
+
};
|
|
471
|
+
case DeploymentTypeEnum.CLOUD_PREM:
|
|
472
|
+
default:
|
|
473
|
+
return {
|
|
474
|
+
forbiddenAttributes: TIER2_FORBIDDEN_ATTRIBUTES,
|
|
475
|
+
droppedAttributes: TIER2_DROPPED_ATTRIBUTES,
|
|
476
|
+
hashedAttributes: TIER2_HASHED_ATTRIBUTES,
|
|
477
|
+
spanDefinitions,
|
|
478
|
+
attributeAllowlistPassthrough,
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
// ---------------------------------------------------------------------------
|
|
483
|
+
// Always-sample and value patterns (v0.2.0 samplingPolicy + lint-time)
|
|
484
|
+
// ---------------------------------------------------------------------------
|
|
485
|
+
/** Spans that should ALWAYS be sampled (samplingPolicy.alwaysSampleSpans in contract). */
|
|
486
|
+
export const ALWAYS_SAMPLE_SPANS = new Set(["api.execute"]);
|
|
121
487
|
/**
|
|
122
|
-
* Patterns that indicate forbidden content in attribute values.
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
* IMPORTANT: Patterns should NOT use ^ and $ anchors so they match
|
|
126
|
-
* secrets embedded anywhere in a string (e.g., in query params, headers).
|
|
488
|
+
* Patterns that indicate forbidden content in attribute values (e.g. secrets in strings).
|
|
489
|
+
* No ^/$ anchors so they match secrets embedded anywhere.
|
|
490
|
+
* It's not used by TraceSanitizer, only in guardrails.
|
|
127
491
|
*/
|
|
128
492
|
export const FORBIDDEN_VALUE_PATTERNS = [
|
|
129
|
-
// JWT tokens (anywhere in string)
|
|
130
|
-
// Header (eyJ...) and payload (eyJ...) must be base64url encoded JSON
|
|
131
|
-
// Signature can be any length (even short for test tokens)
|
|
132
493
|
/eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]+/,
|
|
133
|
-
// API keys (sk-/pk- prefix patterns with word boundaries)
|
|
134
494
|
/\b(sk|pk)-[a-zA-Z0-9]{32,}\b/,
|
|
135
|
-
// Bearer tokens (anywhere in string)
|
|
136
495
|
/Bearer\s+[A-Za-z0-9._-]{20,}/,
|
|
137
|
-
// PEM blocks (anywhere in string)
|
|
138
496
|
/-----BEGIN\s+(RSA\s+)?(PRIVATE|PUBLIC)\s+KEY-----/,
|
|
139
|
-
// AWS access key IDs
|
|
140
497
|
/\bAKIA[A-Z0-9]{16}\b/,
|
|
141
|
-
// GitHub tokens
|
|
142
498
|
/\b(ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}\b/,
|
|
143
|
-
// Generic API key patterns (key=value or key:value with long alphanumeric)
|
|
144
499
|
/\b(api[_-]?key|apikey|secret[_-]?key|access[_-]?token)[=:]\s*[A-Za-z0-9_-]{20,}\b/i,
|
|
145
500
|
];
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
501
|
+
// ---------------------------------------------------------------------------
|
|
502
|
+
// Helpers (for lint, guardrails)
|
|
503
|
+
// ---------------------------------------------------------------------------
|
|
149
504
|
export function isForbiddenAttribute(name) {
|
|
150
505
|
return TIER2_FORBIDDEN_ATTRIBUTES.has(name);
|
|
151
506
|
}
|
|
152
|
-
/**
|
|
153
|
-
* Check if an attribute should be hashed in Tier 2.
|
|
154
|
-
*/
|
|
155
507
|
export function isHashedAttribute(name) {
|
|
156
508
|
return TIER2_HASHED_ATTRIBUTES.has(name);
|
|
157
509
|
}
|
|
158
|
-
/**
|
|
159
|
-
* Check if an attribute should be dropped in Tier 2.
|
|
160
|
-
*/
|
|
161
510
|
export function isDroppedAttribute(name) {
|
|
162
511
|
return TIER2_DROPPED_ATTRIBUTES.has(name);
|
|
163
512
|
}
|
|
164
|
-
/**
|
|
165
|
-
* Check if a value contains forbidden patterns (like tokens, keys).
|
|
166
|
-
*/
|
|
167
513
|
export function containsForbiddenPattern(value) {
|
|
168
|
-
if (typeof value !==
|
|
514
|
+
if (typeof value !== "string")
|
|
169
515
|
return false;
|
|
170
|
-
return FORBIDDEN_VALUE_PATTERNS.some(pattern => pattern.test(value));
|
|
516
|
+
return FORBIDDEN_VALUE_PATTERNS.some((pattern) => pattern.test(value));
|
|
171
517
|
}
|
|
172
|
-
/**
|
|
173
|
-
* Check if a span should always be sampled.
|
|
174
|
-
*/
|
|
175
518
|
export function shouldAlwaysSample(spanName) {
|
|
176
519
|
return ALWAYS_SAMPLE_SPANS.has(spanName);
|
|
177
520
|
}
|