@superblocksteam/telemetry 2.0.83-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/LICENSE.txt +87 -0
- package/README.md +155 -0
- package/dist/browser/index.d.ts +8 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +19 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/init.d.ts +75 -0
- package/dist/browser/init.d.ts.map +1 -0
- package/dist/browser/init.js +169 -0
- package/dist/browser/init.js.map +1 -0
- package/dist/browser/resilient-exporter.d.ts +43 -0
- package/dist/browser/resilient-exporter.d.ts.map +1 -0
- package/dist/browser/resilient-exporter.js +88 -0
- package/dist/browser/resilient-exporter.js.map +1 -0
- package/dist/common/contracts/tier2-traces.d.ts +75 -0
- package/dist/common/contracts/tier2-traces.d.ts.map +1 -0
- package/dist/common/contracts/tier2-traces.js +186 -0
- package/dist/common/contracts/tier2-traces.js.map +1 -0
- package/dist/common/deployment-type.d.ts +18 -0
- package/dist/common/deployment-type.d.ts.map +1 -0
- package/dist/common/deployment-type.js +30 -0
- package/dist/common/deployment-type.js.map +1 -0
- package/dist/common/guardrails.d.ts +116 -0
- package/dist/common/guardrails.d.ts.map +1 -0
- package/dist/common/guardrails.js +189 -0
- package/dist/common/guardrails.js.map +1 -0
- package/dist/common/index.d.ts +16 -0
- package/dist/common/index.d.ts.map +1 -0
- package/dist/common/index.js +32 -0
- package/dist/common/index.js.map +1 -0
- package/dist/common/log-sanitizer.d.ts +78 -0
- package/dist/common/log-sanitizer.d.ts.map +1 -0
- package/dist/common/log-sanitizer.js +340 -0
- package/dist/common/log-sanitizer.js.map +1 -0
- package/dist/common/policy-evaluator.d.ts +103 -0
- package/dist/common/policy-evaluator.d.ts.map +1 -0
- package/dist/common/policy-evaluator.js +200 -0
- package/dist/common/policy-evaluator.js.map +1 -0
- package/dist/common/resource.d.ts +62 -0
- package/dist/common/resource.d.ts.map +1 -0
- package/dist/common/resource.js +106 -0
- package/dist/common/resource.js.map +1 -0
- package/dist/common/tier-hints.d.ts +182 -0
- package/dist/common/tier-hints.d.ts.map +1 -0
- package/dist/common/tier-hints.js +209 -0
- package/dist/common/tier-hints.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/lint/forbidden-attributes.d.ts +149 -0
- package/dist/lint/forbidden-attributes.d.ts.map +1 -0
- package/dist/lint/forbidden-attributes.js +214 -0
- package/dist/lint/forbidden-attributes.js.map +1 -0
- package/dist/lint/index.d.ts +9 -0
- package/dist/lint/index.d.ts.map +1 -0
- package/dist/lint/index.js +16 -0
- package/dist/lint/index.js.map +1 -0
- package/dist/llmobs/index.d.ts +22 -0
- package/dist/llmobs/index.d.ts.map +1 -0
- package/dist/llmobs/index.js +29 -0
- package/dist/llmobs/index.js.map +1 -0
- package/dist/llmobs/tier1-exporter.d.ts +146 -0
- package/dist/llmobs/tier1-exporter.d.ts.map +1 -0
- package/dist/llmobs/tier1-exporter.js +196 -0
- package/dist/llmobs/tier1-exporter.js.map +1 -0
- package/dist/llmobs/tier2-summarizer.d.ts +268 -0
- package/dist/llmobs/tier2-summarizer.d.ts.map +1 -0
- package/dist/llmobs/tier2-summarizer.js +650 -0
- package/dist/llmobs/tier2-summarizer.js.map +1 -0
- package/dist/node/exporters/resilient-exporter.d.ts +77 -0
- package/dist/node/exporters/resilient-exporter.d.ts.map +1 -0
- package/dist/node/exporters/resilient-exporter.js +129 -0
- package/dist/node/exporters/resilient-exporter.js.map +1 -0
- package/dist/node/index.d.ts +11 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +24 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/init.d.ts +75 -0
- package/dist/node/init.d.ts.map +1 -0
- package/dist/node/init.js +245 -0
- package/dist/node/init.js.map +1 -0
- package/dist/node/log-processor.d.ts +83 -0
- package/dist/node/log-processor.d.ts.map +1 -0
- package/dist/node/log-processor.js +266 -0
- package/dist/node/log-processor.js.map +1 -0
- package/dist/node/metrics-client.d.ts +66 -0
- package/dist/node/metrics-client.d.ts.map +1 -0
- package/dist/node/metrics-client.js +193 -0
- package/dist/node/metrics-client.js.map +1 -0
- package/dist/node/traced-socket.d.ts +76 -0
- package/dist/node/traced-socket.d.ts.map +1 -0
- package/dist/node/traced-socket.js +261 -0
- package/dist/node/traced-socket.js.map +1 -0
- package/dist/testing/in-memory-exporter.d.ts +179 -0
- package/dist/testing/in-memory-exporter.d.ts.map +1 -0
- package/dist/testing/in-memory-exporter.js +254 -0
- package/dist/testing/in-memory-exporter.js.map +1 -0
- package/dist/testing/index.d.ts +8 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +19 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/test-init.d.ts +80 -0
- package/dist/testing/test-init.d.ts.map +1 -0
- package/dist/testing/test-init.js +144 -0
- package/dist/testing/test-init.js.map +1 -0
- package/dist/types/index.d.ts +40 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +23 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/policy.d.ts +92 -0
- package/dist/types/policy.d.ts.map +1 -0
- package/dist/types/policy.js +125 -0
- package/dist/types/policy.js.map +1 -0
- package/dist-esm/browser/index.d.ts +8 -0
- package/dist-esm/browser/index.d.ts.map +1 -0
- package/dist-esm/browser/index.js +9 -0
- package/dist-esm/browser/index.js.map +1 -0
- package/dist-esm/browser/init.d.ts +75 -0
- package/dist-esm/browser/init.d.ts.map +1 -0
- package/dist-esm/browser/init.js +162 -0
- package/dist-esm/browser/init.js.map +1 -0
- package/dist-esm/browser/resilient-exporter.d.ts +43 -0
- package/dist-esm/browser/resilient-exporter.d.ts.map +1 -0
- package/dist-esm/browser/resilient-exporter.js +84 -0
- package/dist-esm/browser/resilient-exporter.js.map +1 -0
- package/dist-esm/common/contracts/tier2-traces.d.ts +75 -0
- package/dist-esm/common/contracts/tier2-traces.d.ts.map +1 -0
- package/dist-esm/common/contracts/tier2-traces.js +178 -0
- package/dist-esm/common/contracts/tier2-traces.js.map +1 -0
- package/dist-esm/common/deployment-type.d.ts +18 -0
- package/dist-esm/common/deployment-type.d.ts.map +1 -0
- package/dist-esm/common/deployment-type.js +27 -0
- package/dist-esm/common/deployment-type.js.map +1 -0
- package/dist-esm/common/guardrails.d.ts +116 -0
- package/dist-esm/common/guardrails.d.ts.map +1 -0
- package/dist-esm/common/guardrails.js +179 -0
- package/dist-esm/common/guardrails.js.map +1 -0
- package/dist-esm/common/index.d.ts +16 -0
- package/dist-esm/common/index.d.ts.map +1 -0
- package/dist-esm/common/index.js +16 -0
- package/dist-esm/common/index.js.map +1 -0
- package/dist-esm/common/log-sanitizer.d.ts +78 -0
- package/dist-esm/common/log-sanitizer.d.ts.map +1 -0
- package/dist-esm/common/log-sanitizer.js +331 -0
- package/dist-esm/common/log-sanitizer.js.map +1 -0
- package/dist-esm/common/policy-evaluator.d.ts +103 -0
- package/dist-esm/common/policy-evaluator.d.ts.map +1 -0
- package/dist-esm/common/policy-evaluator.js +196 -0
- package/dist-esm/common/policy-evaluator.js.map +1 -0
- package/dist-esm/common/resource.d.ts +62 -0
- package/dist-esm/common/resource.d.ts.map +1 -0
- package/dist-esm/common/resource.js +100 -0
- package/dist-esm/common/resource.js.map +1 -0
- package/dist-esm/common/tier-hints.d.ts +182 -0
- package/dist-esm/common/tier-hints.d.ts.map +1 -0
- package/dist-esm/common/tier-hints.js +199 -0
- package/dist-esm/common/tier-hints.js.map +1 -0
- package/dist-esm/index.d.ts +43 -0
- package/dist-esm/index.d.ts.map +1 -0
- package/dist-esm/index.js +53 -0
- package/dist-esm/index.js.map +1 -0
- package/dist-esm/lint/forbidden-attributes.d.ts +149 -0
- package/dist-esm/lint/forbidden-attributes.d.ts.map +1 -0
- package/dist-esm/lint/forbidden-attributes.js +209 -0
- package/dist-esm/lint/forbidden-attributes.js.map +1 -0
- package/dist-esm/lint/index.d.ts +9 -0
- package/dist-esm/lint/index.d.ts.map +1 -0
- package/dist-esm/lint/index.js +9 -0
- package/dist-esm/lint/index.js.map +1 -0
- package/dist-esm/llmobs/index.d.ts +22 -0
- package/dist-esm/llmobs/index.d.ts.map +1 -0
- package/dist-esm/llmobs/index.js +22 -0
- package/dist-esm/llmobs/index.js.map +1 -0
- package/dist-esm/llmobs/tier1-exporter.d.ts +146 -0
- package/dist-esm/llmobs/tier1-exporter.d.ts.map +1 -0
- package/dist-esm/llmobs/tier1-exporter.js +190 -0
- package/dist-esm/llmobs/tier1-exporter.js.map +1 -0
- package/dist-esm/llmobs/tier2-summarizer.d.ts +268 -0
- package/dist-esm/llmobs/tier2-summarizer.d.ts.map +1 -0
- package/dist-esm/llmobs/tier2-summarizer.js +646 -0
- package/dist-esm/llmobs/tier2-summarizer.js.map +1 -0
- package/dist-esm/node/exporters/resilient-exporter.d.ts +77 -0
- package/dist-esm/node/exporters/resilient-exporter.d.ts.map +1 -0
- package/dist-esm/node/exporters/resilient-exporter.js +125 -0
- package/dist-esm/node/exporters/resilient-exporter.js.map +1 -0
- package/dist-esm/node/index.d.ts +11 -0
- package/dist-esm/node/index.d.ts.map +1 -0
- package/dist-esm/node/index.js +11 -0
- package/dist-esm/node/index.js.map +1 -0
- package/dist-esm/node/init.d.ts +75 -0
- package/dist-esm/node/init.d.ts.map +1 -0
- package/dist-esm/node/init.js +239 -0
- package/dist-esm/node/init.js.map +1 -0
- package/dist-esm/node/log-processor.d.ts +83 -0
- package/dist-esm/node/log-processor.d.ts.map +1 -0
- package/dist-esm/node/log-processor.js +261 -0
- package/dist-esm/node/log-processor.js.map +1 -0
- package/dist-esm/node/metrics-client.d.ts +66 -0
- package/dist-esm/node/metrics-client.d.ts.map +1 -0
- package/dist-esm/node/metrics-client.js +189 -0
- package/dist-esm/node/metrics-client.js.map +1 -0
- package/dist-esm/node/traced-socket.d.ts +76 -0
- package/dist-esm/node/traced-socket.d.ts.map +1 -0
- package/dist-esm/node/traced-socket.js +257 -0
- package/dist-esm/node/traced-socket.js.map +1 -0
- package/dist-esm/testing/in-memory-exporter.d.ts +179 -0
- package/dist-esm/testing/in-memory-exporter.d.ts.map +1 -0
- package/dist-esm/testing/in-memory-exporter.js +248 -0
- package/dist-esm/testing/in-memory-exporter.js.map +1 -0
- package/dist-esm/testing/index.d.ts +8 -0
- package/dist-esm/testing/index.d.ts.map +1 -0
- package/dist-esm/testing/index.js +8 -0
- package/dist-esm/testing/index.js.map +1 -0
- package/dist-esm/testing/test-init.d.ts +80 -0
- package/dist-esm/testing/test-init.d.ts.map +1 -0
- package/dist-esm/testing/test-init.js +137 -0
- package/dist-esm/testing/test-init.js.map +1 -0
- package/dist-esm/types/index.d.ts +40 -0
- package/dist-esm/types/index.d.ts.map +1 -0
- package/dist-esm/types/index.js +7 -0
- package/dist-esm/types/index.js.map +1 -0
- package/dist-esm/types/policy.d.ts +92 -0
- package/dist-esm/types/policy.d.ts.map +1 -0
- package/dist-esm/types/policy.js +122 -0
- package/dist-esm/types/policy.js.map +1 -0
- package/package.json +101 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tier Policy Hints
|
|
3
|
+
*
|
|
4
|
+
* SDK-level hints that inform the OTEL Collector how to route spans.
|
|
5
|
+
* These are HINTS, not guarantees — the Collector makes final routing decisions.
|
|
6
|
+
*
|
|
7
|
+
* NOTE: This is different from tier TAGS (which indicate which pipeline processed
|
|
8
|
+
* a span). Hints are prescriptive ("please route this way"), tags are descriptive
|
|
9
|
+
* ("this was processed by Tier X"). The Collector adds tier tags; the SDK adds hints.
|
|
10
|
+
*
|
|
11
|
+
* See: engineering/projects/o11y-refactor/proposals/sdk-tier-policy-hints.md
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The attribute key used for tier policy hints.
|
|
15
|
+
* Collector filters on this attribute to make routing decisions.
|
|
16
|
+
*/
|
|
17
|
+
export const TIER_HINT_ATTRIBUTE = "superblocks.tier_hint";
|
|
18
|
+
/**
|
|
19
|
+
* Tier policy hints that inform the Collector how to route spans.
|
|
20
|
+
*
|
|
21
|
+
* These are HINTS, not guarantees — the Collector makes final routing decisions
|
|
22
|
+
* based on its configuration. In cloud-prem deployments, the Collector respects
|
|
23
|
+
* these hints to control which tiers receive the span.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* import { trace } from '@opentelemetry/api';
|
|
28
|
+
* import { TierPolicyHint, TIER_HINT_ATTRIBUTE } from '@superblocksteam/telemetry';
|
|
29
|
+
*
|
|
30
|
+
* const span = tracer.startSpan('sensitive_operation');
|
|
31
|
+
* span.setAttribute(TIER_HINT_ATTRIBUTE, TierPolicyHint.TIER1_ONLY);
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export var TierPolicyHint;
|
|
35
|
+
(function (TierPolicyHint) {
|
|
36
|
+
/**
|
|
37
|
+
* Route to Tier 1 only. Do not export to Tier 2 or Tier 3.
|
|
38
|
+
*
|
|
39
|
+
* Use for:
|
|
40
|
+
* - Spans containing customer secrets or credentials
|
|
41
|
+
* - Highly sensitive customer data that must not leave their environment
|
|
42
|
+
* - Debug/diagnostic spans that should remain local
|
|
43
|
+
*
|
|
44
|
+
* The span will be stored in the customer's Tier 1 backend (e.g., Tempo)
|
|
45
|
+
* but will NOT be exported to Superblocks (Tier 2) or AI analytics (Tier 3).
|
|
46
|
+
*/
|
|
47
|
+
TierPolicyHint["TIER1_ONLY"] = "tier1_only";
|
|
48
|
+
/**
|
|
49
|
+
* Include in Tier 3 (AI quality analysis) in addition to Tier 1 and Tier 2.
|
|
50
|
+
*
|
|
51
|
+
* Use for:
|
|
52
|
+
* - GenAI spans that should be analyzed for quality metrics
|
|
53
|
+
* - AI/LLM operations where prompts and responses are valuable for analysis
|
|
54
|
+
* - Spans with AI quality signals (latency, token usage, etc.)
|
|
55
|
+
*
|
|
56
|
+
* The span will go to all tiers: Tier 1 (full fidelity), Tier 2 (sanitized),
|
|
57
|
+
* and Tier 3 (AI analytics with identity stripped).
|
|
58
|
+
*/
|
|
59
|
+
TierPolicyHint["INCLUDE_TIER3"] = "include_tier3";
|
|
60
|
+
/**
|
|
61
|
+
* Skip all external export. Tier 1 (local) only, no Tier 2/3.
|
|
62
|
+
* Alias for TIER1_ONLY, kept for semantic clarity.
|
|
63
|
+
*
|
|
64
|
+
* Use for:
|
|
65
|
+
* - High-cardinality diagnostic spans (cost control)
|
|
66
|
+
* - Temporary debug spans that shouldn't persist
|
|
67
|
+
* - Spans that are only useful for local debugging
|
|
68
|
+
*
|
|
69
|
+
* This is functionally equivalent to TIER1_ONLY but communicates
|
|
70
|
+
* a different intent: "this is for cost/noise control" rather than
|
|
71
|
+
* "this contains sensitive data."
|
|
72
|
+
*/
|
|
73
|
+
TierPolicyHint["SKIP_EXPORT"] = "skip_export";
|
|
74
|
+
})(TierPolicyHint || (TierPolicyHint = {}));
|
|
75
|
+
/**
|
|
76
|
+
* Set a tier policy hint on a span.
|
|
77
|
+
*
|
|
78
|
+
* This is a convenience function that sets the `superblocks.tier_hint` attribute.
|
|
79
|
+
* You can also set the attribute directly if preferred.
|
|
80
|
+
*
|
|
81
|
+
* @param span - The span to set the hint on
|
|
82
|
+
* @param hint - The tier policy hint
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* import { setTierHint, TierPolicyHint } from '@superblocksteam/telemetry';
|
|
87
|
+
*
|
|
88
|
+
* tracer.startActiveSpan('decrypt_secret', (span) => {
|
|
89
|
+
* setTierHint(span, TierPolicyHint.TIER1_ONLY);
|
|
90
|
+
* // ... perform operation
|
|
91
|
+
* span.end();
|
|
92
|
+
* });
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export function setTierHint(span, hint) {
|
|
96
|
+
span.setAttribute(TIER_HINT_ATTRIBUTE, hint);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Mark a span as containing sensitive data that should not leave Tier 1.
|
|
100
|
+
*
|
|
101
|
+
* Use this for spans that handle customer secrets, credentials, or other
|
|
102
|
+
* highly sensitive data that must remain in the customer's environment.
|
|
103
|
+
*
|
|
104
|
+
* @param span - The span to mark as sensitive
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* import { markSensitive } from '@superblocksteam/telemetry';
|
|
109
|
+
*
|
|
110
|
+
* tracer.startActiveSpan('decrypt_customer_secret', (span) => {
|
|
111
|
+
* markSensitive(span);
|
|
112
|
+
* // ... decrypt operation
|
|
113
|
+
* span.end();
|
|
114
|
+
* });
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export function markSensitive(span) {
|
|
118
|
+
setTierHint(span, TierPolicyHint.TIER1_ONLY);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Mark a span for AI quality analysis (Tier 3).
|
|
122
|
+
*
|
|
123
|
+
* Use this for GenAI spans that should be analyzed for quality metrics.
|
|
124
|
+
* The span will go to all tiers, with Tier 3 receiving the content
|
|
125
|
+
* (prompts/responses) for AI quality analysis.
|
|
126
|
+
*
|
|
127
|
+
* @param span - The span to mark for AI analysis
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* import { markForAIAnalysis } from '@superblocksteam/telemetry';
|
|
132
|
+
*
|
|
133
|
+
* tracer.startActiveSpan('gen_ai.chat', (span) => {
|
|
134
|
+
* markForAIAnalysis(span);
|
|
135
|
+
* span.setAttribute('gen_ai.system', 'anthropic');
|
|
136
|
+
* // ... LLM call
|
|
137
|
+
* span.end();
|
|
138
|
+
* });
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export function markForAIAnalysis(span) {
|
|
142
|
+
setTierHint(span, TierPolicyHint.INCLUDE_TIER3);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Mark a span as debug-only (no export to Tier 2/3).
|
|
146
|
+
*
|
|
147
|
+
* Use this for high-cardinality diagnostic spans where you want to
|
|
148
|
+
* control costs by preventing export to paid backends.
|
|
149
|
+
*
|
|
150
|
+
* @param span - The span to mark as debug-only
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```typescript
|
|
154
|
+
* import { markDebugOnly } from '@superblocksteam/telemetry';
|
|
155
|
+
*
|
|
156
|
+
* tracer.startActiveSpan('debug.cache_lookup', (span) => {
|
|
157
|
+
* markDebugOnly(span);
|
|
158
|
+
* span.setAttribute('cache.key', cacheKey); // High cardinality OK
|
|
159
|
+
* // ... lookup
|
|
160
|
+
* span.end();
|
|
161
|
+
* });
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export function markDebugOnly(span) {
|
|
165
|
+
setTierHint(span, TierPolicyHint.SKIP_EXPORT);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Check if a span has a tier hint set.
|
|
169
|
+
*
|
|
170
|
+
* @param span - The span to check (must be a ReadableSpan with attributes)
|
|
171
|
+
* @returns The tier hint if set, undefined otherwise
|
|
172
|
+
*/
|
|
173
|
+
export function getTierHint(span) {
|
|
174
|
+
const hint = span.attributes?.[TIER_HINT_ATTRIBUTE];
|
|
175
|
+
if (typeof hint === "string" &&
|
|
176
|
+
Object.values(TierPolicyHint).includes(hint)) {
|
|
177
|
+
return hint;
|
|
178
|
+
}
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Check if a tier hint indicates the span should skip Tier 2 export.
|
|
183
|
+
*
|
|
184
|
+
* @param hint - The tier hint to check
|
|
185
|
+
* @returns true if Tier 2 should be skipped
|
|
186
|
+
*/
|
|
187
|
+
export function shouldSkipTier2(hint) {
|
|
188
|
+
return (hint === TierPolicyHint.TIER1_ONLY || hint === TierPolicyHint.SKIP_EXPORT);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Check if a tier hint indicates the span should be included in Tier 3.
|
|
192
|
+
*
|
|
193
|
+
* @param hint - The tier hint to check
|
|
194
|
+
* @returns true if Tier 3 should be included
|
|
195
|
+
*/
|
|
196
|
+
export function shouldIncludeTier3(hint) {
|
|
197
|
+
return hint === TierPolicyHint.INCLUDE_TIER3;
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=tier-hints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tier-hints.js","sourceRoot":"","sources":["../../src/common/tier-hints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,uBAAuB,CAAC;AAE3D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAN,IAAY,cAyCX;AAzCD,WAAY,cAAc;IACxB;;;;;;;;;;OAUG;IACH,2CAAyB,CAAA;IAEzB;;;;;;;;;;OAUG;IACH,iDAA+B,CAAA;IAE/B;;;;;;;;;;;;OAYG;IACH,6CAA2B,CAAA;AAC7B,CAAC,EAzCW,cAAc,KAAd,cAAc,QAyCzB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,WAAW,CAAC,IAAU,EAAE,IAAoB;IAC1D,IAAI,CAAC,YAAY,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,aAAa,CAAC,IAAU;IACtC,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAU;IAC1C,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,aAAa,CAAC,IAAU;IACtC,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC;AAChD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,IAE3B;IACC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,mBAAmB,CAAC,CAAC;IACpD,IACE,OAAO,IAAI,KAAK,QAAQ;QACxB,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,IAAsB,CAAC,EAC9D,CAAC;QACD,OAAO,IAAsB,CAAC;IAChC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,IAAgC;IAC9D,OAAO,CACL,IAAI,KAAK,cAAc,CAAC,UAAU,IAAI,IAAI,KAAK,cAAc,CAAC,WAAW,CAC1E,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAgC;IACjE,OAAO,IAAI,KAAK,cAAc,CAAC,aAAa,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @superblocksteam/telemetry
|
|
3
|
+
*
|
|
4
|
+
* Canonical telemetry bootstrap package for all Superblocks services.
|
|
5
|
+
* Provides policy-aware OpenTelemetry initialization with tier-based routing.
|
|
6
|
+
*
|
|
7
|
+
* This package is the ONLY approved way to initialize telemetry.
|
|
8
|
+
* Direct usage of NodeSDK or WebTracerProvider is prohibited.
|
|
9
|
+
*
|
|
10
|
+
* ## Usage
|
|
11
|
+
*
|
|
12
|
+
* ### Node.js Services
|
|
13
|
+
*
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { initNodeTelemetry } from '@superblocksteam/telemetry/node';
|
|
16
|
+
* import { getDefaultPolicy, DeploymentType } from '@superblocksteam/shared';
|
|
17
|
+
*
|
|
18
|
+
* const policy = getDefaultPolicy(DeploymentType.CLOUD_PREM);
|
|
19
|
+
* const telemetry = initNodeTelemetry({
|
|
20
|
+
* serviceName: 'my-service',
|
|
21
|
+
* serviceVersion: '1.0.0',
|
|
22
|
+
* environment: 'production',
|
|
23
|
+
* otlpUrl: 'http://localhost:4318',
|
|
24
|
+
* }, policy);
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* ### Browser
|
|
28
|
+
*
|
|
29
|
+
* ```typescript
|
|
30
|
+
* import { initBrowserTelemetry } from '@superblocksteam/telemetry/browser';
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* ### Testing
|
|
34
|
+
*
|
|
35
|
+
* ```typescript
|
|
36
|
+
* import { initTestTelemetry } from '@superblocksteam/telemetry/testing';
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export * from "./types/index.js";
|
|
40
|
+
export * from "./common/index.js";
|
|
41
|
+
export * from "./llmobs/index.js";
|
|
42
|
+
export { initNodeTelemetry, getTelemetryInstance, isTelemetryInitialized, resetTelemetry, type NodeTelemetryInstance, MetricsClient, type Labels, type CounterHandle, type GaugeHandle, type HistogramHandle, TracedSocket, type TracedSocketConfig, type TracedSocketOptions, } from './node/index.js';
|
|
43
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,cAAc,kBAAkB,CAAC;AAGjC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,mBAAmB,CAAC;AAIlC,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,cAAc,EACd,KAAK,qBAAqB,EAC1B,aAAa,EACb,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,YAAY,EACZ,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @superblocksteam/telemetry
|
|
3
|
+
*
|
|
4
|
+
* Canonical telemetry bootstrap package for all Superblocks services.
|
|
5
|
+
* Provides policy-aware OpenTelemetry initialization with tier-based routing.
|
|
6
|
+
*
|
|
7
|
+
* This package is the ONLY approved way to initialize telemetry.
|
|
8
|
+
* Direct usage of NodeSDK or WebTracerProvider is prohibited.
|
|
9
|
+
*
|
|
10
|
+
* ## Usage
|
|
11
|
+
*
|
|
12
|
+
* ### Node.js Services
|
|
13
|
+
*
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { initNodeTelemetry } from '@superblocksteam/telemetry/node';
|
|
16
|
+
* import { getDefaultPolicy, DeploymentType } from '@superblocksteam/shared';
|
|
17
|
+
*
|
|
18
|
+
* const policy = getDefaultPolicy(DeploymentType.CLOUD_PREM);
|
|
19
|
+
* const telemetry = initNodeTelemetry({
|
|
20
|
+
* serviceName: 'my-service',
|
|
21
|
+
* serviceVersion: '1.0.0',
|
|
22
|
+
* environment: 'production',
|
|
23
|
+
* otlpUrl: 'http://localhost:4318',
|
|
24
|
+
* }, policy);
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* ### Browser
|
|
28
|
+
*
|
|
29
|
+
* ```typescript
|
|
30
|
+
* import { initBrowserTelemetry } from '@superblocksteam/telemetry/browser';
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* ### Testing
|
|
34
|
+
*
|
|
35
|
+
* ```typescript
|
|
36
|
+
* import { initTestTelemetry } from '@superblocksteam/telemetry/testing';
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
// Re-export types
|
|
40
|
+
export * from "./types/index.js";
|
|
41
|
+
// Re-export common utilities
|
|
42
|
+
export * from "./common/index.js";
|
|
43
|
+
// Re-export LLMObs tiered telemetry
|
|
44
|
+
export * from "./llmobs/index.js";
|
|
45
|
+
// Re-export Node.js telemetry functions for convenience
|
|
46
|
+
// This allows imports like: import { initNodeTelemetry } from '@superblocksteam/telemetry'
|
|
47
|
+
export { initNodeTelemetry, getTelemetryInstance, isTelemetryInitialized, resetTelemetry, MetricsClient, TracedSocket, } from './node/index.js';
|
|
48
|
+
// Note: Browser and Testing modules are still exported via package.json subpath exports
|
|
49
|
+
// Import them as:
|
|
50
|
+
// - @superblocksteam/telemetry/browser
|
|
51
|
+
// - @superblocksteam/telemetry/testing
|
|
52
|
+
// - @superblocksteam/telemetry/llmobs
|
|
53
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,kBAAkB;AAClB,cAAc,kBAAkB,CAAC;AAEjC,6BAA6B;AAC7B,cAAc,mBAAmB,CAAC;AAElC,oCAAoC;AACpC,cAAc,mBAAmB,CAAC;AAElC,wDAAwD;AACxD,2FAA2F;AAC3F,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,cAAc,EAEd,aAAa,EAKb,YAAY,GAGb,MAAM,iBAAiB,CAAC;AAEzB,wFAAwF;AACxF,kBAAkB;AAClB,yCAAyC;AACzC,yCAAyC;AACzC,wCAAwC"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESLint Rule: No Forbidden Telemetry Attributes
|
|
3
|
+
*
|
|
4
|
+
* This rule detects usage of forbidden attributes in span/metric instrumentation.
|
|
5
|
+
* It catches common leak paths before code is merged.
|
|
6
|
+
*
|
|
7
|
+
* Usage in eslint.config.js:
|
|
8
|
+
* ```
|
|
9
|
+
* import { noForbiddenTelemetryAttributes } from '@superblocksteam/telemetry/lint';
|
|
10
|
+
*
|
|
11
|
+
* export default [
|
|
12
|
+
* {
|
|
13
|
+
* plugins: {
|
|
14
|
+
* telemetry: { rules: { 'no-forbidden-attributes': noForbiddenTelemetryAttributes } }
|
|
15
|
+
* },
|
|
16
|
+
* rules: {
|
|
17
|
+
* 'telemetry/no-forbidden-attributes': 'error'
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* ];
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Forbidden attribute patterns for static analysis.
|
|
25
|
+
*/
|
|
26
|
+
export declare const FORBIDDEN_ATTRIBUTE_PATTERNS: string[];
|
|
27
|
+
/**
|
|
28
|
+
* ESLint rule metadata.
|
|
29
|
+
*/
|
|
30
|
+
export declare const noForbiddenTelemetryAttributesMeta: {
|
|
31
|
+
type: string;
|
|
32
|
+
docs: {
|
|
33
|
+
description: string;
|
|
34
|
+
category: string;
|
|
35
|
+
recommended: boolean;
|
|
36
|
+
};
|
|
37
|
+
messages: {
|
|
38
|
+
forbiddenAttribute: string;
|
|
39
|
+
resourceOnlyAttribute: string;
|
|
40
|
+
};
|
|
41
|
+
schema: never[];
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* ESLint rule implementation.
|
|
45
|
+
*
|
|
46
|
+
* Detects patterns like:
|
|
47
|
+
* - span.setAttribute('prompt', value)
|
|
48
|
+
* - span.setAttributes({ prompt: value })
|
|
49
|
+
* - { 'prompt': value }
|
|
50
|
+
*/
|
|
51
|
+
export declare function noForbiddenTelemetryAttributesCreate(context: any): {
|
|
52
|
+
CallExpression(node: any): void;
|
|
53
|
+
Property(node: any): void;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Complete ESLint rule export.
|
|
57
|
+
*/
|
|
58
|
+
export declare const noForbiddenTelemetryAttributes: {
|
|
59
|
+
meta: {
|
|
60
|
+
type: string;
|
|
61
|
+
docs: {
|
|
62
|
+
description: string;
|
|
63
|
+
category: string;
|
|
64
|
+
recommended: boolean;
|
|
65
|
+
};
|
|
66
|
+
messages: {
|
|
67
|
+
forbiddenAttribute: string;
|
|
68
|
+
resourceOnlyAttribute: string;
|
|
69
|
+
};
|
|
70
|
+
schema: never[];
|
|
71
|
+
};
|
|
72
|
+
create: typeof noForbiddenTelemetryAttributesCreate;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* ESLint rule: No Direct OTEL SDK Usage
|
|
76
|
+
*
|
|
77
|
+
* Detects direct usage of NodeSDK or WebTracerProvider outside the telemetry package.
|
|
78
|
+
*/
|
|
79
|
+
export declare const noDirectOtelSdkMeta: {
|
|
80
|
+
type: string;
|
|
81
|
+
docs: {
|
|
82
|
+
description: string;
|
|
83
|
+
category: string;
|
|
84
|
+
recommended: boolean;
|
|
85
|
+
};
|
|
86
|
+
messages: {
|
|
87
|
+
directSdkUsage: string;
|
|
88
|
+
};
|
|
89
|
+
schema: never[];
|
|
90
|
+
};
|
|
91
|
+
export declare function noDirectOtelSdkCreate(context: any): {
|
|
92
|
+
ImportSpecifier?: undefined;
|
|
93
|
+
CallExpression?: undefined;
|
|
94
|
+
} | {
|
|
95
|
+
ImportSpecifier(node: any): void;
|
|
96
|
+
CallExpression(node: any): void;
|
|
97
|
+
};
|
|
98
|
+
export declare const noDirectOtelSdk: {
|
|
99
|
+
meta: {
|
|
100
|
+
type: string;
|
|
101
|
+
docs: {
|
|
102
|
+
description: string;
|
|
103
|
+
category: string;
|
|
104
|
+
recommended: boolean;
|
|
105
|
+
};
|
|
106
|
+
messages: {
|
|
107
|
+
directSdkUsage: string;
|
|
108
|
+
};
|
|
109
|
+
schema: never[];
|
|
110
|
+
};
|
|
111
|
+
create: typeof noDirectOtelSdkCreate;
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* All telemetry ESLint rules.
|
|
115
|
+
*/
|
|
116
|
+
export declare const telemetryRules: {
|
|
117
|
+
'no-forbidden-attributes': {
|
|
118
|
+
meta: {
|
|
119
|
+
type: string;
|
|
120
|
+
docs: {
|
|
121
|
+
description: string;
|
|
122
|
+
category: string;
|
|
123
|
+
recommended: boolean;
|
|
124
|
+
};
|
|
125
|
+
messages: {
|
|
126
|
+
forbiddenAttribute: string;
|
|
127
|
+
resourceOnlyAttribute: string;
|
|
128
|
+
};
|
|
129
|
+
schema: never[];
|
|
130
|
+
};
|
|
131
|
+
create: typeof noForbiddenTelemetryAttributesCreate;
|
|
132
|
+
};
|
|
133
|
+
'no-direct-otel-sdk': {
|
|
134
|
+
meta: {
|
|
135
|
+
type: string;
|
|
136
|
+
docs: {
|
|
137
|
+
description: string;
|
|
138
|
+
category: string;
|
|
139
|
+
recommended: boolean;
|
|
140
|
+
};
|
|
141
|
+
messages: {
|
|
142
|
+
directSdkUsage: string;
|
|
143
|
+
};
|
|
144
|
+
schema: never[];
|
|
145
|
+
};
|
|
146
|
+
create: typeof noDirectOtelSdkCreate;
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
//# sourceMappingURL=forbidden-attributes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forbidden-attributes.d.ts","sourceRoot":"","sources":["../../src/lint/forbidden-attributes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAOH;;GAEG;AACH,eAAO,MAAM,4BAA4B,UAKxC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kCAAkC;;;;;;;;;;;;CAgB9C,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,oCAAoC,CAAC,OAAO,EAAE,GAAG;yBAsBxC,GAAG;mBA6BT,GAAG;EAuBrB;AAED;;GAEG;AACH,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;CAG1C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;CAa/B,CAAC;AAYF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,GAAG;;;;0BASxB,GAAG;yBAYJ,GAAG;EAsB3B;AAED,eAAO,MAAM,eAAe;;;;;;;;;;;;;;CAG3B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAG1B,CAAC"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESLint Rule: No Forbidden Telemetry Attributes
|
|
3
|
+
*
|
|
4
|
+
* This rule detects usage of forbidden attributes in span/metric instrumentation.
|
|
5
|
+
* It catches common leak paths before code is merged.
|
|
6
|
+
*
|
|
7
|
+
* Usage in eslint.config.js:
|
|
8
|
+
* ```
|
|
9
|
+
* import { noForbiddenTelemetryAttributes } from '@superblocksteam/telemetry/lint';
|
|
10
|
+
*
|
|
11
|
+
* export default [
|
|
12
|
+
* {
|
|
13
|
+
* plugins: {
|
|
14
|
+
* telemetry: { rules: { 'no-forbidden-attributes': noForbiddenTelemetryAttributes } }
|
|
15
|
+
* },
|
|
16
|
+
* rules: {
|
|
17
|
+
* 'telemetry/no-forbidden-attributes': 'error'
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* ];
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
/* eslint-disable @typescript-eslint/no-explicit-any -- ESLint rule APIs use untyped AST nodes */
|
|
24
|
+
import { TIER2_FORBIDDEN_ATTRIBUTES } from '../common/contracts/tier2-traces.js';
|
|
25
|
+
import { RESOURCE_ONLY_ATTRIBUTES } from '../common/resource.js';
|
|
26
|
+
/**
|
|
27
|
+
* Forbidden attribute patterns for static analysis.
|
|
28
|
+
*/
|
|
29
|
+
export const FORBIDDEN_ATTRIBUTE_PATTERNS = [
|
|
30
|
+
// Direct string literals
|
|
31
|
+
...Array.from(TIER2_FORBIDDEN_ATTRIBUTES),
|
|
32
|
+
// Resource-only attributes
|
|
33
|
+
...Array.from(RESOURCE_ONLY_ATTRIBUTES),
|
|
34
|
+
];
|
|
35
|
+
/**
|
|
36
|
+
* ESLint rule metadata.
|
|
37
|
+
*/
|
|
38
|
+
export const noForbiddenTelemetryAttributesMeta = {
|
|
39
|
+
type: 'problem',
|
|
40
|
+
docs: {
|
|
41
|
+
description: 'Disallow forbidden telemetry attributes in Tier 2 paths',
|
|
42
|
+
category: 'Security',
|
|
43
|
+
recommended: true,
|
|
44
|
+
},
|
|
45
|
+
messages: {
|
|
46
|
+
forbiddenAttribute: "Attribute '{{name}}' is forbidden in Tier 2 telemetry. " +
|
|
47
|
+
'This data should only be in Tier 1 (local retention).',
|
|
48
|
+
resourceOnlyAttribute: "Attribute '{{name}}' should be a RESOURCE attribute, not a span attribute. " +
|
|
49
|
+
'Set it in initNodeTelemetry() config, not per-span.',
|
|
50
|
+
},
|
|
51
|
+
schema: [],
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* ESLint rule implementation.
|
|
55
|
+
*
|
|
56
|
+
* Detects patterns like:
|
|
57
|
+
* - span.setAttribute('prompt', value)
|
|
58
|
+
* - span.setAttributes({ prompt: value })
|
|
59
|
+
* - { 'prompt': value }
|
|
60
|
+
*/
|
|
61
|
+
export function noForbiddenTelemetryAttributesCreate(context) {
|
|
62
|
+
const forbiddenSet = new Set(FORBIDDEN_ATTRIBUTE_PATTERNS);
|
|
63
|
+
const resourceOnlySet = RESOURCE_ONLY_ATTRIBUTES;
|
|
64
|
+
function checkAttributeName(node, name) {
|
|
65
|
+
if (TIER2_FORBIDDEN_ATTRIBUTES.has(name)) {
|
|
66
|
+
context.report({
|
|
67
|
+
node,
|
|
68
|
+
messageId: 'forbiddenAttribute',
|
|
69
|
+
data: { name },
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
else if (resourceOnlySet.has(name)) {
|
|
73
|
+
context.report({
|
|
74
|
+
node,
|
|
75
|
+
messageId: 'resourceOnlyAttribute',
|
|
76
|
+
data: { name },
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
// Check span.setAttribute('forbidden', value)
|
|
82
|
+
CallExpression(node) {
|
|
83
|
+
if (node.callee.type === 'MemberExpression' &&
|
|
84
|
+
node.callee.property.name === 'setAttribute' &&
|
|
85
|
+
node.arguments.length >= 1 &&
|
|
86
|
+
node.arguments[0].type === 'Literal' &&
|
|
87
|
+
typeof node.arguments[0].value === 'string') {
|
|
88
|
+
checkAttributeName(node.arguments[0], node.arguments[0].value);
|
|
89
|
+
}
|
|
90
|
+
// Check span.setAttributes({ forbidden: value })
|
|
91
|
+
if (node.callee.type === 'MemberExpression' &&
|
|
92
|
+
node.callee.property.name === 'setAttributes' &&
|
|
93
|
+
node.arguments.length >= 1 &&
|
|
94
|
+
node.arguments[0].type === 'ObjectExpression') {
|
|
95
|
+
for (const prop of node.arguments[0].properties) {
|
|
96
|
+
if (prop.key.type === 'Literal' && typeof prop.key.value === 'string') {
|
|
97
|
+
checkAttributeName(prop.key, prop.key.value);
|
|
98
|
+
}
|
|
99
|
+
else if (prop.key.type === 'Identifier') {
|
|
100
|
+
checkAttributeName(prop.key, prop.key.name);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
// Check object literals with forbidden keys in telemetry-related files
|
|
106
|
+
Property(node) {
|
|
107
|
+
// Only check if we're likely in a telemetry context
|
|
108
|
+
const filename = context.getFilename();
|
|
109
|
+
if (!filename.includes('telemetry') &&
|
|
110
|
+
!filename.includes('tracing') &&
|
|
111
|
+
!filename.includes('observability')) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
let name = null;
|
|
115
|
+
if (node.key.type === 'Literal' && typeof node.key.value === 'string') {
|
|
116
|
+
name = node.key.value;
|
|
117
|
+
}
|
|
118
|
+
else if (node.key.type === 'Identifier') {
|
|
119
|
+
name = node.key.name;
|
|
120
|
+
}
|
|
121
|
+
if (name && forbiddenSet.has(name)) {
|
|
122
|
+
checkAttributeName(node.key, name);
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Complete ESLint rule export.
|
|
129
|
+
*/
|
|
130
|
+
export const noForbiddenTelemetryAttributes = {
|
|
131
|
+
meta: noForbiddenTelemetryAttributesMeta,
|
|
132
|
+
create: noForbiddenTelemetryAttributesCreate,
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* ESLint rule: No Direct OTEL SDK Usage
|
|
136
|
+
*
|
|
137
|
+
* Detects direct usage of NodeSDK or WebTracerProvider outside the telemetry package.
|
|
138
|
+
*/
|
|
139
|
+
export const noDirectOtelSdkMeta = {
|
|
140
|
+
type: 'problem',
|
|
141
|
+
docs: {
|
|
142
|
+
description: 'Disallow direct OpenTelemetry SDK usage outside telemetry package',
|
|
143
|
+
category: 'Best Practices',
|
|
144
|
+
recommended: true,
|
|
145
|
+
},
|
|
146
|
+
messages: {
|
|
147
|
+
directSdkUsage: "Direct usage of '{{name}}' is not allowed. " +
|
|
148
|
+
'Use @superblocksteam/telemetry bootstrap functions instead.',
|
|
149
|
+
},
|
|
150
|
+
schema: [],
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Forbidden OTEL SDK imports.
|
|
154
|
+
*/
|
|
155
|
+
const FORBIDDEN_SDK_IMPORTS = [
|
|
156
|
+
'NodeSDK',
|
|
157
|
+
'WebTracerProvider',
|
|
158
|
+
'NodeTracerProvider',
|
|
159
|
+
'BasicTracerProvider',
|
|
160
|
+
];
|
|
161
|
+
export function noDirectOtelSdkCreate(context) {
|
|
162
|
+
const filename = context.getFilename();
|
|
163
|
+
// Allow in telemetry package itself
|
|
164
|
+
if (filename.includes('packages/telemetry')) {
|
|
165
|
+
return {};
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
ImportSpecifier(node) {
|
|
169
|
+
const importedName = node.imported.name;
|
|
170
|
+
if (FORBIDDEN_SDK_IMPORTS.includes(importedName)) {
|
|
171
|
+
context.report({
|
|
172
|
+
node,
|
|
173
|
+
messageId: 'directSdkUsage',
|
|
174
|
+
data: { name: importedName },
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
// Also check require() calls
|
|
179
|
+
CallExpression(node) {
|
|
180
|
+
if (node.callee.name === 'require' &&
|
|
181
|
+
node.arguments.length === 1 &&
|
|
182
|
+
node.arguments[0].type === 'Literal') {
|
|
183
|
+
const requirePath = node.arguments[0].value;
|
|
184
|
+
if (typeof requirePath === 'string' &&
|
|
185
|
+
(requirePath.includes('@opentelemetry/sdk-node') ||
|
|
186
|
+
requirePath.includes('@opentelemetry/sdk-trace-node') ||
|
|
187
|
+
requirePath.includes('@opentelemetry/sdk-trace-web'))) {
|
|
188
|
+
context.report({
|
|
189
|
+
node,
|
|
190
|
+
messageId: 'directSdkUsage',
|
|
191
|
+
data: { name: requirePath },
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
export const noDirectOtelSdk = {
|
|
199
|
+
meta: noDirectOtelSdkMeta,
|
|
200
|
+
create: noDirectOtelSdkCreate,
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* All telemetry ESLint rules.
|
|
204
|
+
*/
|
|
205
|
+
export const telemetryRules = {
|
|
206
|
+
'no-forbidden-attributes': noForbiddenTelemetryAttributes,
|
|
207
|
+
'no-direct-otel-sdk': noDirectOtelSdk,
|
|
208
|
+
};
|
|
209
|
+
//# sourceMappingURL=forbidden-attributes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forbidden-attributes.js","sourceRoot":"","sources":["../../src/lint/forbidden-attributes.ts"],"names":[],"mappings":"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"}
|