evlog 2.14.0 → 2.15.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/LICENSE +21 -0
- package/README.md +49 -19
- package/dist/adapters/axiom.d.mts +18 -27
- package/dist/adapters/axiom.d.mts.map +1 -1
- package/dist/adapters/axiom.mjs +40 -30
- package/dist/adapters/axiom.mjs.map +1 -1
- package/dist/adapters/better-stack.d.mts +11 -24
- package/dist/adapters/better-stack.d.mts.map +1 -1
- package/dist/adapters/better-stack.mjs +34 -29
- package/dist/adapters/better-stack.mjs.map +1 -1
- package/dist/adapters/datadog.d.mts +1 -1
- package/dist/adapters/datadog.d.mts.map +1 -1
- package/dist/adapters/datadog.mjs +10 -4
- package/dist/adapters/datadog.mjs.map +1 -1
- package/dist/adapters/fs.d.mts +2 -2
- package/dist/adapters/fs.d.mts.map +1 -1
- package/dist/adapters/fs.mjs +19 -7
- package/dist/adapters/fs.mjs.map +1 -1
- package/dist/adapters/hyperdx.d.mts +1 -1
- package/dist/adapters/hyperdx.mjs +1 -2
- package/dist/adapters/hyperdx.mjs.map +1 -1
- package/dist/adapters/otlp.d.mts +1 -1
- package/dist/adapters/otlp.d.mts.map +1 -1
- package/dist/adapters/otlp.mjs +36 -31
- package/dist/adapters/otlp.mjs.map +1 -1
- package/dist/adapters/posthog.d.mts +50 -70
- package/dist/adapters/posthog.d.mts.map +1 -1
- package/dist/adapters/posthog.mjs +50 -85
- package/dist/adapters/posthog.mjs.map +1 -1
- package/dist/adapters/sentry.d.mts +1 -1
- package/dist/adapters/sentry.d.mts.map +1 -1
- package/dist/adapters/sentry.mjs +15 -5
- package/dist/adapters/sentry.mjs.map +1 -1
- package/dist/ai/index.d.mts +1 -1
- package/dist/{audit-d9esRZOK.mjs → audit--n0QRR2Y.mjs} +202 -20
- package/dist/audit--n0QRR2Y.mjs.map +1 -0
- package/dist/{audit-mUutdf6A.d.mts → audit-CJl-wZ10.d.mts} +144 -2
- package/dist/audit-CJl-wZ10.d.mts.map +1 -0
- package/dist/better-auth/index.d.mts +1 -1
- package/dist/better-auth/index.mjs.map +1 -1
- package/dist/browser.d.mts +1 -1
- package/dist/define-D6OJdSUH.mjs +63 -0
- package/dist/define-D6OJdSUH.mjs.map +1 -0
- package/dist/define-Fp8TrdEB.d.mts +57 -0
- package/dist/define-Fp8TrdEB.d.mts.map +1 -0
- package/dist/{dist-Do8P4zWd.mjs → dist-BIlS38vi.mjs} +1 -1
- package/dist/dist-BIlS38vi.mjs.map +1 -0
- package/dist/drain-ByWUeOQC.mjs +160 -0
- package/dist/drain-ByWUeOQC.mjs.map +1 -0
- package/dist/elysia/index.d.mts +25 -2
- package/dist/elysia/index.d.mts.map +1 -1
- package/dist/elysia/index.mjs +53 -20
- package/dist/elysia/index.mjs.map +1 -1
- package/dist/enricher-BA6viylF.mjs +95 -0
- package/dist/enricher-BA6viylF.mjs.map +1 -0
- package/dist/enricher-CLSnrzrr.d.mts +42 -0
- package/dist/enricher-CLSnrzrr.d.mts.map +1 -0
- package/dist/enrichers.d.mts +16 -9
- package/dist/enrichers.d.mts.map +1 -1
- package/dist/enrichers.mjs +81 -64
- package/dist/enrichers.mjs.map +1 -1
- package/dist/{error-D1FZI2Kd.d.mts → error-C-66_G2M.d.mts} +2 -2
- package/dist/{error-D1FZI2Kd.d.mts.map → error-C-66_G2M.d.mts.map} +1 -1
- package/dist/error.d.mts +1 -1
- package/dist/{errors-BJRXUfMg.mjs → errors-BQgyQ9xe.mjs} +1 -1
- package/dist/{errors-BJRXUfMg.mjs.map → errors-BQgyQ9xe.mjs.map} +1 -1
- package/dist/{errors-NIXCyk6I.d.mts → errors-DQoYsDW1.d.mts} +2 -2
- package/dist/{errors-NIXCyk6I.d.mts.map → errors-DQoYsDW1.d.mts.map} +1 -1
- package/dist/event-ef-5Dbxg.mjs +53 -0
- package/dist/event-ef-5Dbxg.mjs.map +1 -0
- package/dist/express/index.d.mts +2 -2
- package/dist/express/index.d.mts.map +1 -1
- package/dist/express/index.mjs +17 -15
- package/dist/express/index.mjs.map +1 -1
- package/dist/fastify/index.d.mts +2 -2
- package/dist/fastify/index.d.mts.map +1 -1
- package/dist/fastify/index.mjs +19 -20
- package/dist/fastify/index.mjs.map +1 -1
- package/dist/fork-D44V93-K.mjs +227 -0
- package/dist/fork-D44V93-K.mjs.map +1 -0
- package/dist/{headers-D74M0wsg.mjs → headers-CU-QqnYg.mjs} +19 -2
- package/dist/headers-CU-QqnYg.mjs.map +1 -0
- package/dist/hono/index.d.mts +2 -2
- package/dist/hono/index.d.mts.map +1 -1
- package/dist/hono/index.mjs +14 -10
- package/dist/hono/index.mjs.map +1 -1
- package/dist/http.d.mts +1 -1
- package/dist/http.d.mts.map +1 -1
- package/dist/http.mjs +3 -2
- package/dist/http.mjs.map +1 -1
- package/dist/index.d.mts +8 -7
- package/dist/index.mjs +3 -2
- package/dist/integration-Bz8X6_Lb.mjs +75 -0
- package/dist/integration-Bz8X6_Lb.mjs.map +1 -0
- package/dist/{logger-b3epPH0N.d.mts → logger-Brt5-WMK.d.mts} +28 -3
- package/dist/logger-Brt5-WMK.d.mts.map +1 -0
- package/dist/logger.d.mts +2 -2
- package/dist/logger.mjs +2 -2
- package/dist/middleware-CGM-bOvE.d.mts +72 -0
- package/dist/middleware-CGM-bOvE.d.mts.map +1 -0
- package/dist/nestjs/index.d.mts +2 -2
- package/dist/nestjs/index.mjs +3 -4
- package/dist/nestjs/index.mjs.map +1 -1
- package/dist/next/client.d.mts +1 -1
- package/dist/next/index.d.mts +4 -4
- package/dist/next/index.mjs +3 -3
- package/dist/next/index.mjs.map +1 -1
- package/dist/next/instrumentation.d.mts +1 -1
- package/dist/next/instrumentation.mjs +1 -1
- package/dist/next/instrumentation.mjs.map +1 -1
- package/dist/nitro/errorHandler.mjs +2 -2
- package/dist/nitro/errorHandler.mjs.map +1 -1
- package/dist/nitro/module.d.mts +2 -2
- package/dist/nitro/plugin.mjs +21 -11
- package/dist/nitro/plugin.mjs.map +1 -1
- package/dist/nitro/v3/errorHandler.mjs +3 -3
- package/dist/nitro/v3/index.d.mts +2 -2
- package/dist/nitro/v3/middleware.mjs.map +1 -1
- package/dist/nitro/v3/module.d.mts +1 -1
- package/dist/nitro/v3/plugin.mjs +29 -17
- package/dist/nitro/v3/plugin.mjs.map +1 -1
- package/dist/nitro/v3/useLogger.d.mts +1 -1
- package/dist/nitro/v3/useLogger.mjs.map +1 -1
- package/dist/{nitro-DenB86W6.d.mts → nitro-DHPb9dXG.d.mts} +2 -2
- package/dist/{nitro-DenB86W6.d.mts.map → nitro-DHPb9dXG.d.mts.map} +1 -1
- package/dist/{nitro-OmT_M4Pb.mjs → nitro-DavLelNz.mjs} +2 -2
- package/dist/nitro-DavLelNz.mjs.map +1 -0
- package/dist/{nitroConfigBridge-C37lXaNm.mjs → nitroConfigBridge-aZ1e5upQ.mjs} +1 -1
- package/dist/nitroConfigBridge-aZ1e5upQ.mjs.map +1 -0
- package/dist/nuxt/module.d.mts +1 -1
- package/dist/nuxt/module.mjs +2 -2
- package/dist/{parseError-BR9pocvY.d.mts → parseError-B1zJZvQ5.d.mts} +2 -2
- package/dist/parseError-B1zJZvQ5.d.mts.map +1 -0
- package/dist/pipeline.mjs.map +1 -1
- package/dist/react-router/index.d.mts +2 -2
- package/dist/react-router/index.mjs +3 -4
- package/dist/react-router/index.mjs.map +1 -1
- package/dist/{routes-CGPmbzCZ.mjs → routes-B48wm7Pb.mjs} +1 -1
- package/dist/{routes-CGPmbzCZ.mjs.map → routes-B48wm7Pb.mjs.map} +1 -1
- package/dist/runtime/client/log.d.mts +1 -1
- package/dist/runtime/client/log.mjs +2 -2
- package/dist/runtime/client/log.mjs.map +1 -1
- package/dist/runtime/client/plugin.mjs.map +1 -1
- package/dist/runtime/server/routes/_evlog/ingest.post.mjs +21 -10
- package/dist/runtime/server/routes/_evlog/ingest.post.mjs.map +1 -1
- package/dist/runtime/server/useLogger.d.mts +1 -1
- package/dist/runtime/server/useLogger.mjs.map +1 -1
- package/dist/runtime/utils/parseError.d.mts +2 -2
- package/dist/runtime/utils/parseError.mjs +1 -1
- package/dist/{_severity-CQijvfhU.mjs → severity-BYWZ96Sb.mjs} +6 -2
- package/dist/severity-BYWZ96Sb.mjs.map +1 -0
- package/dist/{source-location-DRvDDqfq.mjs → source-location-Dco0cRTz.mjs} +3 -3
- package/dist/source-location-Dco0cRTz.mjs.map +1 -0
- package/dist/storage-BT-3fT1-.mjs +27 -0
- package/dist/storage-BT-3fT1-.mjs.map +1 -0
- package/dist/sveltekit/index.d.mts +2 -2
- package/dist/sveltekit/index.mjs +5 -6
- package/dist/sveltekit/index.mjs.map +1 -1
- package/dist/toolkit.d.mts +288 -12
- package/dist/toolkit.d.mts.map +1 -1
- package/dist/toolkit.mjs +13 -7
- package/dist/types.d.mts +1 -1
- package/dist/{useLogger-C56tDPwf.d.mts → useLogger-Cb1R6bQE.d.mts} +2 -2
- package/dist/{useLogger-C56tDPwf.d.mts.map → useLogger-Cb1R6bQE.d.mts.map} +1 -1
- package/dist/{utils-DzGCLRFe.d.mts → utils-gQCeZMbg.d.mts} +4 -3
- package/dist/utils-gQCeZMbg.d.mts.map +1 -0
- package/dist/utils.d.mts +2 -2
- package/dist/utils.mjs +7 -1
- package/dist/utils.mjs.map +1 -1
- package/dist/vite/index.d.mts +1 -1
- package/dist/vite/index.mjs +1 -1
- package/dist/vite/index.mjs.map +1 -1
- package/dist/workers.d.mts +48 -4
- package/dist/workers.d.mts.map +1 -1
- package/dist/workers.mjs +32 -5
- package/dist/workers.mjs.map +1 -1
- package/package.json +38 -39
- package/dist/_drain-CmCtsuF6.mjs +0 -23
- package/dist/_drain-CmCtsuF6.mjs.map +0 -1
- package/dist/_http-CHSsrWDJ.mjs +0 -71
- package/dist/_http-CHSsrWDJ.mjs.map +0 -1
- package/dist/_severity-CQijvfhU.mjs.map +0 -1
- package/dist/audit-d9esRZOK.mjs.map +0 -1
- package/dist/audit-mUutdf6A.d.mts.map +0 -1
- package/dist/dist-Do8P4zWd.mjs.map +0 -1
- package/dist/fork-CTJXnpl8.mjs +0 -72
- package/dist/fork-CTJXnpl8.mjs.map +0 -1
- package/dist/headers-D74M0wsg.mjs.map +0 -1
- package/dist/logger-b3epPH0N.d.mts.map +0 -1
- package/dist/middleware-BWOJ7JI0.mjs +0 -123
- package/dist/middleware-BWOJ7JI0.mjs.map +0 -1
- package/dist/middleware-BYf26Lfu.d.mts +0 -93
- package/dist/middleware-BYf26Lfu.d.mts.map +0 -1
- package/dist/nitro-OmT_M4Pb.mjs.map +0 -1
- package/dist/nitroConfigBridge-C37lXaNm.mjs.map +0 -1
- package/dist/parseError-BR9pocvY.d.mts.map +0 -1
- package/dist/source-location-DRvDDqfq.mjs.map +0 -1
- package/dist/storage-CFGTn37X.mjs +0 -46
- package/dist/storage-CFGTn37X.mjs.map +0 -1
- package/dist/utils-DzGCLRFe.d.mts.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 HugoRCD
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
[](https://evlog.dev)
|
|
12
12
|
[](https://github.com/HugoRCD/evlog/blob/main/LICENSE)
|
|
13
13
|
|
|
14
|
-
**
|
|
14
|
+
**Digging through logs is not observability. It's hope.**
|
|
15
15
|
|
|
16
|
-
A single request generates 10+ log lines. When production breaks at 3am, you're
|
|
16
|
+
A single request generates 10+ log lines. When production breaks at 3am, you're sifting scattered lines for a needle of signal. Your errors say "Something went wrong" — thanks, very helpful.
|
|
17
17
|
|
|
18
|
-
**evlog
|
|
18
|
+
**evlog is different.** One wide event per operation. All the context. Errors that explain *why* and what to do next.
|
|
19
19
|
|
|
20
20
|
## Why evlog?
|
|
21
21
|
|
|
@@ -336,30 +336,40 @@ async function processSyncJob(job: Job) {
|
|
|
336
336
|
|
|
337
337
|
## Cloudflare Workers
|
|
338
338
|
|
|
339
|
-
Use the Workers adapter for structured logs and correct platform severity.
|
|
339
|
+
Use the Workers adapter for structured logs and correct platform severity. With `initWorkersLogger({ drain })`, use **`defineWorkerFetch`** so async drains are registered with `waitUntil` automatically (Cloudflare only passes `ExecutionContext` as the third `fetch` argument — there is no global).
|
|
340
340
|
|
|
341
341
|
```typescript
|
|
342
342
|
// src/index.ts
|
|
343
|
-
import {
|
|
343
|
+
import { defineWorkerFetch, initWorkersLogger } from 'evlog/workers'
|
|
344
344
|
|
|
345
345
|
initWorkersLogger({
|
|
346
346
|
env: { service: 'edge-api' },
|
|
347
347
|
})
|
|
348
348
|
|
|
349
|
+
export default defineWorkerFetch(async (request, _env, _ctx, log) => {
|
|
350
|
+
try {
|
|
351
|
+
log.set({ route: 'health' })
|
|
352
|
+
const response = new Response('ok', { status: 200 })
|
|
353
|
+
log.emit({ status: response.status })
|
|
354
|
+
return response
|
|
355
|
+
} catch (error) {
|
|
356
|
+
log.error(error as Error)
|
|
357
|
+
log.emit({ status: 500 })
|
|
358
|
+
throw error
|
|
359
|
+
}
|
|
360
|
+
})
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
If you keep a raw `export default { fetch }`, pass `{ executionCtx: ctx }` to `createWorkersLogger` or `waitUntil` on `createRequestLogger`.
|
|
364
|
+
|
|
365
|
+
```typescript
|
|
366
|
+
// Lower-level (equivalent)
|
|
367
|
+
import { createWorkersLogger } from 'evlog/workers'
|
|
368
|
+
|
|
349
369
|
export default {
|
|
350
|
-
async fetch(request: Request) {
|
|
351
|
-
const log = createWorkersLogger(request)
|
|
352
|
-
|
|
353
|
-
try {
|
|
354
|
-
log.set({ route: 'health' })
|
|
355
|
-
const response = new Response('ok', { status: 200 })
|
|
356
|
-
log.emit({ status: response.status })
|
|
357
|
-
return response
|
|
358
|
-
} catch (error) {
|
|
359
|
-
log.error(error as Error)
|
|
360
|
-
log.emit({ status: 500 })
|
|
361
|
-
throw error
|
|
362
|
-
}
|
|
370
|
+
async fetch(request: Request, _env: unknown, ctx: ExecutionContext) {
|
|
371
|
+
const log = createWorkersLogger(request, { executionCtx: ctx })
|
|
372
|
+
// ...
|
|
363
373
|
},
|
|
364
374
|
}
|
|
365
375
|
```
|
|
@@ -373,6 +383,7 @@ invocation_logs = false
|
|
|
373
383
|
```
|
|
374
384
|
|
|
375
385
|
Notes:
|
|
386
|
+
- Prefer **`defineWorkerFetch`** so you do not have to pass `executionCtx` yourself when using a drain
|
|
376
387
|
- `requestId` defaults to `cf-ray` when available
|
|
377
388
|
- `request.cf` is included (colo, country, asn) unless disabled
|
|
378
389
|
- Use `headerAllowlist` to avoid logging sensitive headers
|
|
@@ -747,7 +758,7 @@ export default defineEventHandler(async (event) => {
|
|
|
747
758
|
|
|
748
759
|
`AuditFields` is exported and merges with `BaseWideEvent` — augment it with `declare module` if you need extra typed fields. Audit events are always force-kept by tail sampling and get a deterministic `idempotencyKey` so retries are safe across drains.
|
|
749
760
|
|
|
750
|
-
See [the Audit Logs guide](https://evlog.dev/logging/audit) for compliance, GDPR, and recipe details.
|
|
761
|
+
See [the Audit Logs guide](https://evlog.dev/logging/audit/overview) for compliance, GDPR, and recipe details.
|
|
751
762
|
|
|
752
763
|
## AI SDK Integration
|
|
753
764
|
|
|
@@ -1185,6 +1196,21 @@ initWorkersLogger({
|
|
|
1185
1196
|
})
|
|
1186
1197
|
```
|
|
1187
1198
|
|
|
1199
|
+
### `defineWorkerFetch(handler)`
|
|
1200
|
+
|
|
1201
|
+
Recommended for Workers when using **`initWorkersLogger({ drain })`**. Wraps your handler so `createWorkersLogger` always receives `executionCtx` — you do not pass `ctx` into the factory yourself. Cloudflare does not expose `ExecutionContext` globally (only as `fetch`’s third argument), so this is the “automatic” option for plain Workers scripts.
|
|
1202
|
+
|
|
1203
|
+
```typescript
|
|
1204
|
+
import { defineWorkerFetch, initWorkersLogger } from 'evlog/workers'
|
|
1205
|
+
|
|
1206
|
+
initWorkersLogger({ env: { service: 'edge-api' }, drain })
|
|
1207
|
+
|
|
1208
|
+
export default defineWorkerFetch(async (request, env, ctx, log) => {
|
|
1209
|
+
log.emit({ status: 200 })
|
|
1210
|
+
return new Response('ok')
|
|
1211
|
+
})
|
|
1212
|
+
```
|
|
1213
|
+
|
|
1188
1214
|
### `createWorkersLogger(request, options?)`
|
|
1189
1215
|
|
|
1190
1216
|
Create a request-scoped logger for Workers. Auto-extracts `cf-ray`, `request.cf`, method, and path.
|
|
@@ -1192,11 +1218,15 @@ Create a request-scoped logger for Workers. Auto-extracts `cf-ray`, `request.cf`
|
|
|
1192
1218
|
```typescript
|
|
1193
1219
|
import { createWorkersLogger } from 'evlog/workers'
|
|
1194
1220
|
|
|
1221
|
+
// ctx is the third argument to fetch(request, env, ctx)
|
|
1195
1222
|
const log = createWorkersLogger(request, {
|
|
1196
1223
|
requestId: 'custom-id', // Override cf-ray (default: cf-ray header)
|
|
1197
1224
|
headers: ['x-request-id'], // Headers to include (default: none)
|
|
1225
|
+
executionCtx: ctx, // With initWorkersLogger({ drain }), registers async drain via waitUntil
|
|
1198
1226
|
})
|
|
1199
1227
|
|
|
1228
|
+
// Or pass waitUntil directly: waitUntil: ctx.waitUntil.bind(ctx)
|
|
1229
|
+
|
|
1200
1230
|
log.set({ user: { id: '123' } })
|
|
1201
1231
|
log.emit({ status: 200 })
|
|
1202
1232
|
```
|
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
import { F as DrainContext, it as WideEvent } from "../audit-
|
|
1
|
+
import { F as DrainContext, it as WideEvent } from "../audit-CJl-wZ10.mjs";
|
|
2
2
|
//#region src/adapters/axiom.d.ts
|
|
3
3
|
interface BaseAxiomConfig {
|
|
4
|
-
/** Axiom dataset name */
|
|
4
|
+
/** Axiom dataset name. */
|
|
5
5
|
dataset: string;
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Axiom API key.
|
|
8
|
+
*
|
|
9
|
+
* @example `xaat-...`
|
|
10
|
+
*/
|
|
11
|
+
apiKey: string;
|
|
12
|
+
/**
|
|
13
|
+
* @deprecated Renamed to {@link BaseAxiomConfig.apiKey}. Will be removed in
|
|
14
|
+
* the next major version. Pass `apiKey` instead.
|
|
15
|
+
*/
|
|
16
|
+
token?: string;
|
|
17
|
+
/** Organization ID (required for Personal Access Tokens). */
|
|
9
18
|
orgId?: string;
|
|
10
19
|
/** Request timeout in milliseconds. Default: 5000 */
|
|
11
20
|
timeout?: number;
|
|
@@ -36,42 +45,24 @@ type AxiomConfig = BaseAxiomConfig & (EdgeAxiomConfig | EndpointAxiomConfig);
|
|
|
36
45
|
* 1. Overrides passed to createAxiomDrain()
|
|
37
46
|
* 2. runtimeConfig.evlog.axiom
|
|
38
47
|
* 3. runtimeConfig.axiom
|
|
39
|
-
* 4. Environment variables:
|
|
48
|
+
* 4. Environment variables: NUXT_AXIOM_API_KEY, AXIOM_API_KEY (or legacy `*_TOKEN`)
|
|
40
49
|
*
|
|
41
50
|
* @example
|
|
42
51
|
* ```ts
|
|
43
|
-
* // Zero config
|
|
44
|
-
*
|
|
52
|
+
* // Zero config — set NUXT_AXIOM_API_KEY and NUXT_AXIOM_DATASET
|
|
53
|
+
* initLogger({ drain: createAxiomDrain() })
|
|
45
54
|
*
|
|
46
55
|
* // With overrides
|
|
47
|
-
*
|
|
48
|
-
* dataset: 'my-dataset',
|
|
49
|
-
* }))
|
|
56
|
+
* initLogger({ drain: createAxiomDrain({ dataset: 'my-dataset' }) })
|
|
50
57
|
* ```
|
|
51
58
|
*/
|
|
52
59
|
declare function createAxiomDrain(overrides?: Partial<AxiomConfig>): (ctx: DrainContext | DrainContext[]) => Promise<void>;
|
|
53
60
|
/**
|
|
54
61
|
* Send a single event to Axiom.
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* ```ts
|
|
58
|
-
* await sendToAxiom(event, {
|
|
59
|
-
* dataset: 'my-logs',
|
|
60
|
-
* token: process.env.AXIOM_TOKEN!,
|
|
61
|
-
* })
|
|
62
|
-
* ```
|
|
63
62
|
*/
|
|
64
63
|
declare function sendToAxiom(event: WideEvent, config: AxiomConfig): Promise<void>;
|
|
65
64
|
/**
|
|
66
65
|
* Send a batch of events to Axiom.
|
|
67
|
-
*
|
|
68
|
-
* @example
|
|
69
|
-
* ```ts
|
|
70
|
-
* await sendBatchToAxiom(events, {
|
|
71
|
-
* dataset: 'my-logs',
|
|
72
|
-
* token: process.env.AXIOM_TOKEN!,
|
|
73
|
-
* })
|
|
74
|
-
* ```
|
|
75
66
|
*/
|
|
76
67
|
declare function sendBatchToAxiom(events: WideEvent[], config: AxiomConfig): Promise<void>;
|
|
77
68
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"axiom.d.mts","names":[],"sources":["../../src/adapters/axiom.ts"],"mappings":";;UAMU,eAAA;;EAER,OAAA;EAFQ;
|
|
1
|
+
{"version":3,"file":"axiom.d.mts","names":[],"sources":["../../src/adapters/axiom.ts"],"mappings":";;UAMU,eAAA;;EAER,OAAA;EAFQ;;;;;EAQR,MAAA;EAKA;;;;EAAA,KAAA;EAMO;EAJP,KAAA;EAOuB;EALvB,OAAA;EAWA;EATA,OAAA;AAAA;AAAA,UAGQ,eAAA;;;;AAkBV;;EAZE,OAAA;EAYwB;EAVxB,OAAA;AAAA;AAAA,UAGQ,mBAAA;EAOwE;EALhF,OAAA;EAK2C;EAH3C,OAAA;AAAA;AAAA,KAGU,WAAA,GAAc,eAAA,IAAmB,eAAA,GAAkB,mBAAA;AAkD/D;;;;;;;;;;;;;;;;;;AAAA,iBAAgB,gBAAA,CAAiB,SAAA,GAAY,OAAA,CAAQ,WAAA,KAAY,GAAA,EAAb,YAAA,GAAa,YAAA,OAAA,OAAA;AAmCjE;;;AAAA,iBAAsB,WAAA,CAAY,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,WAAA,GAAc,OAAA;;;;iBAOpD,gBAAA,CAAiB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,WAAA,GAAc,OAAA"}
|
package/dist/adapters/axiom.mjs
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as defineDrain } from "../_drain-CmCtsuF6.mjs";
|
|
1
|
+
import { a as resolveAdapterConfig, n as defineHttpDrain, r as httpPost } from "../drain-ByWUeOQC.mjs";
|
|
3
2
|
//#region src/adapters/axiom.ts
|
|
4
3
|
const AXIOM_FIELDS = [
|
|
5
4
|
{
|
|
6
5
|
key: "dataset",
|
|
7
6
|
env: ["NUXT_AXIOM_DATASET", "AXIOM_DATASET"]
|
|
8
7
|
},
|
|
8
|
+
{
|
|
9
|
+
key: "apiKey",
|
|
10
|
+
env: ["NUXT_AXIOM_API_KEY", "AXIOM_API_KEY"]
|
|
11
|
+
},
|
|
9
12
|
{
|
|
10
13
|
key: "token",
|
|
11
14
|
env: ["NUXT_AXIOM_TOKEN", "AXIOM_TOKEN"]
|
|
@@ -25,6 +28,17 @@ const AXIOM_FIELDS = [
|
|
|
25
28
|
{ key: "timeout" },
|
|
26
29
|
{ key: "retries" }
|
|
27
30
|
];
|
|
31
|
+
let warnedAboutToken = false;
|
|
32
|
+
function applyApiKeyAlias(config) {
|
|
33
|
+
if (!config.apiKey && config.token) {
|
|
34
|
+
if (!warnedAboutToken) {
|
|
35
|
+
warnedAboutToken = true;
|
|
36
|
+
console.warn("[evlog/axiom] `token` is deprecated, use `apiKey` instead. (Env: NUXT_AXIOM_TOKEN/AXIOM_TOKEN → NUXT_AXIOM_API_KEY/AXIOM_API_KEY.)");
|
|
37
|
+
}
|
|
38
|
+
config.apiKey = config.token;
|
|
39
|
+
}
|
|
40
|
+
return config;
|
|
41
|
+
}
|
|
28
42
|
/**
|
|
29
43
|
* Create a drain function for sending logs to Axiom.
|
|
30
44
|
*
|
|
@@ -32,26 +46,24 @@ const AXIOM_FIELDS = [
|
|
|
32
46
|
* 1. Overrides passed to createAxiomDrain()
|
|
33
47
|
* 2. runtimeConfig.evlog.axiom
|
|
34
48
|
* 3. runtimeConfig.axiom
|
|
35
|
-
* 4. Environment variables:
|
|
49
|
+
* 4. Environment variables: NUXT_AXIOM_API_KEY, AXIOM_API_KEY (or legacy `*_TOKEN`)
|
|
36
50
|
*
|
|
37
51
|
* @example
|
|
38
52
|
* ```ts
|
|
39
|
-
* // Zero config
|
|
40
|
-
*
|
|
53
|
+
* // Zero config — set NUXT_AXIOM_API_KEY and NUXT_AXIOM_DATASET
|
|
54
|
+
* initLogger({ drain: createAxiomDrain() })
|
|
41
55
|
*
|
|
42
56
|
* // With overrides
|
|
43
|
-
*
|
|
44
|
-
* dataset: 'my-dataset',
|
|
45
|
-
* }))
|
|
57
|
+
* initLogger({ drain: createAxiomDrain({ dataset: 'my-dataset' }) })
|
|
46
58
|
* ```
|
|
47
59
|
*/
|
|
48
60
|
function createAxiomDrain(overrides) {
|
|
49
|
-
return
|
|
61
|
+
return defineHttpDrain({
|
|
50
62
|
name: "axiom",
|
|
51
63
|
resolve: async () => {
|
|
52
|
-
const config = await resolveAdapterConfig("axiom", AXIOM_FIELDS, overrides);
|
|
53
|
-
if (!config.dataset || !config.
|
|
54
|
-
console.error("[evlog/axiom] Missing dataset or
|
|
64
|
+
const config = applyApiKeyAlias(await resolveAdapterConfig("axiom", AXIOM_FIELDS, overrides));
|
|
65
|
+
if (!config.dataset || !config.apiKey) {
|
|
66
|
+
console.error("[evlog/axiom] Missing dataset or apiKey. Set NUXT_AXIOM_API_KEY/NUXT_AXIOM_DATASET env vars or pass to createAxiomDrain()");
|
|
55
67
|
return null;
|
|
56
68
|
}
|
|
57
69
|
if (config.edgeUrl && config.baseUrl) {
|
|
@@ -60,39 +72,37 @@ function createAxiomDrain(overrides) {
|
|
|
60
72
|
}
|
|
61
73
|
return config;
|
|
62
74
|
},
|
|
63
|
-
|
|
75
|
+
encode: (events, config) => {
|
|
76
|
+
const url = resolveIngestUrl(config);
|
|
77
|
+
const headers = {
|
|
78
|
+
"Content-Type": "application/json",
|
|
79
|
+
"Authorization": `Bearer ${config.apiKey}`
|
|
80
|
+
};
|
|
81
|
+
if (config.orgId) headers["X-Axiom-Org-Id"] = config.orgId;
|
|
82
|
+
return {
|
|
83
|
+
url,
|
|
84
|
+
headers,
|
|
85
|
+
body: JSON.stringify(events)
|
|
86
|
+
};
|
|
87
|
+
}
|
|
64
88
|
});
|
|
65
89
|
}
|
|
66
90
|
/**
|
|
67
91
|
* Send a single event to Axiom.
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
* ```ts
|
|
71
|
-
* await sendToAxiom(event, {
|
|
72
|
-
* dataset: 'my-logs',
|
|
73
|
-
* token: process.env.AXIOM_TOKEN!,
|
|
74
|
-
* })
|
|
75
|
-
* ```
|
|
76
92
|
*/
|
|
77
93
|
async function sendToAxiom(event, config) {
|
|
78
94
|
await sendBatchToAxiom([event], config);
|
|
79
95
|
}
|
|
80
96
|
/**
|
|
81
97
|
* Send a batch of events to Axiom.
|
|
82
|
-
*
|
|
83
|
-
* @example
|
|
84
|
-
* ```ts
|
|
85
|
-
* await sendBatchToAxiom(events, {
|
|
86
|
-
* dataset: 'my-logs',
|
|
87
|
-
* token: process.env.AXIOM_TOKEN!,
|
|
88
|
-
* })
|
|
89
|
-
* ```
|
|
90
98
|
*/
|
|
91
99
|
async function sendBatchToAxiom(events, config) {
|
|
100
|
+
const apiKey = config.apiKey ?? config.token;
|
|
101
|
+
if (!apiKey) throw new Error("[evlog/axiom] Missing apiKey");
|
|
92
102
|
const url = resolveIngestUrl(config);
|
|
93
103
|
const headers = {
|
|
94
104
|
"Content-Type": "application/json",
|
|
95
|
-
"Authorization": `Bearer ${
|
|
105
|
+
"Authorization": `Bearer ${apiKey}`
|
|
96
106
|
};
|
|
97
107
|
if (config.orgId) headers["X-Axiom-Org-Id"] = config.orgId;
|
|
98
108
|
await httpPost({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"axiom.mjs","names":[],"sources":["../../src/adapters/axiom.ts"],"sourcesContent":["import type { WideEvent } from '../types'\nimport type { ConfigField } from '
|
|
1
|
+
{"version":3,"file":"axiom.mjs","names":[],"sources":["../../src/adapters/axiom.ts"],"sourcesContent":["import type { WideEvent } from '../types'\nimport type { ConfigField } from '../shared/config'\nimport { resolveAdapterConfig } from '../shared/config'\nimport { defineHttpDrain } from '../shared/drain'\nimport { httpPost } from '../shared/http'\n\ninterface BaseAxiomConfig {\n /** Axiom dataset name. */\n dataset: string\n /**\n * Axiom API key.\n *\n * @example `xaat-...`\n */\n apiKey: string\n /**\n * @deprecated Renamed to {@link BaseAxiomConfig.apiKey}. Will be removed in\n * the next major version. Pass `apiKey` instead.\n */\n token?: string\n /** Organization ID (required for Personal Access Tokens). */\n orgId?: string\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n /** Number of retry attempts on transient failures. Default: 2 */\n retries?: number\n}\n\ninterface EdgeAxiomConfig {\n /**\n * Edge URL for Axiom ingest/query endpoints.\n * If no path is provided, uses /v1/ingest/{dataset}.\n * If a custom path is provided, it is used as-is (trailing slash trimmed).\n */\n edgeUrl: string\n /** Mutually exclusive with edgeUrl. */\n baseUrl?: never\n}\n\ninterface EndpointAxiomConfig {\n /** Base URL for Axiom API. Uses /v1/datasets/{dataset}/ingest. */\n baseUrl?: string\n /** Mutually exclusive with baseUrl. */\n edgeUrl?: never\n}\n\nexport type AxiomConfig = BaseAxiomConfig & (EdgeAxiomConfig | EndpointAxiomConfig)\n\ntype ResolvedAxiomConfig = BaseAxiomConfig & {\n edgeUrl?: string\n baseUrl?: string\n}\n\nconst AXIOM_FIELDS: ConfigField<ResolvedAxiomConfig>[] = [\n { key: 'dataset', env: ['NUXT_AXIOM_DATASET', 'AXIOM_DATASET'] },\n { key: 'apiKey', env: ['NUXT_AXIOM_API_KEY', 'AXIOM_API_KEY'] },\n // Deprecated env var names — resolved as a fallback for `apiKey` below.\n { key: 'token', env: ['NUXT_AXIOM_TOKEN', 'AXIOM_TOKEN'] },\n { key: 'orgId', env: ['NUXT_AXIOM_ORG_ID', 'AXIOM_ORG_ID'] },\n { key: 'edgeUrl', env: ['NUXT_AXIOM_EDGE_URL', 'AXIOM_EDGE_URL'] },\n { key: 'baseUrl', env: ['NUXT_AXIOM_URL', 'AXIOM_URL'] },\n { key: 'timeout' },\n { key: 'retries' },\n]\n\nlet warnedAboutToken = false\n\nfunction applyApiKeyAlias(config: ResolvedAxiomConfig): ResolvedAxiomConfig {\n if (!config.apiKey && config.token) {\n if (!warnedAboutToken) {\n warnedAboutToken = true\n console.warn('[evlog/axiom] `token` is deprecated, use `apiKey` instead. (Env: NUXT_AXIOM_TOKEN/AXIOM_TOKEN → NUXT_AXIOM_API_KEY/AXIOM_API_KEY.)')\n }\n config.apiKey = config.token\n }\n return config\n}\n\n/**\n * Create a drain function for sending logs to Axiom.\n *\n * Configuration priority (highest to lowest):\n * 1. Overrides passed to createAxiomDrain()\n * 2. runtimeConfig.evlog.axiom\n * 3. runtimeConfig.axiom\n * 4. Environment variables: NUXT_AXIOM_API_KEY, AXIOM_API_KEY (or legacy `*_TOKEN`)\n *\n * @example\n * ```ts\n * // Zero config — set NUXT_AXIOM_API_KEY and NUXT_AXIOM_DATASET\n * initLogger({ drain: createAxiomDrain() })\n *\n * // With overrides\n * initLogger({ drain: createAxiomDrain({ dataset: 'my-dataset' }) })\n * ```\n */\nexport function createAxiomDrain(overrides?: Partial<AxiomConfig>) {\n return defineHttpDrain<AxiomConfig>({\n name: 'axiom',\n resolve: async () => {\n const resolved = await resolveAdapterConfig<ResolvedAxiomConfig>(\n 'axiom',\n AXIOM_FIELDS,\n overrides as Partial<ResolvedAxiomConfig>,\n )\n const config = applyApiKeyAlias(resolved)\n if (!config.dataset || !config.apiKey) {\n console.error('[evlog/axiom] Missing dataset or apiKey. Set NUXT_AXIOM_API_KEY/NUXT_AXIOM_DATASET env vars or pass to createAxiomDrain()')\n return null\n }\n if (config.edgeUrl && config.baseUrl) {\n console.warn('[evlog/axiom] Both edgeUrl and baseUrl are set. edgeUrl takes precedence for ingest.')\n delete config.baseUrl\n }\n return config as AxiomConfig\n },\n encode: (events, config) => {\n const url = resolveIngestUrl(config)\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.apiKey}`,\n }\n if (config.orgId) headers['X-Axiom-Org-Id'] = config.orgId\n return { url, headers, body: JSON.stringify(events) }\n },\n })\n}\n\n/**\n * Send a single event to Axiom.\n */\nexport async function sendToAxiom(event: WideEvent, config: AxiomConfig): Promise<void> {\n await sendBatchToAxiom([event], config)\n}\n\n/**\n * Send a batch of events to Axiom.\n */\nexport async function sendBatchToAxiom(events: WideEvent[], config: AxiomConfig): Promise<void> {\n const apiKey = config.apiKey ?? config.token\n if (!apiKey) {\n throw new Error('[evlog/axiom] Missing apiKey')\n }\n const url = resolveIngestUrl(config)\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n }\n if (config.orgId) headers['X-Axiom-Org-Id'] = config.orgId\n await httpPost({\n url,\n headers,\n body: JSON.stringify(events),\n timeout: config.timeout ?? 5000,\n retries: config.retries,\n label: 'Axiom',\n })\n}\n\nfunction resolveIngestUrl(config: AxiomConfig): string {\n const encodedDataset = encodeURIComponent(config.dataset)\n\n if (!config.edgeUrl) {\n const baseUrl = config.baseUrl ?? 'https://api.axiom.co'\n return `${baseUrl}/v1/datasets/${encodedDataset}/ingest`\n }\n\n try {\n const parsed = new URL(config.edgeUrl)\n if (parsed.pathname === '' || parsed.pathname === '/') {\n parsed.pathname = `/v1/ingest/${encodedDataset}`\n return parsed.toString()\n }\n parsed.pathname = parsed.pathname.replace(/\\/+$/, '')\n return parsed.toString()\n } catch {\n console.warn(`[evlog/axiom] edgeUrl \"${config.edgeUrl}\" is not a valid URL, falling back to string concatenation.`)\n const trimmed = config.edgeUrl.replace(/\\/+$/, '')\n return `${trimmed}/v1/ingest/${encodedDataset}`\n }\n}\n"],"mappings":";;AAqDA,MAAM,eAAmD;CACvD;EAAE,KAAK;EAAW,KAAK,CAAC,sBAAsB,gBAAgB;EAAE;CAChE;EAAE,KAAK;EAAU,KAAK,CAAC,sBAAsB,gBAAgB;EAAE;CAE/D;EAAE,KAAK;EAAS,KAAK,CAAC,oBAAoB,cAAc;EAAE;CAC1D;EAAE,KAAK;EAAS,KAAK,CAAC,qBAAqB,eAAe;EAAE;CAC5D;EAAE,KAAK;EAAW,KAAK,CAAC,uBAAuB,iBAAiB;EAAE;CAClE;EAAE,KAAK;EAAW,KAAK,CAAC,kBAAkB,YAAY;EAAE;CACxD,EAAE,KAAK,WAAW;CAClB,EAAE,KAAK,WAAW;CACnB;AAED,IAAI,mBAAmB;AAEvB,SAAS,iBAAiB,QAAkD;AAC1E,KAAI,CAAC,OAAO,UAAU,OAAO,OAAO;AAClC,MAAI,CAAC,kBAAkB;AACrB,sBAAmB;AACnB,WAAQ,KAAK,qIAAqI;;AAEpJ,SAAO,SAAS,OAAO;;AAEzB,QAAO;;;;;;;;;;;;;;;;;;;;AAqBT,SAAgB,iBAAiB,WAAkC;AACjE,QAAO,gBAA6B;EAClC,MAAM;EACN,SAAS,YAAY;GAMnB,MAAM,SAAS,iBAAiB,MALT,qBACrB,SACA,cACA,UACD,CACwC;AACzC,OAAI,CAAC,OAAO,WAAW,CAAC,OAAO,QAAQ;AACrC,YAAQ,MAAM,4HAA4H;AAC1I,WAAO;;AAET,OAAI,OAAO,WAAW,OAAO,SAAS;AACpC,YAAQ,KAAK,uFAAuF;AACpG,WAAO,OAAO;;AAEhB,UAAO;;EAET,SAAS,QAAQ,WAAW;GAC1B,MAAM,MAAM,iBAAiB,OAAO;GACpC,MAAM,UAAkC;IACtC,gBAAgB;IAChB,iBAAiB,UAAU,OAAO;IACnC;AACD,OAAI,OAAO,MAAO,SAAQ,oBAAoB,OAAO;AACrD,UAAO;IAAE;IAAK;IAAS,MAAM,KAAK,UAAU,OAAO;IAAE;;EAExD,CAAC;;;;;AAMJ,eAAsB,YAAY,OAAkB,QAAoC;AACtF,OAAM,iBAAiB,CAAC,MAAM,EAAE,OAAO;;;;;AAMzC,eAAsB,iBAAiB,QAAqB,QAAoC;CAC9F,MAAM,SAAS,OAAO,UAAU,OAAO;AACvC,KAAI,CAAC,OACH,OAAM,IAAI,MAAM,+BAA+B;CAEjD,MAAM,MAAM,iBAAiB,OAAO;CACpC,MAAM,UAAkC;EACtC,gBAAgB;EAChB,iBAAiB,UAAU;EAC5B;AACD,KAAI,OAAO,MAAO,SAAQ,oBAAoB,OAAO;AACrD,OAAM,SAAS;EACb;EACA;EACA,MAAM,KAAK,UAAU,OAAO;EAC5B,SAAS,OAAO,WAAW;EAC3B,SAAS,OAAO;EAChB,OAAO;EACR,CAAC;;AAGJ,SAAS,iBAAiB,QAA6B;CACrD,MAAM,iBAAiB,mBAAmB,OAAO,QAAQ;AAEzD,KAAI,CAAC,OAAO,QAEV,QAAO,GADS,OAAO,WAAW,uBAChB,eAAe,eAAe;AAGlD,KAAI;EACF,MAAM,SAAS,IAAI,IAAI,OAAO,QAAQ;AACtC,MAAI,OAAO,aAAa,MAAM,OAAO,aAAa,KAAK;AACrD,UAAO,WAAW,cAAc;AAChC,UAAO,OAAO,UAAU;;AAE1B,SAAO,WAAW,OAAO,SAAS,QAAQ,QAAQ,GAAG;AACrD,SAAO,OAAO,UAAU;SAClB;AACN,UAAQ,KAAK,0BAA0B,OAAO,QAAQ,6DAA6D;AAEnH,SAAO,GADS,OAAO,QAAQ,QAAQ,QAAQ,GAC9B,CAAC,aAAa"}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import { F as DrainContext, it as WideEvent } from "../audit-
|
|
1
|
+
import { F as DrainContext, it as WideEvent } from "../audit-CJl-wZ10.mjs";
|
|
2
2
|
//#region src/adapters/better-stack.d.ts
|
|
3
3
|
interface BetterStackConfig {
|
|
4
|
-
/** Better Stack
|
|
5
|
-
|
|
4
|
+
/** Better Stack API key (replaces deprecated `sourceToken`). */
|
|
5
|
+
apiKey: string;
|
|
6
|
+
/**
|
|
7
|
+
* @deprecated Renamed to {@link BetterStackConfig.apiKey}. Will be removed
|
|
8
|
+
* in the next major version. Pass `apiKey` instead.
|
|
9
|
+
*/
|
|
10
|
+
sourceToken?: string;
|
|
6
11
|
/** Logtail ingestion endpoint. Default: https://in.logs.betterstack.com */
|
|
7
12
|
endpoint?: string;
|
|
8
13
|
/** Request timeout in milliseconds. Default: 5000 */
|
|
@@ -22,40 +27,22 @@ declare function toBetterStackEvent(event: WideEvent): Record<string, unknown>;
|
|
|
22
27
|
* 1. Overrides passed to createBetterStackDrain()
|
|
23
28
|
* 2. runtimeConfig.evlog.betterStack
|
|
24
29
|
* 3. runtimeConfig.betterStack
|
|
25
|
-
* 4. Environment variables:
|
|
30
|
+
* 4. Environment variables: NUXT_BETTER_STACK_API_KEY, BETTER_STACK_API_KEY (or legacy `*_SOURCE_TOKEN`)
|
|
26
31
|
*
|
|
27
32
|
* @example
|
|
28
33
|
* ```ts
|
|
29
|
-
*
|
|
30
|
-
* nitroApp.hooks.hook('evlog:drain', createBetterStackDrain())
|
|
34
|
+
* initLogger({ drain: createBetterStackDrain() })
|
|
31
35
|
*
|
|
32
|
-
*
|
|
33
|
-
* nitroApp.hooks.hook('evlog:drain', createBetterStackDrain({
|
|
34
|
-
* sourceToken: 'my-token',
|
|
35
|
-
* }))
|
|
36
|
+
* initLogger({ drain: createBetterStackDrain({ apiKey: 'my-key' }) })
|
|
36
37
|
* ```
|
|
37
38
|
*/
|
|
38
39
|
declare function createBetterStackDrain(overrides?: Partial<BetterStackConfig>): (ctx: DrainContext | DrainContext[]) => Promise<void>;
|
|
39
40
|
/**
|
|
40
41
|
* Send a single event to Better Stack.
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* ```ts
|
|
44
|
-
* await sendToBetterStack(event, {
|
|
45
|
-
* sourceToken: process.env.BETTER_STACK_SOURCE_TOKEN!,
|
|
46
|
-
* })
|
|
47
|
-
* ```
|
|
48
42
|
*/
|
|
49
43
|
declare function sendToBetterStack(event: WideEvent, config: BetterStackConfig): Promise<void>;
|
|
50
44
|
/**
|
|
51
45
|
* Send a batch of events to Better Stack.
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* ```ts
|
|
55
|
-
* await sendBatchToBetterStack(events, {
|
|
56
|
-
* sourceToken: process.env.BETTER_STACK_SOURCE_TOKEN!,
|
|
57
|
-
* })
|
|
58
|
-
* ```
|
|
59
46
|
*/
|
|
60
47
|
declare function sendBatchToBetterStack(events: WideEvent[], config: BetterStackConfig): Promise<void>;
|
|
61
48
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"better-stack.d.mts","names":[],"sources":["../../src/adapters/better-stack.ts"],"mappings":";;UAMiB,iBAAA;;EAEf,
|
|
1
|
+
{"version":3,"file":"better-stack.d.mts","names":[],"sources":["../../src/adapters/better-stack.ts"],"mappings":";;UAMiB,iBAAA;;EAEf,MAAA;EAFe;;;;EAOf,WAAA;EAAA;EAEA,QAAA;EAEA;EAAA,OAAA;EAEO;EAAP,OAAA;AAAA;;;;;iBA6Bc,kBAAA,CAAmB,KAAA,EAAO,SAAA,GAAY,MAAA;;;;AAqBtD;;;;;;;;;;;;;iBAAgB,sBAAA,CAAuB,SAAA,GAAY,OAAA,CAAQ,iBAAA,KAAkB,GAAA,EAAnB,YAAA,GAAmB,YAAA,OAAA,OAAA;;;;iBA0BvD,iBAAA,CAAkB,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,iBAAA,GAAoB,OAAA;;AAAtF;;iBAOsB,sBAAA,CAAuB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,iBAAA,GAAoB,OAAA"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as defineDrain } from "../_drain-CmCtsuF6.mjs";
|
|
1
|
+
import { a as resolveAdapterConfig, n as defineHttpDrain, r as httpPost } from "../drain-ByWUeOQC.mjs";
|
|
3
2
|
//#region src/adapters/better-stack.ts
|
|
4
3
|
const BETTER_STACK_FIELDS = [
|
|
4
|
+
{
|
|
5
|
+
key: "apiKey",
|
|
6
|
+
env: ["NUXT_BETTER_STACK_API_KEY", "BETTER_STACK_API_KEY"]
|
|
7
|
+
},
|
|
5
8
|
{
|
|
6
9
|
key: "sourceToken",
|
|
7
10
|
env: ["NUXT_BETTER_STACK_SOURCE_TOKEN", "BETTER_STACK_SOURCE_TOKEN"]
|
|
@@ -13,6 +16,17 @@ const BETTER_STACK_FIELDS = [
|
|
|
13
16
|
{ key: "timeout" },
|
|
14
17
|
{ key: "retries" }
|
|
15
18
|
];
|
|
19
|
+
let warnedAboutSourceToken = false;
|
|
20
|
+
function applyApiKeyAlias(config) {
|
|
21
|
+
if (!config.apiKey && config.sourceToken) {
|
|
22
|
+
if (!warnedAboutSourceToken) {
|
|
23
|
+
warnedAboutSourceToken = true;
|
|
24
|
+
console.warn("[evlog/better-stack] `sourceToken` is deprecated, use `apiKey` instead. (Env: NUXT_BETTER_STACK_SOURCE_TOKEN → NUXT_BETTER_STACK_API_KEY.)");
|
|
25
|
+
}
|
|
26
|
+
config.apiKey = config.sourceToken;
|
|
27
|
+
}
|
|
28
|
+
return config;
|
|
29
|
+
}
|
|
16
30
|
/**
|
|
17
31
|
* Transform an evlog wide event into a Better Stack event.
|
|
18
32
|
* Maps `timestamp` to `dt` (Better Stack's expected field).
|
|
@@ -31,62 +45,53 @@ function toBetterStackEvent(event) {
|
|
|
31
45
|
* 1. Overrides passed to createBetterStackDrain()
|
|
32
46
|
* 2. runtimeConfig.evlog.betterStack
|
|
33
47
|
* 3. runtimeConfig.betterStack
|
|
34
|
-
* 4. Environment variables:
|
|
48
|
+
* 4. Environment variables: NUXT_BETTER_STACK_API_KEY, BETTER_STACK_API_KEY (or legacy `*_SOURCE_TOKEN`)
|
|
35
49
|
*
|
|
36
50
|
* @example
|
|
37
51
|
* ```ts
|
|
38
|
-
*
|
|
39
|
-
* nitroApp.hooks.hook('evlog:drain', createBetterStackDrain())
|
|
52
|
+
* initLogger({ drain: createBetterStackDrain() })
|
|
40
53
|
*
|
|
41
|
-
*
|
|
42
|
-
* nitroApp.hooks.hook('evlog:drain', createBetterStackDrain({
|
|
43
|
-
* sourceToken: 'my-token',
|
|
44
|
-
* }))
|
|
54
|
+
* initLogger({ drain: createBetterStackDrain({ apiKey: 'my-key' }) })
|
|
45
55
|
* ```
|
|
46
56
|
*/
|
|
47
57
|
function createBetterStackDrain(overrides) {
|
|
48
|
-
return
|
|
58
|
+
return defineHttpDrain({
|
|
49
59
|
name: "better-stack",
|
|
50
60
|
resolve: async () => {
|
|
51
|
-
const config = await resolveAdapterConfig("betterStack", BETTER_STACK_FIELDS, overrides);
|
|
52
|
-
if (!config.
|
|
53
|
-
console.error("[evlog/better-stack] Missing
|
|
61
|
+
const config = applyApiKeyAlias(await resolveAdapterConfig("betterStack", BETTER_STACK_FIELDS, overrides));
|
|
62
|
+
if (!config.apiKey) {
|
|
63
|
+
console.error("[evlog/better-stack] Missing apiKey. Set NUXT_BETTER_STACK_API_KEY env var or pass to createBetterStackDrain()");
|
|
54
64
|
return null;
|
|
55
65
|
}
|
|
56
66
|
return config;
|
|
57
67
|
},
|
|
58
|
-
|
|
68
|
+
encode: (events, config) => ({
|
|
69
|
+
url: (config.endpoint ?? "https://in.logs.betterstack.com").replace(/\/+$/, ""),
|
|
70
|
+
headers: {
|
|
71
|
+
"Content-Type": "application/json",
|
|
72
|
+
"Authorization": `Bearer ${config.apiKey}`
|
|
73
|
+
},
|
|
74
|
+
body: JSON.stringify(events.map(toBetterStackEvent))
|
|
75
|
+
})
|
|
59
76
|
});
|
|
60
77
|
}
|
|
61
78
|
/**
|
|
62
79
|
* Send a single event to Better Stack.
|
|
63
|
-
*
|
|
64
|
-
* @example
|
|
65
|
-
* ```ts
|
|
66
|
-
* await sendToBetterStack(event, {
|
|
67
|
-
* sourceToken: process.env.BETTER_STACK_SOURCE_TOKEN!,
|
|
68
|
-
* })
|
|
69
|
-
* ```
|
|
70
80
|
*/
|
|
71
81
|
async function sendToBetterStack(event, config) {
|
|
72
82
|
await sendBatchToBetterStack([event], config);
|
|
73
83
|
}
|
|
74
84
|
/**
|
|
75
85
|
* Send a batch of events to Better Stack.
|
|
76
|
-
*
|
|
77
|
-
* @example
|
|
78
|
-
* ```ts
|
|
79
|
-
* await sendBatchToBetterStack(events, {
|
|
80
|
-
* sourceToken: process.env.BETTER_STACK_SOURCE_TOKEN!,
|
|
81
|
-
* })
|
|
82
|
-
* ```
|
|
83
86
|
*/
|
|
84
87
|
async function sendBatchToBetterStack(events, config) {
|
|
88
|
+
const apiKey = config.apiKey ?? config.sourceToken;
|
|
89
|
+
if (!apiKey) throw new Error("[evlog/better-stack] Missing apiKey");
|
|
85
90
|
await httpPost({
|
|
86
91
|
url: (config.endpoint ?? "https://in.logs.betterstack.com").replace(/\/+$/, ""),
|
|
87
92
|
headers: {
|
|
88
93
|
"Content-Type": "application/json",
|
|
89
|
-
"Authorization": `Bearer ${
|
|
94
|
+
"Authorization": `Bearer ${apiKey}`
|
|
90
95
|
},
|
|
91
96
|
body: JSON.stringify(events.map(toBetterStackEvent)),
|
|
92
97
|
timeout: config.timeout ?? 5e3,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"better-stack.mjs","names":[],"sources":["../../src/adapters/better-stack.ts"],"sourcesContent":["import type { WideEvent } from '../types'\nimport type { ConfigField } from '
|
|
1
|
+
{"version":3,"file":"better-stack.mjs","names":[],"sources":["../../src/adapters/better-stack.ts"],"sourcesContent":["import type { WideEvent } from '../types'\nimport type { ConfigField } from '../shared/config'\nimport { resolveAdapterConfig } from '../shared/config'\nimport { defineHttpDrain } from '../shared/drain'\nimport { httpPost } from '../shared/http'\n\nexport interface BetterStackConfig {\n /** Better Stack API key (replaces deprecated `sourceToken`). */\n apiKey: string\n /**\n * @deprecated Renamed to {@link BetterStackConfig.apiKey}. Will be removed\n * in the next major version. Pass `apiKey` instead.\n */\n sourceToken?: string\n /** Logtail ingestion endpoint. Default: https://in.logs.betterstack.com */\n endpoint?: string\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n /** Number of retry attempts on transient failures. Default: 2 */\n retries?: number\n}\n\nconst BETTER_STACK_FIELDS: ConfigField<BetterStackConfig>[] = [\n { key: 'apiKey', env: ['NUXT_BETTER_STACK_API_KEY', 'BETTER_STACK_API_KEY'] },\n // Deprecated env var names — resolved as a fallback for `apiKey` below.\n { key: 'sourceToken', env: ['NUXT_BETTER_STACK_SOURCE_TOKEN', 'BETTER_STACK_SOURCE_TOKEN'] },\n { key: 'endpoint', env: ['NUXT_BETTER_STACK_ENDPOINT', 'BETTER_STACK_ENDPOINT'] },\n { key: 'timeout' },\n { key: 'retries' },\n]\n\nlet warnedAboutSourceToken = false\n\nfunction applyApiKeyAlias(config: BetterStackConfig): BetterStackConfig {\n if (!config.apiKey && config.sourceToken) {\n if (!warnedAboutSourceToken) {\n warnedAboutSourceToken = true\n console.warn('[evlog/better-stack] `sourceToken` is deprecated, use `apiKey` instead. (Env: NUXT_BETTER_STACK_SOURCE_TOKEN → NUXT_BETTER_STACK_API_KEY.)')\n }\n config.apiKey = config.sourceToken\n }\n return config\n}\n\n/**\n * Transform an evlog wide event into a Better Stack event.\n * Maps `timestamp` to `dt` (Better Stack's expected field).\n */\nexport function toBetterStackEvent(event: WideEvent): Record<string, unknown> {\n const { timestamp, ...rest } = event\n return { ...rest, dt: timestamp }\n}\n\n/**\n * Create a drain function for sending logs to Better Stack.\n *\n * Configuration priority (highest to lowest):\n * 1. Overrides passed to createBetterStackDrain()\n * 2. runtimeConfig.evlog.betterStack\n * 3. runtimeConfig.betterStack\n * 4. Environment variables: NUXT_BETTER_STACK_API_KEY, BETTER_STACK_API_KEY (or legacy `*_SOURCE_TOKEN`)\n *\n * @example\n * ```ts\n * initLogger({ drain: createBetterStackDrain() })\n *\n * initLogger({ drain: createBetterStackDrain({ apiKey: 'my-key' }) })\n * ```\n */\nexport function createBetterStackDrain(overrides?: Partial<BetterStackConfig>) {\n return defineHttpDrain<BetterStackConfig>({\n name: 'better-stack',\n resolve: async () => {\n const resolved = await resolveAdapterConfig<BetterStackConfig>('betterStack', BETTER_STACK_FIELDS, overrides)\n const config = applyApiKeyAlias(resolved as BetterStackConfig)\n if (!config.apiKey) {\n console.error('[evlog/better-stack] Missing apiKey. Set NUXT_BETTER_STACK_API_KEY env var or pass to createBetterStackDrain()')\n return null\n }\n return config\n },\n encode: (events, config) => ({\n url: (config.endpoint ?? 'https://in.logs.betterstack.com').replace(/\\/+$/, ''),\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.apiKey}`,\n },\n body: JSON.stringify(events.map(toBetterStackEvent)),\n }),\n })\n}\n\n/**\n * Send a single event to Better Stack.\n */\nexport async function sendToBetterStack(event: WideEvent, config: BetterStackConfig): Promise<void> {\n await sendBatchToBetterStack([event], config)\n}\n\n/**\n * Send a batch of events to Better Stack.\n */\nexport async function sendBatchToBetterStack(events: WideEvent[], config: BetterStackConfig): Promise<void> {\n const apiKey = config.apiKey ?? config.sourceToken\n if (!apiKey) throw new Error('[evlog/better-stack] Missing apiKey')\n const endpoint = (config.endpoint ?? 'https://in.logs.betterstack.com').replace(/\\/+$/, '')\n\n await httpPost({\n url: endpoint,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n },\n body: JSON.stringify(events.map(toBetterStackEvent)),\n timeout: config.timeout ?? 5000,\n retries: config.retries,\n label: 'Better Stack',\n })\n}\n"],"mappings":";;AAsBA,MAAM,sBAAwD;CAC5D;EAAE,KAAK;EAAU,KAAK,CAAC,6BAA6B,uBAAuB;EAAE;CAE7E;EAAE,KAAK;EAAe,KAAK,CAAC,kCAAkC,4BAA4B;EAAE;CAC5F;EAAE,KAAK;EAAY,KAAK,CAAC,8BAA8B,wBAAwB;EAAE;CACjF,EAAE,KAAK,WAAW;CAClB,EAAE,KAAK,WAAW;CACnB;AAED,IAAI,yBAAyB;AAE7B,SAAS,iBAAiB,QAA8C;AACtE,KAAI,CAAC,OAAO,UAAU,OAAO,aAAa;AACxC,MAAI,CAAC,wBAAwB;AAC3B,4BAAyB;AACzB,WAAQ,KAAK,6IAA6I;;AAE5J,SAAO,SAAS,OAAO;;AAEzB,QAAO;;;;;;AAOT,SAAgB,mBAAmB,OAA2C;CAC5E,MAAM,EAAE,WAAW,GAAG,SAAS;AAC/B,QAAO;EAAE,GAAG;EAAM,IAAI;EAAW;;;;;;;;;;;;;;;;;;AAmBnC,SAAgB,uBAAuB,WAAwC;AAC7E,QAAO,gBAAmC;EACxC,MAAM;EACN,SAAS,YAAY;GAEnB,MAAM,SAAS,iBAAiB,MADT,qBAAwC,eAAe,qBAAqB,UAAU,CAC/C;AAC9D,OAAI,CAAC,OAAO,QAAQ;AAClB,YAAQ,MAAM,iHAAiH;AAC/H,WAAO;;AAET,UAAO;;EAET,SAAS,QAAQ,YAAY;GAC3B,MAAM,OAAO,YAAY,mCAAmC,QAAQ,QAAQ,GAAG;GAC/E,SAAS;IACP,gBAAgB;IAChB,iBAAiB,UAAU,OAAO;IACnC;GACD,MAAM,KAAK,UAAU,OAAO,IAAI,mBAAmB,CAAC;GACrD;EACF,CAAC;;;;;AAMJ,eAAsB,kBAAkB,OAAkB,QAA0C;AAClG,OAAM,uBAAuB,CAAC,MAAM,EAAE,OAAO;;;;;AAM/C,eAAsB,uBAAuB,QAAqB,QAA0C;CAC1G,MAAM,SAAS,OAAO,UAAU,OAAO;AACvC,KAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,sCAAsC;AAGnE,OAAM,SAAS;EACb,MAHgB,OAAO,YAAY,mCAAmC,QAAQ,QAAQ,GAGzE;EACb,SAAS;GACP,gBAAgB;GAChB,iBAAiB,UAAU;GAC5B;EACD,MAAM,KAAK,UAAU,OAAO,IAAI,mBAAmB,CAAC;EACpD,SAAS,OAAO,WAAW;EAC3B,SAAS,OAAO;EAChB,OAAO;EACR,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as DrainContext, it as WideEvent } from "../audit-
|
|
1
|
+
import { F as DrainContext, it as WideEvent } from "../audit-CJl-wZ10.mjs";
|
|
2
2
|
//#region src/adapters/datadog.d.ts
|
|
3
3
|
interface DatadogConfig {
|
|
4
4
|
/** Datadog API key with Logs intake permission */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datadog.d.mts","names":[],"sources":["../../src/adapters/datadog.ts"],"mappings":";;UAMiB,aAAA;;EAEf,MAAA;EAFe;;;;EAOf,IAAA;EAAA;;;;EAKA,SAAA;EAIO;EAFP,OAAA;EAsByC;EApBzC,OAAA;AAAA;;;;;;AA2CF;;iBAvBgB,2BAAA,CAA4B,KAAA,EAAO,SAAA,GAAY,MAAA;;;AAgD/D;;iBAzBgB,wBAAA,CAAyB,KAAA,EAAO,SAAA;;;AA2ChD;;;;;;iBAlBgB,uBAAA,CAAwB,KAAA,EAAO,SAAA;;;AAwC/C;;;;;;iBAtBgB,YAAA,CAAa,KAAA,EAAO,SAAA,GAAY,MAAA;;;AAiDhD;iBA3BgB,uBAAA,CAAwB,MAAA,EAAQ,IAAA,CAAK,aAAA;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"datadog.d.mts","names":[],"sources":["../../src/adapters/datadog.ts"],"mappings":";;UAMiB,aAAA;;EAEf,MAAA;EAFe;;;;EAOf,IAAA;EAAA;;;;EAKA,SAAA;EAIO;EAFP,OAAA;EAsByC;EApBzC,OAAA;AAAA;;;;;;AA2CF;;iBAvBgB,2BAAA,CAA4B,KAAA,EAAO,SAAA,GAAY,MAAA;;;AAgD/D;;iBAzBgB,wBAAA,CAAyB,KAAA,EAAO,SAAA;;;AA2ChD;;;;;;iBAlBgB,uBAAA,CAAwB,KAAA,EAAO,SAAA;;;AAwC/C;;;;;;iBAtBgB,YAAA,CAAa,KAAA,EAAO,SAAA,GAAY,MAAA;;;AAiDhD;iBA3BgB,uBAAA,CAAwB,MAAA,EAAQ,IAAA,CAAK,aAAA;;;;;;;;;;;;;;;;;;AAoDrD;;iBAzBgB,kBAAA,CAAmB,SAAA,GAAY,OAAA,CAAQ,aAAA,KAAc,GAAA,EAAf,YAAA,GAAe,YAAA,OAAA,OAAA;;;;iBAyB/C,aAAA,CAAc,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,aAAA,GAAgB,OAAA;;;;iBAOxD,kBAAA,CAAmB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,aAAA,GAAgB,OAAA"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as defineDrain } from "../_drain-CmCtsuF6.mjs";
|
|
1
|
+
import { a as resolveAdapterConfig, n as defineHttpDrain, r as httpPost } from "../drain-ByWUeOQC.mjs";
|
|
3
2
|
//#region src/adapters/datadog.ts
|
|
4
3
|
const DATADOG_FIELDS = [
|
|
5
4
|
{
|
|
@@ -130,7 +129,7 @@ function resolveDatadogIntakeUrl(config) {
|
|
|
130
129
|
* ```
|
|
131
130
|
*/
|
|
132
131
|
function createDatadogDrain(overrides) {
|
|
133
|
-
return
|
|
132
|
+
return defineHttpDrain({
|
|
134
133
|
name: "datadog",
|
|
135
134
|
resolve: async () => {
|
|
136
135
|
const config = await resolveAdapterConfig("datadog", DATADOG_FIELDS, overrides);
|
|
@@ -140,7 +139,14 @@ function createDatadogDrain(overrides) {
|
|
|
140
139
|
}
|
|
141
140
|
return config;
|
|
142
141
|
},
|
|
143
|
-
|
|
142
|
+
encode: (events, config) => ({
|
|
143
|
+
url: resolveDatadogIntakeUrl(config),
|
|
144
|
+
headers: {
|
|
145
|
+
"Content-Type": "application/json",
|
|
146
|
+
"DD-API-KEY": config.apiKey
|
|
147
|
+
},
|
|
148
|
+
body: JSON.stringify(events.map(toDatadogLog))
|
|
149
|
+
})
|
|
144
150
|
});
|
|
145
151
|
}
|
|
146
152
|
/**
|