evlog 2.17.0 → 2.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -2
- package/dist/adapters/axiom.d.mts +1 -1
- package/dist/adapters/axiom.mjs +2 -2
- package/dist/adapters/axiom.mjs.map +1 -1
- package/dist/adapters/better-stack.d.mts +1 -1
- package/dist/adapters/better-stack.mjs +2 -2
- package/dist/adapters/datadog.d.mts +1 -1
- package/dist/adapters/datadog.mjs +2 -2
- package/dist/adapters/fs.d.mts +1 -1
- package/dist/adapters/fs.mjs +2 -2
- package/dist/adapters/hyperdx.d.mts +1 -1
- package/dist/adapters/hyperdx.mjs +1 -1
- package/dist/adapters/memory.d.mts +116 -0
- package/dist/adapters/memory.d.mts.map +1 -0
- package/dist/adapters/memory.mjs +191 -0
- package/dist/adapters/memory.mjs.map +1 -0
- package/dist/adapters/otlp.d.mts +1 -1
- package/dist/adapters/otlp.mjs +4 -4
- package/dist/adapters/posthog.d.mts +1 -1
- package/dist/adapters/posthog.mjs +2 -2
- package/dist/adapters/sentry.d.mts +1 -1
- package/dist/adapters/sentry.mjs +3 -3
- package/dist/ai/index.d.mts +1 -1
- package/dist/{audit-pV5aLGP0.mjs → audit-BFwTUxBJ.mjs} +475 -151
- package/dist/audit-BFwTUxBJ.mjs.map +1 -0
- package/dist/{audit-CC8nfazi.d.mts → audit-BUAajsPU.d.mts} +126 -35
- package/dist/audit-BUAajsPU.d.mts.map +1 -0
- package/dist/better-auth/index.d.mts +1 -1
- package/dist/browser.d.mts +1 -1
- package/dist/{define-D6OJdSUH.mjs → define-Bpaymi-h.mjs} +2 -1
- package/dist/define-Bpaymi-h.mjs.map +1 -0
- package/dist/{define-MSdhzmXn.d.mts → define-DGwZkZ7x.d.mts} +8 -3
- package/dist/define-DGwZkZ7x.d.mts.map +1 -0
- package/dist/dev-terminal-D4UaEm17.mjs +54 -0
- package/dist/dev-terminal-D4UaEm17.mjs.map +1 -0
- package/dist/{dist-H3GIh-KK.mjs → dist-DdQWiZn8.mjs} +1 -1
- package/dist/{dist-H3GIh-KK.mjs.map → dist-DdQWiZn8.mjs.map} +1 -1
- package/dist/{drain-X7_5szSI.mjs → drain-D_fy7m0n.mjs} +3 -3
- package/dist/drain-D_fy7m0n.mjs.map +1 -0
- package/dist/elysia/index.d.mts +3 -3
- package/dist/elysia/index.d.mts.map +1 -1
- package/dist/elysia/index.mjs +8 -5
- package/dist/elysia/index.mjs.map +1 -1
- package/dist/enrich-drain-CG_2Nix-.mjs +122 -0
- package/dist/enrich-drain-CG_2Nix-.mjs.map +1 -0
- package/dist/{enricher-DxgML6IC.d.mts → enricher-CuMbbdqp.d.mts} +2 -2
- package/dist/{enricher-DxgML6IC.d.mts.map → enricher-CuMbbdqp.d.mts.map} +1 -1
- package/dist/{enricher-N0erZS87.mjs → enricher-DAWf2-Fx.mjs} +2 -2
- package/dist/{enricher-N0erZS87.mjs.map → enricher-DAWf2-Fx.mjs.map} +1 -1
- package/dist/enrichers.d.mts +2 -2
- package/dist/enrichers.mjs +2 -2
- package/dist/{error-CpbbtyXL.d.mts → error-DwajXSKM.d.mts} +2 -2
- package/dist/{error-CpbbtyXL.d.mts.map → error-DwajXSKM.d.mts.map} +1 -1
- package/dist/error.d.mts +1 -1
- package/dist/{errors-DySW1F9_.d.mts → errors-CAq8pYpW.d.mts} +2 -2
- package/dist/{errors-DySW1F9_.d.mts.map → errors-CAq8pYpW.d.mts.map} +1 -1
- package/dist/{errors-BQgyQ9xe.mjs → errors-DA0cyr8q.mjs} +1 -1
- package/dist/{errors-BQgyQ9xe.mjs.map → errors-DA0cyr8q.mjs.map} +1 -1
- package/dist/{event-1BMl7o0k.mjs → event-qwAv-7AZ.mjs} +1 -1
- package/dist/{event-1BMl7o0k.mjs.map → event-qwAv-7AZ.mjs.map} +1 -1
- package/dist/express/index.d.mts +3 -3
- package/dist/express/index.d.mts.map +1 -1
- package/dist/express/index.mjs +3 -3
- package/dist/express/index.mjs.map +1 -1
- package/dist/fastify/index.d.mts +9 -4
- package/dist/fastify/index.d.mts.map +1 -1
- package/dist/fastify/index.mjs +10 -8
- package/dist/fastify/index.mjs.map +1 -1
- package/dist/{fork-8u_zFOJq.mjs → fork-CYm453dq.mjs} +40 -14
- package/dist/fork-CYm453dq.mjs.map +1 -0
- package/dist/{headers-CU-QqnYg.mjs → headers-VtmnWcfn.mjs} +1 -1
- package/dist/{headers-CU-QqnYg.mjs.map → headers-VtmnWcfn.mjs.map} +1 -1
- package/dist/hono/index.d.mts +2 -2
- package/dist/hono/index.d.mts.map +1 -1
- package/dist/hono/index.mjs +10 -2
- package/dist/hono/index.mjs.map +1 -1
- package/dist/{http-6umVAKDW.mjs → http-Bept5EIC.mjs} +2 -2
- package/dist/{http-6umVAKDW.mjs.map → http-Bept5EIC.mjs.map} +1 -1
- package/dist/http.d.mts +1 -1
- package/dist/{index-o1_z4phv.d.mts → index-CE7kH0II.d.mts} +15 -8
- package/dist/index-CE7kH0II.d.mts.map +1 -0
- package/dist/index.d.mts +9 -9
- package/dist/index.mjs +9 -15
- package/dist/index.mjs.map +1 -1
- package/dist/{integration-DTZtjSqh.mjs → integration-CR601uyW.mjs} +3 -3
- package/dist/{integration-DTZtjSqh.mjs.map → integration-CR601uyW.mjs.map} +1 -1
- package/dist/{logger-DntcxxHg.d.mts → logger-BccCJUyD.d.mts} +11 -3
- package/dist/logger-BccCJUyD.d.mts.map +1 -0
- package/dist/logger.d.mts +2 -2
- package/dist/logger.mjs +2 -2
- package/dist/{middleware-U-lIAzHg.d.mts → middleware-DQ6-h8h0.d.mts} +9 -2
- package/dist/middleware-DQ6-h8h0.d.mts.map +1 -0
- package/dist/nestjs/index.d.mts +2 -2
- package/dist/nestjs/index.mjs +4 -4
- package/dist/next/client.d.mts +1 -1
- package/dist/next/index.d.mts +6 -5
- package/dist/next/index.d.mts.map +1 -1
- package/dist/next/index.mjs +36 -38
- 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 +10 -16
- package/dist/nitro/errorHandler.mjs.map +1 -1
- package/dist/nitro/module.d.mts +2 -2
- package/dist/nitro/module.d.mts.map +1 -1
- package/dist/nitro/module.mjs +8 -2
- package/dist/nitro/module.mjs.map +1 -1
- package/dist/nitro/plugin.mjs +37 -65
- package/dist/nitro/plugin.mjs.map +1 -1
- package/dist/nitro/v3/errorHandler.d.mts +0 -7
- package/dist/nitro/v3/errorHandler.mjs +13 -15
- package/dist/nitro/v3/errorHandler.mjs.map +1 -1
- package/dist/nitro/v3/index.d.mts +2 -2
- package/dist/nitro/v3/module.d.mts +1 -1
- package/dist/nitro/v3/module.d.mts.map +1 -1
- package/dist/nitro/v3/module.mjs +9 -4
- package/dist/nitro/v3/module.mjs.map +1 -1
- package/dist/nitro/v3/plugin.mjs +77 -44
- package/dist/nitro/v3/plugin.mjs.map +1 -1
- package/dist/nitro/v3/useLogger.d.mts +1 -1
- package/dist/nitro-ClRZLD1g.mjs +96 -0
- package/dist/nitro-ClRZLD1g.mjs.map +1 -0
- package/dist/{nitro-oZre8ab3.d.mts → nitro-zCXTylj4.d.mts} +7 -2
- package/dist/nitro-zCXTylj4.d.mts.map +1 -0
- package/dist/nitroConfigBridge-BkVWnSV3.mjs +164 -0
- package/dist/nitroConfigBridge-BkVWnSV3.mjs.map +1 -0
- package/dist/{nodeResponse-BkkionWl.mjs → nodeResponse-CIEEbrNE.mjs} +1 -1
- package/dist/{nodeResponse-BkkionWl.mjs.map → nodeResponse-CIEEbrNE.mjs.map} +1 -1
- package/dist/nuxt/module.d.mts +13 -4
- package/dist/nuxt/module.d.mts.map +1 -1
- package/dist/nuxt/module.mjs +11 -4
- package/dist/nuxt/module.mjs.map +1 -1
- package/dist/orpc/index.d.mts +115 -0
- package/dist/orpc/index.d.mts.map +1 -0
- package/dist/orpc/index.mjs +145 -0
- package/dist/orpc/index.mjs.map +1 -0
- package/dist/{package-v_MmOZeA.mjs → package-CUhII9DA.mjs} +2 -2
- package/dist/package-CUhII9DA.mjs.map +1 -0
- package/dist/{parseError-yVZ58wIK.d.mts → parseError-Cagr-Ctc.d.mts} +2 -2
- package/dist/parseError-Cagr-Ctc.d.mts.map +1 -0
- package/dist/pretty-error-CVVgwlTn.mjs +278 -0
- package/dist/pretty-error-CVVgwlTn.mjs.map +1 -0
- package/dist/pretty-error-snippet.node-c_bzjg7g.mjs +47 -0
- package/dist/pretty-error-snippet.node-c_bzjg7g.mjs.map +1 -0
- package/dist/react-router/index.d.mts +2 -2
- package/dist/react-router/index.mjs +5 -6
- package/dist/react-router/index.mjs.map +1 -1
- package/dist/{routes-CnIgYWf8.mjs → routes-4rMzRyTk.mjs} +1 -1
- package/dist/{routes-CnIgYWf8.mjs.map → routes-4rMzRyTk.mjs.map} +1 -1
- package/dist/runtime/client/log.d.mts +1 -1
- package/dist/runtime/server/routes/_evlog/ingest.post.mjs +28 -12
- package/dist/runtime/server/routes/_evlog/ingest.post.mjs.map +1 -1
- package/dist/runtime/server/useLogger.d.mts +1 -1
- package/dist/runtime/utils/parseError.d.mts +2 -2
- package/dist/runtime/utils/parseError.mjs +1 -1
- package/dist/{severity-R5Egq3qz.mjs → severity-CwXUSHt3.mjs} +1 -1
- package/dist/{severity-R5Egq3qz.mjs.map → severity-CwXUSHt3.mjs.map} +1 -1
- package/dist/{source-location-Dco0cRTz.mjs → source-location-xkDGiERl.mjs} +1 -1
- package/dist/{source-location-Dco0cRTz.mjs.map → source-location-xkDGiERl.mjs.map} +1 -1
- package/dist/{storage-Dwinmg8P.mjs → storage-7X37OToT.mjs} +2 -1
- package/dist/{storage-Dwinmg8P.mjs.map → storage-7X37OToT.mjs.map} +1 -1
- package/dist/stream.d.mts +1 -1
- package/dist/stream.mjs +1 -1
- package/dist/streamResponse-CmQ3qUbF.mjs +94 -0
- package/dist/streamResponse-CmQ3qUbF.mjs.map +1 -0
- package/dist/sveltekit/index.d.mts +3 -3
- package/dist/sveltekit/index.d.mts.map +1 -1
- package/dist/sveltekit/index.mjs +48 -16
- package/dist/sveltekit/index.mjs.map +1 -1
- package/dist/toolkit.d.mts +38 -7
- package/dist/toolkit.d.mts.map +1 -1
- package/dist/toolkit.mjs +15 -14
- package/dist/types.d.mts +2 -2
- package/dist/{useLogger-BsPL4AQm.d.mts → useLogger-Dv52PDpH.d.mts} +2 -2
- package/dist/{useLogger-BsPL4AQm.d.mts.map → useLogger-Dv52PDpH.d.mts.map} +1 -1
- package/dist/{utils-DLCeShxL.d.mts → utils-DmNbZwBZ.d.mts} +21 -4
- package/dist/{utils-DLCeShxL.d.mts.map → utils-DmNbZwBZ.d.mts.map} +1 -1
- package/dist/utils.d.mts +2 -2
- package/dist/utils.mjs +31 -9
- package/dist/utils.mjs.map +1 -1
- package/dist/vite/index.d.mts +1 -1
- package/dist/vite/index.mjs +1 -1
- package/dist/workers.d.mts +1 -1
- package/dist/workers.mjs +1 -1
- package/package.json +48 -15
- package/dist/audit-CC8nfazi.d.mts.map +0 -1
- package/dist/audit-pV5aLGP0.mjs.map +0 -1
- package/dist/define-D6OJdSUH.mjs.map +0 -1
- package/dist/define-MSdhzmXn.d.mts.map +0 -1
- package/dist/drain-X7_5szSI.mjs.map +0 -1
- package/dist/fork-8u_zFOJq.mjs.map +0 -1
- package/dist/index-o1_z4phv.d.mts.map +0 -1
- package/dist/logger-DntcxxHg.d.mts.map +0 -1
- package/dist/middleware-U-lIAzHg.d.mts.map +0 -1
- package/dist/nitro-DErMq_Zj.mjs +0 -34
- package/dist/nitro-DErMq_Zj.mjs.map +0 -1
- package/dist/nitro-oZre8ab3.d.mts.map +0 -1
- package/dist/nitroConfigBridge-DKk7eOn-.mjs +0 -92
- package/dist/nitroConfigBridge-DKk7eOn-.mjs.map +0 -1
- package/dist/package-v_MmOZeA.mjs.map +0 -1
- package/dist/parseError-yVZ58wIK.d.mts.map +0 -1
package/README.md
CHANGED
|
@@ -528,6 +528,38 @@ log.set({ users: { count: 42 } })
|
|
|
528
528
|
|
|
529
529
|
See the full [nestjs example](https://github.com/HugoRCD/evlog/tree/main/examples/nestjs) for a complete working project.
|
|
530
530
|
|
|
531
|
+
## oRPC
|
|
532
|
+
|
|
533
|
+
```typescript
|
|
534
|
+
// server/orpc.ts
|
|
535
|
+
import { os } from '@orpc/server'
|
|
536
|
+
import { RPCHandler } from '@orpc/server/fetch'
|
|
537
|
+
import { initLogger } from 'evlog'
|
|
538
|
+
import { evlog, withEvlog, type EvlogOrpcContext } from 'evlog/orpc'
|
|
539
|
+
|
|
540
|
+
initLogger({ env: { service: 'orpc-api' } })
|
|
541
|
+
|
|
542
|
+
const base = os.$context<EvlogOrpcContext>().use(evlog())
|
|
543
|
+
|
|
544
|
+
const router = {
|
|
545
|
+
ping: base.handler(({ context }) => {
|
|
546
|
+
context.log.set({ pinged: true })
|
|
547
|
+
return { ok: true }
|
|
548
|
+
}),
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
const handler = withEvlog(new RPCHandler(router))
|
|
552
|
+
|
|
553
|
+
export default async function fetch(request: Request) {
|
|
554
|
+
const { matched, response } = await handler.handle(request, { prefix: '/rpc' })
|
|
555
|
+
return matched ? response : new Response('Not Found', { status: 404 })
|
|
556
|
+
}
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
`withEvlog()` wraps the handler and emits one wide event per request; `os.use(evlog())` exposes `context.log` to procedures and tags each event with the procedure path as `operation`. Use `useLogger()` from `evlog/orpc` to access the logger off-context.
|
|
560
|
+
|
|
561
|
+
See the full [orpc example](https://github.com/HugoRCD/evlog/tree/main/examples/orpc) for a complete working project.
|
|
562
|
+
|
|
531
563
|
## Browser
|
|
532
564
|
|
|
533
565
|
Use the `log` API on the client side for structured browser logging:
|
|
@@ -821,7 +853,7 @@ export default defineNitroPlugin((nitroApp) => {
|
|
|
821
853
|
Set environment variables:
|
|
822
854
|
|
|
823
855
|
```bash
|
|
824
|
-
|
|
856
|
+
NUXT_AXIOM_API_KEY=xaat-your-token
|
|
825
857
|
NUXT_AXIOM_DATASET=your-dataset
|
|
826
858
|
```
|
|
827
859
|
|
|
@@ -916,9 +948,69 @@ export default defineNitroPlugin((nitroApp) => {
|
|
|
916
948
|
Set environment variables:
|
|
917
949
|
|
|
918
950
|
```bash
|
|
919
|
-
|
|
951
|
+
NUXT_BETTER_STACK_API_KEY=your-source-token
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
### HyperDX
|
|
955
|
+
|
|
956
|
+
```typescript
|
|
957
|
+
// server/plugins/evlog-drain.ts
|
|
958
|
+
import { createHyperDXDrain } from 'evlog/hyperdx'
|
|
959
|
+
|
|
960
|
+
export default defineNitroPlugin((nitroApp) => {
|
|
961
|
+
nitroApp.hooks.hook('evlog:drain', createHyperDXDrain())
|
|
962
|
+
})
|
|
963
|
+
```
|
|
964
|
+
|
|
965
|
+
Set environment variables:
|
|
966
|
+
|
|
967
|
+
```bash
|
|
968
|
+
NUXT_HYPERDX_API_KEY=your-api-key
|
|
969
|
+
# Optional — defaults to https://in-otel.hyperdx.io
|
|
970
|
+
NUXT_HYPERDX_ENDPOINT=https://in-otel.hyperdx.io
|
|
971
|
+
```
|
|
972
|
+
|
|
973
|
+
### File System
|
|
974
|
+
|
|
975
|
+
Write wide events to local NDJSON files (`.evlog/logs/` by default):
|
|
976
|
+
|
|
977
|
+
```typescript
|
|
978
|
+
// server/plugins/evlog-drain.ts
|
|
979
|
+
import { createFsDrain } from 'evlog/fs'
|
|
980
|
+
|
|
981
|
+
export default defineNitroPlugin((nitroApp) => {
|
|
982
|
+
nitroApp.hooks.hook('evlog:drain', createFsDrain())
|
|
983
|
+
})
|
|
984
|
+
```
|
|
985
|
+
|
|
986
|
+
Set environment variables:
|
|
987
|
+
|
|
988
|
+
```bash
|
|
989
|
+
NUXT_EVLOG_FS_DIR=.evlog/logs
|
|
920
990
|
```
|
|
921
991
|
|
|
992
|
+
### Memory
|
|
993
|
+
|
|
994
|
+
In-memory ring buffer — works in any runtime, including Cloudflare Workers:
|
|
995
|
+
|
|
996
|
+
```typescript
|
|
997
|
+
// server/plugins/evlog-drain.ts
|
|
998
|
+
import { createMemoryDrain } from 'evlog/memory'
|
|
999
|
+
|
|
1000
|
+
export default defineNitroPlugin((nitroApp) => {
|
|
1001
|
+
nitroApp.hooks.hook('evlog:drain', createMemoryDrain())
|
|
1002
|
+
})
|
|
1003
|
+
```
|
|
1004
|
+
|
|
1005
|
+
Optional environment variables:
|
|
1006
|
+
|
|
1007
|
+
```bash
|
|
1008
|
+
NUXT_EVLOG_MEMORY_STORE=default
|
|
1009
|
+
NUXT_EVLOG_MEMORY_MAX_EVENTS=1000
|
|
1010
|
+
```
|
|
1011
|
+
|
|
1012
|
+
Pair with `readMemoryLogs()` for dev-only agent access over HTTP. See the [Memory adapter docs](https://www.evlog.dev/integrate/adapters/self-hosted/memory).
|
|
1013
|
+
|
|
922
1014
|
### Multiple Destinations
|
|
923
1015
|
|
|
924
1016
|
Send logs to multiple services:
|
|
@@ -1297,6 +1389,7 @@ try {
|
|
|
1297
1389
|
| **Hono** | `app.use(evlog())` with `import { evlog } from 'evlog/hono'` ([example](./examples/hono)) |
|
|
1298
1390
|
| **Fastify** | `app.register(evlog)` with `import { evlog } from 'evlog/fastify'` ([example](./examples/fastify)) |
|
|
1299
1391
|
| **Elysia** | `.use(evlog())` with `import { evlog } from 'evlog/elysia'` ([example](./examples/elysia)) |
|
|
1392
|
+
| **oRPC** | `withEvlog(handler)` + `os.use(evlog())` with `import { evlog, withEvlog } from 'evlog/orpc'` ([example](./examples/orpc)) |
|
|
1300
1393
|
| **Cloudflare Workers** | Manual setup with `import { initWorkersLogger, createWorkersLogger } from 'evlog/workers'` ([example](./examples/workers)) |
|
|
1301
1394
|
| **Custom** | Build your own with `import { createMiddlewareLogger } from 'evlog/toolkit'` ([guide](https://evlog.dev/extend/custom-framework)) |
|
|
1302
1395
|
| **Analog** | Nitro v2 module setup |
|
package/dist/adapters/axiom.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as httpPost } from "../http-
|
|
2
|
-
import { i as resolveAdapterConfig, n as defineHttpDrain } from "../drain-
|
|
1
|
+
import { r as httpPost } from "../http-Bept5EIC.mjs";
|
|
2
|
+
import { i as resolveAdapterConfig, n as defineHttpDrain } from "../drain-D_fy7m0n.mjs";
|
|
3
3
|
//#region src/adapters/axiom.ts
|
|
4
4
|
const AXIOM_FIELDS = [
|
|
5
5
|
{
|
|
@@ -1 +1 @@
|
|
|
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 source: '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,
|
|
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: Partial<ResolvedAxiomConfig>): Partial<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 source: '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,QAAoE;AAC5F,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;EACP,QAAQ;EACT,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,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as DrainContext, ft as WideEvent } from "../audit-BUAajsPU.mjs";
|
|
2
2
|
//#region src/adapters/better-stack.d.ts
|
|
3
3
|
interface BetterStackConfig {
|
|
4
4
|
/** Better Stack API key (replaces deprecated `sourceToken`). */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as httpPost } from "../http-
|
|
2
|
-
import { i as resolveAdapterConfig, n as defineHttpDrain } from "../drain-
|
|
1
|
+
import { r as httpPost } from "../http-Bept5EIC.mjs";
|
|
2
|
+
import { i as resolveAdapterConfig, n as defineHttpDrain } from "../drain-D_fy7m0n.mjs";
|
|
3
3
|
//#region src/adapters/better-stack.ts
|
|
4
4
|
const BETTER_STACK_FIELDS = [
|
|
5
5
|
{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as DrainContext, ft as WideEvent } from "../audit-BUAajsPU.mjs";
|
|
2
2
|
//#region src/adapters/datadog.d.ts
|
|
3
3
|
interface DatadogConfig {
|
|
4
4
|
/** Datadog API key with Logs intake permission */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as httpPost } from "../http-
|
|
2
|
-
import { i as resolveAdapterConfig, n as defineHttpDrain } from "../drain-
|
|
1
|
+
import { r as httpPost } from "../http-Bept5EIC.mjs";
|
|
2
|
+
import { i as resolveAdapterConfig, n as defineHttpDrain } from "../drain-D_fy7m0n.mjs";
|
|
3
3
|
//#region src/adapters/datadog.ts
|
|
4
4
|
const DATADOG_FIELDS = [
|
|
5
5
|
{
|
package/dist/adapters/fs.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as DrainContext, X as LogLevel, ft as WideEvent } from "../audit-BUAajsPU.mjs";
|
|
2
2
|
//#region src/adapters/fs.d.ts
|
|
3
3
|
interface FsConfig {
|
|
4
4
|
/** Directory for log files. Default: `.evlog/logs` */
|
package/dist/adapters/fs.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { i as resolveAdapterConfig, t as defineDrain } from "../drain-
|
|
1
|
+
import { i as resolveAdapterConfig, t as defineDrain } from "../drain-D_fy7m0n.mjs";
|
|
2
2
|
import { join, sep } from "node:path";
|
|
3
|
-
import { appendFile, mkdir, open, readdir, stat, unlink, writeFile } from "node:fs/promises";
|
|
4
3
|
import { createReadStream } from "node:fs";
|
|
4
|
+
import { appendFile, mkdir, open, readdir, stat, unlink, writeFile } from "node:fs/promises";
|
|
5
5
|
import { createInterface } from "node:readline";
|
|
6
6
|
//#region src/adapters/fs.ts
|
|
7
7
|
const FS_FIELDS = [
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { B as DrainContext, X as LogLevel, ft as WideEvent } from "../audit-BUAajsPU.mjs";
|
|
2
|
+
//#region src/adapters/memory.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for the in-memory drain.
|
|
5
|
+
*/
|
|
6
|
+
interface MemoryConfig {
|
|
7
|
+
/** Named store key. Multiple drains sharing the same key share the same buffer. Default: `'default'` */
|
|
8
|
+
store: string;
|
|
9
|
+
/** Maximum number of events to keep in the ring buffer. Oldest events are discarded when the limit is exceeded. Default: `1000` */
|
|
10
|
+
maxEvents: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Write events directly into the named store. Exported for direct use and
|
|
14
|
+
* easier testing without going through the drain pipeline.
|
|
15
|
+
*/
|
|
16
|
+
declare function writeToMemory(events: WideEvent[], config: MemoryConfig): void;
|
|
17
|
+
/**
|
|
18
|
+
* Create a drain that stores wide events in an in-memory ring buffer.
|
|
19
|
+
*
|
|
20
|
+
* Works in **any** runtime — including Cloudflare Workers (workerd) — where
|
|
21
|
+
* the filesystem (`evlog/fs`) is not available. Pair it with a dev-only HTTP
|
|
22
|
+
* endpoint to let agents retrieve the buffer over HTTP.
|
|
23
|
+
*
|
|
24
|
+
* Configuration priority (highest to lowest):
|
|
25
|
+
* 1. Overrides passed to `createMemoryDrain()`
|
|
26
|
+
* 2. `runtimeConfig.evlog.memory` / `runtimeConfig.memory` (Nitro)
|
|
27
|
+
* 3. Environment variables: `NUXT_EVLOG_MEMORY_STORE`, `EVLOG_MEMORY_STORE`,
|
|
28
|
+
* `NUXT_EVLOG_MEMORY_MAX_EVENTS`, `EVLOG_MEMORY_MAX_EVENTS`
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* // Hono + Cloudflare Workers
|
|
33
|
+
* import { createMemoryDrain, readMemoryLogs } from 'evlog/memory'
|
|
34
|
+
*
|
|
35
|
+
* app.use(evlog({ drain: createMemoryDrain() }))
|
|
36
|
+
*
|
|
37
|
+
* // Dev-only endpoint for agent retrieval
|
|
38
|
+
* if (env.NODE_ENV === 'development') {
|
|
39
|
+
* app.get('/_evlog/logs', (c) => c.json(readMemoryLogs()))
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
declare function createMemoryDrain(overrides?: Partial<MemoryConfig>): (ctx: DrainContext | DrainContext[]) => Promise<void>;
|
|
44
|
+
/** Options accepted by {@link readMemoryLogs}. */
|
|
45
|
+
interface ReadMemoryLogsOptions {
|
|
46
|
+
/** Named store to read from. Default: `'default'` */
|
|
47
|
+
store?: string;
|
|
48
|
+
/** Only include events with `timestamp >= since`. */
|
|
49
|
+
since?: Date | string;
|
|
50
|
+
/** Only include events with `timestamp <= until`. */
|
|
51
|
+
until?: Date | string;
|
|
52
|
+
/** Filter by log level. */
|
|
53
|
+
level?: LogLevel | LogLevel[];
|
|
54
|
+
/** Custom predicate — return `false` to skip the event. */
|
|
55
|
+
filter?: (event: WideEvent) => boolean;
|
|
56
|
+
/** Return at most this many of the most-recent matching events. */
|
|
57
|
+
limit?: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Read events from the named in-memory store. Returns a snapshot of the
|
|
61
|
+
* buffer with optional filtering, ordered oldest-first.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* import { readMemoryLogs } from 'evlog/memory'
|
|
66
|
+
*
|
|
67
|
+
* // All events
|
|
68
|
+
* const events = readMemoryLogs()
|
|
69
|
+
*
|
|
70
|
+
* // Errors in the last hour
|
|
71
|
+
* const errors = readMemoryLogs({
|
|
72
|
+
* level: 'error',
|
|
73
|
+
* since: new Date(Date.now() - 60 * 60 * 1000),
|
|
74
|
+
* })
|
|
75
|
+
*
|
|
76
|
+
* // Expose as a JSON endpoint
|
|
77
|
+
* app.get('/_evlog/logs', (c) => c.json(readMemoryLogs({ limit: 200 })))
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
declare function readMemoryLogs(options?: ReadMemoryLogsOptions): WideEvent[];
|
|
81
|
+
/**
|
|
82
|
+
* Clear all events from a named store (or `'default'`).
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* clearMemoryLogs() // clears the default store
|
|
87
|
+
* clearMemoryLogs('my-store') // clears a named store
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
declare function clearMemoryLogs(store?: string): void;
|
|
91
|
+
/**
|
|
92
|
+
* Parse a flat query-string object (e.g. from `c.req.query()` in Hono, or
|
|
93
|
+
* `req.query` in Express) into {@link ReadMemoryLogsOptions} with proper type
|
|
94
|
+
* coercion.
|
|
95
|
+
*
|
|
96
|
+
* This lets agents discover and pass filter parameters through HTTP query
|
|
97
|
+
* strings directly:
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* // Hono — zero glue
|
|
102
|
+
* app.get('/_evlog/logs', (c) =>
|
|
103
|
+
* c.json(readMemoryLogs(parseReadMemoryLogsQuery(c.req.query()))))
|
|
104
|
+
*
|
|
105
|
+
* // Express
|
|
106
|
+
* app.get('/_evlog/logs', (req, res) =>
|
|
107
|
+
* res.json(readMemoryLogs(parseReadMemoryLogsQuery(req.query as Record<string, string>))))
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* Supported query params: `store`, `since`, `until`, `level` (comma-separated),
|
|
111
|
+
* `limit`. The `filter` predicate cannot be expressed as a query param.
|
|
112
|
+
*/
|
|
113
|
+
declare function parseReadMemoryLogsQuery(query: Record<string, string | string[] | undefined>): ReadMemoryLogsOptions;
|
|
114
|
+
//#endregion
|
|
115
|
+
export { MemoryConfig, ReadMemoryLogsOptions, clearMemoryLogs, createMemoryDrain, parseReadMemoryLogsQuery, readMemoryLogs, writeToMemory };
|
|
116
|
+
//# sourceMappingURL=memory.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.mts","names":[],"sources":["../../src/adapters/memory.ts"],"mappings":";;;;;UAQiB,YAAA;EAAY;EAE3B,KAAA;EAAA;EAEA,SAAA;AAAA;;;;;iBA2Cc,aAAA,CAAc,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,YAAA;;;;;AAmC3D;;;;;;;;;;;;;;;;;;;AAYA;;;iBAZgB,iBAAA,CAAkB,SAAA,GAAY,OAAA,CAAQ,YAAA,KAAa,GAAA,EAAd,YAAA,GAAc,YAAA,OAAA,OAAA;;UAYlD,qBAAA;EAQI;EANnB,KAAA;EAQ0B;EAN1B,KAAA,GAAQ,IAAA;EAFR;EAIA,KAAA,GAAQ,IAAA;EAFA;EAIR,KAAA,GAAQ,QAAA,GAAW,QAAA;EAFX;EAIR,MAAA,IAAU,KAAA,EAAO,SAAA;EAFT;EAIR,KAAA;AAAA;;;;;;AA+BF;;;;;;;;;AAuCA;;;;;AA6BA;;iBApEgB,cAAA,CAAe,OAAA,GAAS,qBAAA,GAA6B,SAAA;;;;;;;;;;iBAuCrD,eAAA,CAAgB,KAAA;;;;;;;;;;;;;;;;;;;;;;;iBA6BhB,wBAAA,CACd,KAAA,EAAO,MAAA,0CACN,qBAAA"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { i as resolveAdapterConfig, t as defineDrain } from "../drain-D_fy7m0n.mjs";
|
|
2
|
+
//#region src/adapters/memory.ts
|
|
3
|
+
const DEFAULT_STORE = "default";
|
|
4
|
+
const DEFAULT_MAX_EVENTS = 1e3;
|
|
5
|
+
const MEMORY_FIELDS = [{
|
|
6
|
+
key: "store",
|
|
7
|
+
env: ["NUXT_EVLOG_MEMORY_STORE", "EVLOG_MEMORY_STORE"]
|
|
8
|
+
}, {
|
|
9
|
+
key: "maxEvents",
|
|
10
|
+
env: ["NUXT_EVLOG_MEMORY_MAX_EVENTS", "EVLOG_MEMORY_MAX_EVENTS"]
|
|
11
|
+
}];
|
|
12
|
+
const stores = /* @__PURE__ */ new Map();
|
|
13
|
+
function getOrCreateStore(name) {
|
|
14
|
+
if (!stores.has(name)) stores.set(name, []);
|
|
15
|
+
return stores.get(name);
|
|
16
|
+
}
|
|
17
|
+
function parseMaxEvents(value) {
|
|
18
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
19
|
+
const n = Math.floor(value);
|
|
20
|
+
return n > 0 ? n : void 0;
|
|
21
|
+
}
|
|
22
|
+
if (typeof value === "string" && value) {
|
|
23
|
+
const parsed = Number.parseFloat(value);
|
|
24
|
+
if (!Number.isFinite(parsed)) return void 0;
|
|
25
|
+
const n = Math.floor(parsed);
|
|
26
|
+
return n > 0 ? n : void 0;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function resolveMemoryConfig(overrides) {
|
|
30
|
+
return {
|
|
31
|
+
store: overrides?.store ?? DEFAULT_STORE,
|
|
32
|
+
maxEvents: parseMaxEvents(overrides?.maxEvents) ?? DEFAULT_MAX_EVENTS
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Write events directly into the named store. Exported for direct use and
|
|
37
|
+
* easier testing without going through the drain pipeline.
|
|
38
|
+
*/
|
|
39
|
+
function writeToMemory(events, config) {
|
|
40
|
+
if (events.length === 0) return;
|
|
41
|
+
const store = getOrCreateStore(config.store);
|
|
42
|
+
store.push(...events);
|
|
43
|
+
if (store.length > config.maxEvents) store.splice(0, store.length - config.maxEvents);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Create a drain that stores wide events in an in-memory ring buffer.
|
|
47
|
+
*
|
|
48
|
+
* Works in **any** runtime — including Cloudflare Workers (workerd) — where
|
|
49
|
+
* the filesystem (`evlog/fs`) is not available. Pair it with a dev-only HTTP
|
|
50
|
+
* endpoint to let agents retrieve the buffer over HTTP.
|
|
51
|
+
*
|
|
52
|
+
* Configuration priority (highest to lowest):
|
|
53
|
+
* 1. Overrides passed to `createMemoryDrain()`
|
|
54
|
+
* 2. `runtimeConfig.evlog.memory` / `runtimeConfig.memory` (Nitro)
|
|
55
|
+
* 3. Environment variables: `NUXT_EVLOG_MEMORY_STORE`, `EVLOG_MEMORY_STORE`,
|
|
56
|
+
* `NUXT_EVLOG_MEMORY_MAX_EVENTS`, `EVLOG_MEMORY_MAX_EVENTS`
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* // Hono + Cloudflare Workers
|
|
61
|
+
* import { createMemoryDrain, readMemoryLogs } from 'evlog/memory'
|
|
62
|
+
*
|
|
63
|
+
* app.use(evlog({ drain: createMemoryDrain() }))
|
|
64
|
+
*
|
|
65
|
+
* // Dev-only endpoint for agent retrieval
|
|
66
|
+
* if (env.NODE_ENV === 'development') {
|
|
67
|
+
* app.get('/_evlog/logs', (c) => c.json(readMemoryLogs()))
|
|
68
|
+
* }
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
function createMemoryDrain(overrides) {
|
|
72
|
+
return defineDrain({
|
|
73
|
+
name: "memory",
|
|
74
|
+
resolve: async () => {
|
|
75
|
+
return resolveMemoryConfig(await resolveAdapterConfig("memory", MEMORY_FIELDS, overrides));
|
|
76
|
+
},
|
|
77
|
+
send: (events, cfg) => Promise.resolve(writeToMemory(events, cfg))
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function normalizeTimestamp(value) {
|
|
81
|
+
if (!value) return void 0;
|
|
82
|
+
const ts = (value instanceof Date ? value : new Date(value)).getTime();
|
|
83
|
+
return Number.isNaN(ts) ? void 0 : ts;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Read events from the named in-memory store. Returns a snapshot of the
|
|
87
|
+
* buffer with optional filtering, ordered oldest-first.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* import { readMemoryLogs } from 'evlog/memory'
|
|
92
|
+
*
|
|
93
|
+
* // All events
|
|
94
|
+
* const events = readMemoryLogs()
|
|
95
|
+
*
|
|
96
|
+
* // Errors in the last hour
|
|
97
|
+
* const errors = readMemoryLogs({
|
|
98
|
+
* level: 'error',
|
|
99
|
+
* since: new Date(Date.now() - 60 * 60 * 1000),
|
|
100
|
+
* })
|
|
101
|
+
*
|
|
102
|
+
* // Expose as a JSON endpoint
|
|
103
|
+
* app.get('/_evlog/logs', (c) => c.json(readMemoryLogs({ limit: 200 })))
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
function readMemoryLogs(options = {}) {
|
|
107
|
+
const storeName = options.store ?? DEFAULT_STORE;
|
|
108
|
+
const events = [...stores.get(storeName) ?? []];
|
|
109
|
+
const sinceMs = normalizeTimestamp(options.since);
|
|
110
|
+
const untilMs = normalizeTimestamp(options.until);
|
|
111
|
+
const levels = options.level ? new Set(Array.isArray(options.level) ? options.level : [options.level]) : void 0;
|
|
112
|
+
const custom = options.filter;
|
|
113
|
+
const filtered = events.filter((event) => {
|
|
114
|
+
if (levels && !levels.has(event.level)) return false;
|
|
115
|
+
if (sinceMs !== void 0 || untilMs !== void 0) {
|
|
116
|
+
const ts = typeof event.timestamp === "string" ? Date.parse(event.timestamp) : NaN;
|
|
117
|
+
if (Number.isNaN(ts)) return false;
|
|
118
|
+
if (sinceMs !== void 0 && ts < sinceMs) return false;
|
|
119
|
+
if (untilMs !== void 0 && ts > untilMs) return false;
|
|
120
|
+
}
|
|
121
|
+
if (custom && !custom(event)) return false;
|
|
122
|
+
return true;
|
|
123
|
+
});
|
|
124
|
+
if (options.limit !== void 0) {
|
|
125
|
+
if (options.limit <= 0) return [];
|
|
126
|
+
if (filtered.length > options.limit) return filtered.slice(-options.limit);
|
|
127
|
+
}
|
|
128
|
+
return filtered;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Clear all events from a named store (or `'default'`).
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```ts
|
|
135
|
+
* clearMemoryLogs() // clears the default store
|
|
136
|
+
* clearMemoryLogs('my-store') // clears a named store
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
function clearMemoryLogs(store = DEFAULT_STORE) {
|
|
140
|
+
const s = stores.get(store);
|
|
141
|
+
if (s) s.length = 0;
|
|
142
|
+
}
|
|
143
|
+
const VALID_LEVELS = new Set([
|
|
144
|
+
"info",
|
|
145
|
+
"error",
|
|
146
|
+
"warn",
|
|
147
|
+
"debug"
|
|
148
|
+
]);
|
|
149
|
+
/**
|
|
150
|
+
* Parse a flat query-string object (e.g. from `c.req.query()` in Hono, or
|
|
151
|
+
* `req.query` in Express) into {@link ReadMemoryLogsOptions} with proper type
|
|
152
|
+
* coercion.
|
|
153
|
+
*
|
|
154
|
+
* This lets agents discover and pass filter parameters through HTTP query
|
|
155
|
+
* strings directly:
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```ts
|
|
159
|
+
* // Hono — zero glue
|
|
160
|
+
* app.get('/_evlog/logs', (c) =>
|
|
161
|
+
* c.json(readMemoryLogs(parseReadMemoryLogsQuery(c.req.query()))))
|
|
162
|
+
*
|
|
163
|
+
* // Express
|
|
164
|
+
* app.get('/_evlog/logs', (req, res) =>
|
|
165
|
+
* res.json(readMemoryLogs(parseReadMemoryLogsQuery(req.query as Record<string, string>))))
|
|
166
|
+
* ```
|
|
167
|
+
*
|
|
168
|
+
* Supported query params: `store`, `since`, `until`, `level` (comma-separated),
|
|
169
|
+
* `limit`. The `filter` predicate cannot be expressed as a query param.
|
|
170
|
+
*/
|
|
171
|
+
function parseReadMemoryLogsQuery(query) {
|
|
172
|
+
const opts = {};
|
|
173
|
+
const { store, since, until, level, limit } = query;
|
|
174
|
+
if (typeof store === "string" && store) opts.store = store;
|
|
175
|
+
if (typeof since === "string" && since) opts.since = since;
|
|
176
|
+
if (typeof until === "string" && until) opts.until = until;
|
|
177
|
+
if (level !== void 0) {
|
|
178
|
+
const levels = (Array.isArray(level) ? level : level.split(",")).map((l) => l.trim()).filter((l) => VALID_LEVELS.has(l));
|
|
179
|
+
if (levels.length === 1) [opts.level] = levels;
|
|
180
|
+
else if (levels.length > 1) opts.level = levels;
|
|
181
|
+
}
|
|
182
|
+
if (typeof limit === "string") {
|
|
183
|
+
const n = Number.parseInt(limit, 10);
|
|
184
|
+
if (!Number.isNaN(n)) opts.limit = n;
|
|
185
|
+
}
|
|
186
|
+
return opts;
|
|
187
|
+
}
|
|
188
|
+
//#endregion
|
|
189
|
+
export { clearMemoryLogs, createMemoryDrain, parseReadMemoryLogsQuery, readMemoryLogs, writeToMemory };
|
|
190
|
+
|
|
191
|
+
//# sourceMappingURL=memory.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.mjs","names":[],"sources":["../../src/adapters/memory.ts"],"sourcesContent":["import type { LogLevel, WideEvent } from '../types'\nimport type { ConfigField } from '../shared/config'\nimport { resolveAdapterConfig } from '../shared/config'\nimport { defineDrain } from '../shared/drain'\n\n/**\n * Configuration for the in-memory drain.\n */\nexport interface MemoryConfig {\n /** Named store key. Multiple drains sharing the same key share the same buffer. Default: `'default'` */\n store: string\n /** Maximum number of events to keep in the ring buffer. Oldest events are discarded when the limit is exceeded. Default: `1000` */\n maxEvents: number\n}\n\nconst DEFAULT_STORE = 'default'\nconst DEFAULT_MAX_EVENTS = 1000\n\nconst MEMORY_FIELDS: ConfigField<Partial<MemoryConfig>>[] = [\n { key: 'store', env: ['NUXT_EVLOG_MEMORY_STORE', 'EVLOG_MEMORY_STORE'] },\n { key: 'maxEvents', env: ['NUXT_EVLOG_MEMORY_MAX_EVENTS', 'EVLOG_MEMORY_MAX_EVENTS'] },\n]\n\nconst stores = new Map<string, WideEvent[]>()\n\nfunction getOrCreateStore(name: string): WideEvent[] {\n if (!stores.has(name)) stores.set(name, [])\n return stores.get(name)!\n}\n\nfunction parseMaxEvents(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) {\n const n = Math.floor(value)\n return n > 0 ? n : undefined\n }\n if (typeof value === 'string' && value) {\n const parsed = Number.parseFloat(value)\n if (!Number.isFinite(parsed)) return undefined\n const n = Math.floor(parsed)\n return n > 0 ? n : undefined\n }\n return undefined\n}\n\nfunction resolveMemoryConfig(overrides?: Partial<MemoryConfig>): MemoryConfig {\n return {\n store: overrides?.store ?? DEFAULT_STORE,\n maxEvents: parseMaxEvents(overrides?.maxEvents) ?? DEFAULT_MAX_EVENTS,\n }\n}\n\n/**\n * Write events directly into the named store. Exported for direct use and\n * easier testing without going through the drain pipeline.\n */\nexport function writeToMemory(events: WideEvent[], config: MemoryConfig): void {\n if (events.length === 0) return\n const store = getOrCreateStore(config.store)\n store.push(...events)\n if (store.length > config.maxEvents) {\n store.splice(0, store.length - config.maxEvents)\n }\n}\n\n/**\n * Create a drain that stores wide events in an in-memory ring buffer.\n *\n * Works in **any** runtime — including Cloudflare Workers (workerd) — where\n * the filesystem (`evlog/fs`) is not available. Pair it with a dev-only HTTP\n * endpoint to let agents retrieve the buffer over HTTP.\n *\n * Configuration priority (highest to lowest):\n * 1. Overrides passed to `createMemoryDrain()`\n * 2. `runtimeConfig.evlog.memory` / `runtimeConfig.memory` (Nitro)\n * 3. Environment variables: `NUXT_EVLOG_MEMORY_STORE`, `EVLOG_MEMORY_STORE`,\n * `NUXT_EVLOG_MEMORY_MAX_EVENTS`, `EVLOG_MEMORY_MAX_EVENTS`\n *\n * @example\n * ```ts\n * // Hono + Cloudflare Workers\n * import { createMemoryDrain, readMemoryLogs } from 'evlog/memory'\n *\n * app.use(evlog({ drain: createMemoryDrain() }))\n *\n * // Dev-only endpoint for agent retrieval\n * if (env.NODE_ENV === 'development') {\n * app.get('/_evlog/logs', (c) => c.json(readMemoryLogs()))\n * }\n * ```\n */\nexport function createMemoryDrain(overrides?: Partial<MemoryConfig>) {\n return defineDrain<MemoryConfig>({\n name: 'memory',\n resolve: async () => {\n const resolved = await resolveAdapterConfig<Partial<MemoryConfig>>('memory', MEMORY_FIELDS, overrides)\n return resolveMemoryConfig(resolved)\n },\n send: (events, cfg) => Promise.resolve(writeToMemory(events, cfg)),\n })\n}\n\n/** Options accepted by {@link readMemoryLogs}. */\nexport interface ReadMemoryLogsOptions {\n /** Named store to read from. Default: `'default'` */\n store?: string\n /** Only include events with `timestamp >= since`. */\n since?: Date | string\n /** Only include events with `timestamp <= until`. */\n until?: Date | string\n /** Filter by log level. */\n level?: LogLevel | LogLevel[]\n /** Custom predicate — return `false` to skip the event. */\n filter?: (event: WideEvent) => boolean\n /** Return at most this many of the most-recent matching events. */\n limit?: number\n}\n\nfunction normalizeTimestamp(value: Date | string | undefined): number | undefined {\n if (!value) return undefined\n const date = value instanceof Date ? value : new Date(value)\n const ts = date.getTime()\n return Number.isNaN(ts) ? undefined : ts\n}\n\n/**\n * Read events from the named in-memory store. Returns a snapshot of the\n * buffer with optional filtering, ordered oldest-first.\n *\n * @example\n * ```ts\n * import { readMemoryLogs } from 'evlog/memory'\n *\n * // All events\n * const events = readMemoryLogs()\n *\n * // Errors in the last hour\n * const errors = readMemoryLogs({\n * level: 'error',\n * since: new Date(Date.now() - 60 * 60 * 1000),\n * })\n *\n * // Expose as a JSON endpoint\n * app.get('/_evlog/logs', (c) => c.json(readMemoryLogs({ limit: 200 })))\n * ```\n */\nexport function readMemoryLogs(options: ReadMemoryLogsOptions = {}): WideEvent[] {\n const storeName = options.store ?? DEFAULT_STORE\n const events = [...(stores.get(storeName) ?? [])]\n\n const sinceMs = normalizeTimestamp(options.since)\n const untilMs = normalizeTimestamp(options.until)\n const levels = options.level\n ? new Set<LogLevel>(Array.isArray(options.level) ? options.level : [options.level])\n : undefined\n const custom = options.filter\n\n const filtered = events.filter((event) => {\n if (levels && !levels.has(event.level)) return false\n if (sinceMs !== undefined || untilMs !== undefined) {\n const ts = typeof event.timestamp === 'string' ? Date.parse(event.timestamp) : Number.NaN\n if (Number.isNaN(ts)) return false\n if (sinceMs !== undefined && ts < sinceMs) return false\n if (untilMs !== undefined && ts > untilMs) return false\n }\n if (custom && !custom(event)) return false\n return true\n })\n\n if (options.limit !== undefined) {\n if (options.limit <= 0) return []\n if (filtered.length > options.limit) return filtered.slice(-options.limit)\n }\n return filtered\n}\n\n/**\n * Clear all events from a named store (or `'default'`).\n *\n * @example\n * ```ts\n * clearMemoryLogs() // clears the default store\n * clearMemoryLogs('my-store') // clears a named store\n * ```\n */\nexport function clearMemoryLogs(store = DEFAULT_STORE): void {\n const s = stores.get(store)\n if (s) s.length = 0\n}\n\nconst VALID_LEVELS = new Set<LogLevel>(['info', 'error', 'warn', 'debug'])\n\n/**\n * Parse a flat query-string object (e.g. from `c.req.query()` in Hono, or\n * `req.query` in Express) into {@link ReadMemoryLogsOptions} with proper type\n * coercion.\n *\n * This lets agents discover and pass filter parameters through HTTP query\n * strings directly:\n *\n * @example\n * ```ts\n * // Hono — zero glue\n * app.get('/_evlog/logs', (c) =>\n * c.json(readMemoryLogs(parseReadMemoryLogsQuery(c.req.query()))))\n *\n * // Express\n * app.get('/_evlog/logs', (req, res) =>\n * res.json(readMemoryLogs(parseReadMemoryLogsQuery(req.query as Record<string, string>))))\n * ```\n *\n * Supported query params: `store`, `since`, `until`, `level` (comma-separated),\n * `limit`. The `filter` predicate cannot be expressed as a query param.\n */\nexport function parseReadMemoryLogsQuery(\n query: Record<string, string | string[] | undefined>,\n): ReadMemoryLogsOptions {\n const opts: ReadMemoryLogsOptions = {}\n const { store, since, until, level, limit } = query\n\n if (typeof store === 'string' && store) opts.store = store\n if (typeof since === 'string' && since) opts.since = since\n if (typeof until === 'string' && until) opts.until = until\n\n if (level !== undefined) {\n const raw = Array.isArray(level) ? level : level.split(',')\n const levels = raw.map((l) => l.trim()).filter((l): l is LogLevel => VALID_LEVELS.has(l as LogLevel))\n if (levels.length === 1) [opts.level] = levels\n else if (levels.length > 1) opts.level = levels\n }\n\n if (typeof limit === 'string') {\n const n = Number.parseInt(limit, 10)\n if (!Number.isNaN(n)) opts.limit = n\n }\n\n return opts\n}\n"],"mappings":"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"}
|
package/dist/adapters/otlp.d.mts
CHANGED
package/dist/adapters/otlp.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { r as httpPost } from "../http-
|
|
2
|
-
import { i as resolveAdapterConfig, n as defineHttpDrain } from "../drain-
|
|
3
|
-
import { n as toOtlpAttributeValue } from "../event-
|
|
4
|
-
import { n as OTEL_SEVERITY_TEXT, t as OTEL_SEVERITY_NUMBER } from "../severity-
|
|
1
|
+
import { r as httpPost } from "../http-Bept5EIC.mjs";
|
|
2
|
+
import { i as resolveAdapterConfig, n as defineHttpDrain } from "../drain-D_fy7m0n.mjs";
|
|
3
|
+
import { n as toOtlpAttributeValue } from "../event-qwAv-7AZ.mjs";
|
|
4
|
+
import { n as OTEL_SEVERITY_TEXT, t as OTEL_SEVERITY_NUMBER } from "../severity-CwXUSHt3.mjs";
|
|
5
5
|
//#region src/adapters/otlp.ts
|
|
6
6
|
const OTLP_FIELDS = [
|
|
7
7
|
{
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as httpPost } from "../http-
|
|
2
|
-
import { i as resolveAdapterConfig, n as defineHttpDrain, t as defineDrain } from "../drain-
|
|
1
|
+
import { r as httpPost } from "../http-Bept5EIC.mjs";
|
|
2
|
+
import { i as resolveAdapterConfig, n as defineHttpDrain, t as defineDrain } from "../drain-D_fy7m0n.mjs";
|
|
3
3
|
import { sendBatchToOTLP } from "./otlp.mjs";
|
|
4
4
|
//#region src/adapters/posthog.ts
|
|
5
5
|
const POSTHOG_FIELDS = [
|
package/dist/adapters/sentry.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { r as httpPost } from "../http-
|
|
2
|
-
import { i as resolveAdapterConfig, n as defineHttpDrain } from "../drain-
|
|
3
|
-
import { t as OTEL_SEVERITY_NUMBER } from "../severity-
|
|
1
|
+
import { r as httpPost } from "../http-Bept5EIC.mjs";
|
|
2
|
+
import { i as resolveAdapterConfig, n as defineHttpDrain } from "../drain-D_fy7m0n.mjs";
|
|
3
|
+
import { t as OTEL_SEVERITY_NUMBER } from "../severity-CwXUSHt3.mjs";
|
|
4
4
|
//#region src/adapters/sentry.ts
|
|
5
5
|
const SENTRY_FIELDS = [
|
|
6
6
|
{
|
package/dist/ai/index.d.mts
CHANGED