toad-eye 2.4.2 → 2.4.4

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
@@ -120,6 +120,8 @@ const result = await traceLLMCall(
120
120
 
121
121
  > Or skip this entirely — use `instrument: ['openai']` for zero-code instrumentation.
122
122
 
123
+ > **Note:** In short-lived scripts, call `await shutdown()` before exit to flush buffered spans. Long-running servers (Express, Hono, Next.js) don't need this — spans flush automatically.
124
+
123
125
  </details>
124
126
 
125
127
  ## Budget guards
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { execFileSync, spawn } from "node:child_process";
3
- import { cpSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
3
+ import { cpSync, existsSync, mkdirSync, realpathSync, writeFileSync, } from "node:fs";
4
4
  import { join, resolve } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { initObservability, traceLLMCall, shutdown, calculateCost, } from "./index.js";
@@ -277,8 +277,9 @@ function runCli() {
277
277
  process.exit(1);
278
278
  }
279
279
  }
280
- // Only auto-execute when run as CLI entry point, not when imported (e.g., in tests)
280
+ // Only auto-execute when run as CLI entry point, not when imported (e.g., in tests).
281
+ // Use realpathSync to resolve symlinks (npx creates a symlink in node_modules/.bin/).
281
282
  if (process.argv[1] !== undefined &&
282
- fileURLToPath(import.meta.url) === resolve(process.argv[1])) {
283
+ fileURLToPath(import.meta.url) === realpathSync(resolve(process.argv[1]))) {
283
284
  runCli();
284
285
  }
@@ -3,7 +3,7 @@ import { resourceFromAttributes } from "@opentelemetry/resources";
3
3
  import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
4
4
  import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
5
5
  import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
6
- import { TraceIdRatioBasedSampler, ParentBasedSampler, } from "@opentelemetry/sdk-trace-node";
6
+ import { TraceIdRatioBasedSampler, ParentBasedSampler, BatchSpanProcessor, } from "@opentelemetry/sdk-trace-node";
7
7
  import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
8
8
  import { initMetrics, resetMetrics } from "./metrics.js";
9
9
  import { resetCustomPricing } from "./pricing.js";
@@ -74,9 +74,11 @@ export function initObservability(config) {
74
74
  exporter: metricExporter,
75
75
  exportIntervalMillis: isCloudMode ? 10_000 : 5_000,
76
76
  });
77
- // Add Vercel AI SDK SpanProcessor if 'ai' is in instrument list
77
+ // When custom SpanProcessors are needed (e.g., Vercel AI SDK),
78
+ // we must also include a BatchSpanProcessor for trace export —
79
+ // NodeSDK won't create one automatically when spanProcessors is provided.
78
80
  const spanProcessors = config.instrument?.includes("ai")
79
- ? [new ToadEyeAISpanProcessor()]
81
+ ? [new BatchSpanProcessor(traceExporter), new ToadEyeAISpanProcessor()]
80
82
  : [];
81
83
  // SDK-side head sampling (default: 1.0 = send everything to Collector)
82
84
  const sdkRate = config.sampling?.sdkRate ?? 1.0;
package/package.json CHANGED
@@ -1,30 +1,35 @@
1
1
  {
2
2
  "name": "toad-eye",
3
- "version": "2.4.2",
3
+ "version": "2.4.4",
4
4
  "description": "Auto-instrumentation, cost tracking, budget guards, and observability for LLM services",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
+ "types": "./dist/index.d.ts",
10
11
  "import": "./dist/index.js",
11
- "types": "./dist/index.d.ts"
12
+ "default": "./dist/index.js"
12
13
  },
13
14
  "./alerts": {
15
+ "types": "./dist/alerts/index.d.ts",
14
16
  "import": "./dist/alerts/index.js",
15
- "types": "./dist/alerts/index.d.ts"
17
+ "default": "./dist/alerts/index.js"
16
18
  },
17
19
  "./drift": {
20
+ "types": "./dist/drift/index.d.ts",
18
21
  "import": "./dist/drift/index.js",
19
- "types": "./dist/drift/index.d.ts"
22
+ "default": "./dist/drift/index.js"
20
23
  },
21
24
  "./export": {
25
+ "types": "./dist/export.d.ts",
22
26
  "import": "./dist/export.js",
23
- "types": "./dist/export.d.ts"
27
+ "default": "./dist/export.js"
24
28
  },
25
29
  "./vercel": {
30
+ "types": "./dist/vercel.d.ts",
26
31
  "import": "./dist/vercel.js",
27
- "types": "./dist/vercel.d.ts"
32
+ "default": "./dist/vercel.js"
28
33
  }
29
34
  },
30
35
  "bin": {
@@ -9,31 +9,29 @@ processors:
9
9
  timeout: 1s
10
10
 
11
11
  # Tail-based sampling: keeps 100% errors + slow traces, samples healthy traffic.
12
- # Only applies to traces pipeline — metrics always get 100%.
13
- # To disable: remove tail_sampling from traces pipeline processors.
12
+ # Disabled by default for local development (100% of traces kept).
13
+ # To enable for production: change sampling_percentage to 10 (or your desired rate)
14
+ # and uncomment tail_sampling in the traces pipeline processors below.
14
15
  tail_sampling:
15
16
  decision_wait: 10s
16
17
  num_traces: 100000
17
18
  expected_new_traces_per_sec: 100
18
19
  policies:
19
- # Keep all traces with errors
20
20
  - name: errors-always
21
21
  type: status_code
22
22
  status_code:
23
23
  status_codes: [ERROR]
24
- # Keep all slow traces (> 2s)
25
24
  - name: slow-traces
26
25
  type: latency
27
26
  latency:
28
27
  threshold_ms: 2000
29
- # Sample 10% of remaining healthy traffic
30
28
  - name: probabilistic-fallback
31
29
  type: probabilistic
32
30
  probabilistic:
33
- sampling_percentage: 10
31
+ sampling_percentage: 100
34
32
 
35
33
  exporters:
36
- otlphttp/jaeger:
34
+ otlp_http/jaeger:
37
35
  endpoint: http://jaeger:4318
38
36
  tls:
39
37
  insecure: true
@@ -45,8 +43,8 @@ service:
45
43
  pipelines:
46
44
  traces:
47
45
  receivers: [otlp]
48
- processors: [tail_sampling, batch]
49
- exporters: [otlphttp/jaeger]
46
+ processors: [batch]
47
+ exporters: [otlp_http/jaeger]
50
48
  metrics:
51
49
  receivers: [otlp]
52
50
  processors: [batch]