[{"data":1,"prerenderedAt":1925},["ShallowReactive",2],{"navigation_docs":3,"-use-cases-libraries":581,"-use-cases-libraries-surround":1920},[4,35,85,138,318,458,517,556],{"title":5,"path":6,"stem":7,"children":8,"page":34},"Start","\u002Fstart","1.start",[9,14,19,24,29],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","\u002Fstart\u002Fintroduction","1.start\u002F1.introduction","i-lucide-info",{"title":15,"path":16,"stem":17,"icon":18},"Why start with evlog","\u002Fstart\u002Fwhy-evlog","1.start\u002F2.why-evlog","i-lucide-rocket",{"title":20,"path":21,"stem":22,"icon":23},"Installation","\u002Fstart\u002Finstallation","1.start\u002F3.installation","i-lucide-download",{"title":25,"path":26,"stem":27,"icon":28},"Quick Start","\u002Fstart\u002Fquick-start","1.start\u002F4.quick-start","i-lucide-zap",{"title":30,"path":31,"stem":32,"icon":33},"Choose your logger","\u002Fstart\u002Ftypescript-logging-library","1.start\u002F5.typescript-logging-library","i-lucide-file-code",false,{"title":36,"path":37,"stem":38,"children":39,"page":34},"Learn","\u002Flearn","2.learn",[40,45,50,55,60,65,70,75,80],{"title":41,"path":42,"stem":43,"icon":44},"Overview","\u002Flearn\u002Foverview","2.learn\u002F0.overview","i-lucide-list",{"title":46,"path":47,"stem":48,"icon":49},"Simple Logging","\u002Flearn\u002Fsimple-logging","2.learn\u002F1.simple-logging","i-lucide-terminal",{"title":51,"path":52,"stem":53,"icon":54},"Wide Events","\u002Flearn\u002Fwide-events","2.learn\u002F2.wide-events","i-lucide-layers",{"title":56,"path":57,"stem":58,"icon":59},"Structured Errors","\u002Flearn\u002Fstructured-errors","2.learn\u002F3.structured-errors","i-lucide-shield-alert",{"title":61,"path":62,"stem":63,"icon":64},"Lifecycle","\u002Flearn\u002Flifecycle","2.learn\u002F4.lifecycle","i-lucide-arrow-right-left",{"title":66,"path":67,"stem":68,"icon":69},"Sampling","\u002Flearn\u002Fsampling","2.learn\u002F5.sampling","i-lucide-filter",{"title":71,"path":72,"stem":73,"icon":74},"Auto-Redaction","\u002Flearn\u002Fredaction","2.learn\u002F6.redaction","i-lucide-eye-off",{"title":76,"path":77,"stem":78,"icon":79},"Typed Fields","\u002Flearn\u002Ftyped-fields","2.learn\u002F7.typed-fields","i-simple-icons-typescript",{"title":81,"path":82,"stem":83,"icon":84},"Catalogs","\u002Flearn\u002Fcatalogs","2.learn\u002F8.catalogs","i-lucide-book-open",{"title":86,"path":87,"stem":88,"children":89,"page":34},"CLI","\u002Fcli","3.cli",[90,93,98,103,108,113,118,123,128,133],{"title":41,"path":91,"stem":92,"icon":49},"\u002Fcli\u002Foverview","3.cli\u002F0.overview",{"title":94,"path":95,"stem":96,"icon":97},"init","\u002Fcli\u002Finit","3.cli\u002F1.init","i-lucide-wand-sparkles",{"title":99,"path":100,"stem":101,"icon":102},"map","\u002Fcli\u002Fmap","3.cli\u002F2.map","i-lucide-radar",{"title":104,"path":105,"stem":106,"icon":107},"Rules","\u002Fcli\u002Frules","3.cli\u002F3.rules","i-lucide-list-checks",{"title":109,"path":110,"stem":111,"icon":112},"Scoring","\u002Fcli\u002Fscoring","3.cli\u002F4.scoring","i-lucide-gauge",{"title":114,"path":115,"stem":116,"icon":117},"CI","\u002Fcli\u002Fci","3.cli\u002F5.ci","i-lucide-git-pull-request",{"title":119,"path":120,"stem":121,"icon":122},"doctor","\u002Fcli\u002Fdoctor","3.cli\u002F6.doctor","i-lucide-stethoscope",{"title":124,"path":125,"stem":126,"icon":127},"telemetry","\u002Fcli\u002Ftelemetry","3.cli\u002F7.telemetry","i-lucide-bar-chart-3",{"title":129,"path":130,"stem":131,"icon":132},"agents","\u002Fcli\u002Fagents","3.cli\u002F8.agents","i-lucide-bot",{"title":134,"path":135,"stem":136,"icon":137},"Observability Score","\u002Fcli\u002Fobservability-score","3.cli\u002F9.observability-score","i-lucide-activity",{"title":139,"path":140,"stem":141,"children":142,"page":34},"Integrate","\u002Fintegrate","4.integrate",[143,147,230],{"title":41,"path":144,"stem":145,"icon":146},"\u002Fintegrate\u002Foverview","4.integrate\u002F0.overview","i-lucide-plug",{"title":148,"path":149,"stem":150,"children":151,"page":34},"Adapters","\u002Fintegrate\u002Fadapters","4.integrate\u002Fadapters",[152,155,185,210],{"title":41,"path":153,"stem":154,"icon":44},"\u002Fintegrate\u002Fadapters\u002Foverview","4.integrate\u002Fadapters\u002F01.overview",{"title":156,"path":157,"stem":158,"children":159,"page":34},"Cloud","\u002Fintegrate\u002Fadapters\u002Fcloud","4.integrate\u002Fadapters\u002Fcloud",[160,165,170,175,180],{"title":161,"path":162,"stem":163,"icon":164},"Axiom","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Faxiom","4.integrate\u002Fadapters\u002Fcloud\u002F01.axiom","i-custom-axiom",{"title":166,"path":167,"stem":168,"icon":169},"PostHog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fposthog","4.integrate\u002Fadapters\u002Fcloud\u002F02.posthog","i-simple-icons-posthog",{"title":171,"path":172,"stem":173,"icon":174},"Sentry","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fsentry","4.integrate\u002Fadapters\u002Fcloud\u002F03.sentry","i-simple-icons-sentry",{"title":176,"path":177,"stem":178,"icon":179},"Better Stack","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fbetter-stack","4.integrate\u002Fadapters\u002Fcloud\u002F04.better-stack","i-simple-icons-betterstack",{"title":181,"path":182,"stem":183,"icon":184},"Datadog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fdatadog","4.integrate\u002Fadapters\u002Fcloud\u002F05.datadog","i-simple-icons-datadog",{"title":186,"path":187,"stem":188,"children":189,"page":34},"Cloud or Self-Hosted","\u002Fintegrate\u002Fadapters\u002Fhybrid","4.integrate\u002Fadapters\u002Fhybrid",[190,195,200,205],{"title":191,"path":192,"stem":193,"icon":194},"Grafana Loki","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Floki","4.integrate\u002Fadapters\u002Fhybrid\u002F01.loki","i-simple-icons-grafana",{"title":196,"path":197,"stem":198,"icon":199},"ClickHouse","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Fclickhouse","4.integrate\u002Fadapters\u002Fhybrid\u002F02.clickhouse","i-simple-icons-clickhouse",{"title":201,"path":202,"stem":203,"icon":204},"OTLP","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Fotlp","4.integrate\u002Fadapters\u002Fhybrid\u002F03.otlp","i-simple-icons-opentelemetry",{"title":206,"path":207,"stem":208,"icon":209},"HyperDX","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Fhyperdx","4.integrate\u002Fadapters\u002Fhybrid\u002F04.hyperdx","i-custom-hyperdx",{"title":211,"path":212,"stem":213,"children":214,"page":34},"Self-Hosted","\u002Fintegrate\u002Fadapters\u002Fself-hosted","4.integrate\u002Fadapters\u002Fself-hosted",[215,220,225],{"title":216,"path":217,"stem":218,"icon":219},"File System","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Ffs","4.integrate\u002Fadapters\u002Fself-hosted\u002F01.fs","i-lucide-hard-drive",{"title":221,"path":222,"stem":223,"icon":224},"NuxtHub","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fnuxthub","4.integrate\u002Fadapters\u002Fself-hosted\u002F02.nuxthub","i-simple-icons-nuxt",{"title":226,"path":227,"stem":228,"icon":229},"Memory","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fmemory","4.integrate\u002Fadapters\u002Fself-hosted\u002F03.memory","i-lucide-cpu",{"title":231,"path":232,"stem":233,"children":234,"page":34},"Frameworks","\u002Fintegrate\u002Fframeworks","4.integrate\u002Fframeworks",[235,239,244,249,254,259,264,269,274,279,284,289,294,299,303,308,313],{"title":41,"path":236,"stem":237,"icon":238},"\u002Fintegrate\u002Fframeworks\u002Foverview","4.integrate\u002Fframeworks\u002F00.overview","i-lucide-layout-grid",{"title":240,"path":241,"stem":242,"icon":243},"Nuxt","\u002Fintegrate\u002Fframeworks\u002Fnuxt","4.integrate\u002Fframeworks\u002F01.nuxt","i-simple-icons-nuxtdotjs",{"title":245,"path":246,"stem":247,"icon":248},"Next.js","\u002Fintegrate\u002Fframeworks\u002Fnextjs","4.integrate\u002Fframeworks\u002F02.nextjs","i-simple-icons-nextdotjs",{"title":250,"path":251,"stem":252,"icon":253},"SvelteKit","\u002Fintegrate\u002Fframeworks\u002Fsveltekit","4.integrate\u002Fframeworks\u002F03.sveltekit","i-simple-icons-svelte",{"title":255,"path":256,"stem":257,"icon":258},"Nitro","\u002Fintegrate\u002Fframeworks\u002Fnitro","4.integrate\u002Fframeworks\u002F04.nitro","i-custom-nitro",{"title":260,"path":261,"stem":262,"icon":263},"TanStack Start","\u002Fintegrate\u002Fframeworks\u002Ftanstack-start","4.integrate\u002Fframeworks\u002F05.tanstack-start","i-custom-tanstack",{"title":265,"path":266,"stem":267,"icon":268},"NestJS","\u002Fintegrate\u002Fframeworks\u002Fnestjs","4.integrate\u002Fframeworks\u002F06.nestjs","i-simple-icons-nestjs",{"title":270,"path":271,"stem":272,"icon":273},"Express","\u002Fintegrate\u002Fframeworks\u002Fexpress","4.integrate\u002Fframeworks\u002F07.express","i-simple-icons-express",{"title":275,"path":276,"stem":277,"icon":278},"Hono","\u002Fintegrate\u002Fframeworks\u002Fhono","4.integrate\u002Fframeworks\u002F08.hono","i-simple-icons-hono",{"title":280,"path":281,"stem":282,"icon":283},"Fastify","\u002Fintegrate\u002Fframeworks\u002Ffastify","4.integrate\u002Fframeworks\u002F09.fastify","i-simple-icons-fastify",{"title":285,"path":286,"stem":287,"icon":288},"Elysia","\u002Fintegrate\u002Fframeworks\u002Felysia","4.integrate\u002Fframeworks\u002F10.elysia","i-custom-elysia",{"title":290,"path":291,"stem":292,"icon":293},"React Router","\u002Fintegrate\u002Fframeworks\u002Freact-router","4.integrate\u002Fframeworks\u002F11.react-router","i-custom-reactrouter",{"title":295,"path":296,"stem":297,"icon":298},"Cloudflare Workers","\u002Fintegrate\u002Fframeworks\u002Fcloudflare-workers","4.integrate\u002Fframeworks\u002F12.cloudflare-workers","i-simple-icons-cloudflare",{"title":300,"path":301,"stem":302,"icon":79},"Standalone","\u002Fintegrate\u002Fframeworks\u002Fstandalone","4.integrate\u002Fframeworks\u002F13.standalone",{"title":304,"path":305,"stem":306,"icon":307},"Astro","\u002Fintegrate\u002Fframeworks\u002Fastro","4.integrate\u002Fframeworks\u002F14.astro","i-simple-icons-astro",{"title":309,"path":310,"stem":311,"icon":312},"oRPC","\u002Fintegrate\u002Fframeworks\u002Forpc","4.integrate\u002Fframeworks\u002F15.orpc","i-lucide-network",{"title":314,"path":315,"stem":316,"icon":317},"AWS Lambda","\u002Fintegrate\u002Fframeworks\u002Faws-lambda","4.integrate\u002Fframeworks\u002F16.aws-lambda","i-custom-lambda",{"title":319,"path":320,"stem":321,"children":322,"page":34},"Use Cases","\u002Fuse-cases","5.use-cases",[323,326,331,359,386,418,439,444,449,453],{"title":41,"path":324,"stem":325,"icon":107},"\u002Fuse-cases\u002Foverview","5.use-cases\u002F0.overview",{"title":327,"path":328,"stem":329,"icon":330},"Client Logging","\u002Fuse-cases\u002Fclient-logging","5.use-cases\u002F1.client-logging","i-lucide-monitor",{"title":332,"icon":333,"path":334,"stem":335,"children":336,"page":34},"AI SDK","i-simple-icons-vercel","\u002Fuse-cases\u002Fai-sdk","5.use-cases\u002F2.ai-sdk",[337,340,345,350,355],{"title":41,"path":338,"stem":339,"icon":44},"\u002Fuse-cases\u002Fai-sdk\u002Foverview","5.use-cases\u002F2.ai-sdk\u002F01.overview",{"title":341,"path":342,"stem":343,"icon":344},"Usage","\u002Fuse-cases\u002Fai-sdk\u002Fusage","5.use-cases\u002F2.ai-sdk\u002F02.usage","i-lucide-code",{"title":346,"path":347,"stem":348,"icon":349},"Options","\u002Fuse-cases\u002Fai-sdk\u002Foptions","5.use-cases\u002F2.ai-sdk\u002F03.options","i-lucide-sliders",{"title":351,"path":352,"stem":353,"icon":354},"Metadata","\u002Fuse-cases\u002Fai-sdk\u002Fmetadata","5.use-cases\u002F2.ai-sdk\u002F04.metadata","i-lucide-database",{"title":356,"path":357,"stem":358,"icon":137},"Telemetry","\u002Fuse-cases\u002Fai-sdk\u002Ftelemetry","5.use-cases\u002F2.ai-sdk\u002F05.telemetry",{"title":360,"icon":361,"path":362,"stem":363,"children":364,"page":34},"Better Auth","i-simple-icons-betterauth","\u002Fuse-cases\u002Fbetter-auth","5.use-cases\u002F3.better-auth",[365,368,373,378,382],{"title":41,"path":366,"stem":367,"icon":44},"\u002Fuse-cases\u002Fbetter-auth\u002Foverview","5.use-cases\u002F3.better-auth\u002F01.overview",{"title":369,"path":370,"stem":371,"icon":372},"Identify User","\u002Fuse-cases\u002Fbetter-auth\u002Fidentify-user","5.use-cases\u002F3.better-auth\u002F02.identify-user","i-lucide-user-check",{"title":374,"path":375,"stem":376,"icon":377},"Middleware","\u002Fuse-cases\u002Fbetter-auth\u002Fmiddleware","5.use-cases\u002F3.better-auth\u002F03.middleware","i-lucide-shield",{"title":379,"path":380,"stem":381,"icon":330},"Client Sync","\u002Fuse-cases\u002Fbetter-auth\u002Fclient-sync","5.use-cases\u002F3.better-auth\u002F04.client-sync",{"title":383,"path":384,"stem":385,"icon":112},"Performance","\u002Fuse-cases\u002Fbetter-auth\u002Fperformance","5.use-cases\u002F3.better-auth\u002F05.performance",{"title":387,"icon":388,"path":389,"stem":390,"children":391,"page":34},"Audit Logs","i-lucide-shield-check","\u002Fuse-cases\u002Faudit","5.use-cases\u002F4.audit",[392,395,400,405,410,414],{"title":41,"path":393,"stem":394,"icon":44},"\u002Fuse-cases\u002Faudit\u002Foverview","5.use-cases\u002F4.audit\u002F01.overview",{"title":396,"path":397,"stem":398,"icon":399},"Schema","\u002Fuse-cases\u002Faudit\u002Fschema","5.use-cases\u002F4.audit\u002F02.schema","i-lucide-file-text",{"title":401,"path":402,"stem":403,"icon":404},"Recording","\u002Fuse-cases\u002Faudit\u002Frecording","5.use-cases\u002F4.audit\u002F03.recording","i-lucide-pen-line",{"title":406,"path":407,"stem":408,"icon":409},"Drains","\u002Fuse-cases\u002Faudit\u002Fpipeline","5.use-cases\u002F4.audit\u002F04.pipeline","i-lucide-link",{"title":411,"path":412,"stem":413,"icon":388},"Compliance","\u002Fuse-cases\u002Faudit\u002Fcompliance","5.use-cases\u002F4.audit\u002F05.compliance",{"title":415,"path":416,"stem":417,"icon":84},"Recipes","\u002Fuse-cases\u002Faudit\u002Frecipes","5.use-cases\u002F4.audit\u002F06.recipes",{"title":356,"icon":112,"path":419,"stem":420,"children":421,"page":34},"\u002Fuse-cases\u002Ftelemetry","5.use-cases\u002F4.telemetry",[422,425,430,435],{"title":41,"path":423,"stem":424,"icon":44},"\u002Fuse-cases\u002Ftelemetry\u002Foverview","5.use-cases\u002F4.telemetry\u002F01.overview",{"title":426,"path":427,"stem":428,"icon":429},"Setup","\u002Fuse-cases\u002Ftelemetry\u002Fsetup","5.use-cases\u002F4.telemetry\u002F02.setup","i-lucide-wrench",{"title":431,"path":432,"stem":433,"icon":434},"Ingest","\u002Fuse-cases\u002Ftelemetry\u002Fingest","5.use-cases\u002F4.telemetry\u002F03.ingest","i-lucide-server",{"title":436,"path":437,"stem":438,"icon":84},"Reference","\u002Fuse-cases\u002Ftelemetry\u002Freference","5.use-cases\u002F4.telemetry\u002F04.reference",{"title":440,"path":441,"stem":442,"icon":443},"Enrichers","\u002Fuse-cases\u002Fenrichers","5.use-cases\u002F5.enrichers","i-lucide-sparkles",{"title":445,"path":446,"stem":447,"icon":448},"eve","\u002Fuse-cases\u002Feve","5.use-cases\u002F5.eve","i-custom-eve",{"title":450,"path":451,"stem":452,"icon":434},"Node.js request logging","\u002Fuse-cases\u002Fstructured-logging-nodejs","5.use-cases\u002F6.structured-logging-nodejs",{"title":454,"path":455,"stem":456,"icon":457},"Libraries","\u002Fuse-cases\u002Flibraries","5.use-cases\u002F7.libraries","i-lucide-package",{"title":459,"path":460,"stem":461,"children":462,"page":34},"Extend","\u002Fextend","6.extend",[463,467,472,477,481,486,490,494,498,502,507,512],{"title":41,"path":464,"stem":465,"icon":466},"\u002Fextend\u002Foverview","6.extend\u002F0.overview","i-lucide-blocks",{"title":468,"path":469,"stem":470,"icon":471},"Stream","\u002Fextend\u002Fstream","6.extend\u002F1.stream","i-lucide-radio-tower",{"title":473,"path":474,"stem":475,"icon":476},"Custom framework","\u002Fextend\u002Fcustom-framework","6.extend\u002F10.custom-framework","i-lucide-puzzle",{"title":478,"path":479,"stem":480,"icon":471},"Diagnostics channel","\u002Fextend\u002Fdiagnostics-channel","6.extend\u002F11.diagnostics-channel",{"title":482,"path":483,"stem":484,"icon":485},"FS reader","\u002Fextend\u002Ffs-reader","6.extend\u002F2.fs-reader","i-lucide-folder-search",{"title":415,"path":487,"stem":488,"icon":489},"\u002Fextend\u002Fconsumer-recipes","6.extend\u002F3.consumer-recipes","i-lucide-chef-hat",{"title":491,"path":492,"stem":493,"icon":466},"Plugins","\u002Fextend\u002Fplugins","6.extend\u002F4.plugins",{"title":495,"path":496,"stem":497,"icon":443},"Custom enrichers","\u002Fextend\u002Fcustom-enrichers","6.extend\u002F5.custom-enrichers",{"title":499,"path":500,"stem":501,"icon":69},"Tail sampling","\u002Fextend\u002Ftail-sampling","6.extend\u002F6.tail-sampling",{"title":503,"path":504,"stem":505,"icon":506},"Identity headers","\u002Fextend\u002Fidentity-headers","6.extend\u002F7.identity-headers","i-lucide-fingerprint",{"title":508,"path":509,"stem":510,"icon":511},"Custom drains","\u002Fextend\u002Fcustom-drains","6.extend\u002F8.custom-drains","i-lucide-share-2",{"title":513,"path":514,"stem":515,"icon":516},"Drain pipeline","\u002Fextend\u002Fdrain-pipeline","6.extend\u002F9.drain-pipeline","i-lucide-workflow",{"title":436,"path":518,"stem":519,"children":520,"page":34},"\u002Freference","7.reference",[521,525,530,533,538,542,547,551],{"title":41,"path":522,"stem":523,"icon":524},"\u002Freference\u002Foverview","7.reference\u002F0.overview","i-lucide-book-marked",{"title":526,"path":527,"stem":528,"icon":529},"Configuration","\u002Freference\u002Fconfiguration","7.reference\u002F1.configuration","i-lucide-settings",{"title":383,"path":531,"stem":532,"icon":112},"\u002Freference\u002Fperformance","7.reference\u002F2.performance",{"title":534,"path":535,"stem":536,"icon":537},"Vite Plugin","\u002Freference\u002Fvite-plugin","7.reference\u002F3.vite-plugin","i-custom-vite",{"title":539,"path":540,"stem":541,"icon":388},"Best Practices","\u002Freference\u002Fbest-practices","7.reference\u002F4.best-practices",{"title":543,"path":544,"stem":545,"icon":546},"vs Other Loggers","\u002Freference\u002Fvs-other-loggers","7.reference\u002F5.vs-other-loggers","i-lucide-scale",{"title":548,"path":549,"stem":550,"icon":443},"Agent Skills","\u002Freference\u002Fagent-skills","7.reference\u002F6.agent-skills",{"title":552,"path":553,"stem":554,"icon":555},"Cost","\u002Freference\u002Fcost","7.reference\u002F7.cost","i-lucide-receipt",{"title":557,"path":558,"stem":559,"children":560,"page":34},"Compare","\u002Fcompare","8.compare",[561,565,569,573,577],{"title":562,"path":563,"stem":564,"icon":546},"evlog vs Pino","\u002Fcompare\u002Fpino","8.compare\u002F1.pino",{"title":566,"path":567,"stem":568,"icon":204},"evlog vs OpenTelemetry","\u002Fcompare\u002Fopentelemetry","8.compare\u002F2.opentelemetry",{"title":570,"path":571,"stem":572,"icon":546},"evlog vs LogTape","\u002Fcompare\u002Flogtape","8.compare\u002F3.logtape",{"title":574,"path":575,"stem":576,"icon":546},"evlog vs Winston: formats and request events","\u002Fcompare\u002Fwinston","8.compare\u002F4.winston",{"title":578,"path":579,"stem":580,"icon":546},"evlog vs Consola: reporters and request context","\u002Fcompare\u002Fconsola","8.compare\u002F5.consola",{"id":582,"title":583,"body":584,"description":1907,"extension":1908,"links":1909,"meta":1916,"navigation":1917,"path":455,"seo":1918,"stem":456,"__hash__":1919},"docs\u002F5.use-cases\u002F7.libraries.md","Libraries and SDKs",{"type":585,"value":586,"toc":1898},"minimark",[587,591,671,679,684,694,717,720,870,874,883,1039,1049,1053,1056,1169,1191,1206,1210,1221,1362,1376,1380,1386,1498,1507,1511,1514,1517,1666,1673,1864,1876,1880,1894],[588,589,590],"p",{},"Your package runs inside someone else's process. When it logs, the events it emits land in the host application's stream, pass through the host's redaction, and reach whatever drains the host configured. That division is the whole contract: the library emits, the application configures. This page covers both sides, for a package that ships evlog and for an application that runs one.",[592,593,596,599,657],"prompt",{":actions":594,"description":595,"icon":457},"[\"copy\",\"cursor\",\"claude\"]","Add evlog logging to my library or SDK",[588,597,598],{},"Set up evlog logging in an npm library that runs inside a host application.",[600,601,602,619,626,629,636,647],"ul",{},[603,604,605,606,610,611,614,615,618],"li",{},"Import ",[607,608,609],"code",{},"log"," and ",[607,612,613],{},"createLogger"," from 'evlog' and emit with a tag or a ",[607,616,617],{},"source"," field that starts with the package name",[603,620,621,622,625],{},"Never call ",[607,623,624],{},"initLogger()"," from library code: the configuration is process-wide and the last call wins",[603,627,628],{},"No configuration at import time: emit only when your code runs",[603,630,631,632,635],{},"Inside a host request handler, accept the request logger as a parameter (",[607,633,634],{},"AuditableLogger",") instead of creating your own",[603,637,638,639,642,643,646],{},"Ship errors as a ",[607,640,641],{},"defineErrorCatalog()"," catalog with a prefix your package owns (e.g. ",[607,644,645],{},"mylib.RATE_LIMITED",")",[603,648,649,650,653,654],{},"In tests, collect emitted events with ",[607,651,652],{},"initLogger({ drain })"," or the memory drain from ",[607,655,656],{},"evlog\u002Fmemory",[588,658,659,660,666,667],{},"Docs: ",[661,662,663],"a",{"href":663,"rel":664},"https:\u002F\u002Fwww.evlog.dev\u002Fuse-cases\u002Flibraries",[665],"nofollow","\nCatalogs: ",[661,668,669],{"href":669,"rel":670},"https:\u002F\u002Fwww.evlog.dev\u002Flearn\u002Fcatalogs",[665],[672,673,676,678],"callout",{"color":674,"icon":675},"warning","i-lucide-alert-triangle",[607,677,624],{}," writes process-wide state shared by every evlog copy of the same major version, and the last call wins. A library that calls it at import time replaces the host's drain, sampling, and redaction for the whole process. Configuration belongs to the application.",[680,681,683],"h2",{"id":682},"emit-without-owning-the-configuration","Emit without owning the configuration",[588,685,686,687,689,690,693],{},"Use the global ",[607,688,609],{}," API the same way you would use ",[607,691,692],{},"console.log",". It works whether or not the host configured evlog: without configuration it prints (pretty in development, JSON otherwise). The form you call decides how the event travels:",[600,695,696,703],{},[603,697,698,699,702],{},"The object form, ",[607,700,701],{},"log.info({ source: 'mylib', action: 'sync' })",", always becomes a wide event through the host's pipeline: sampled, redacted, and delivered to the drain the host configured.",[603,704,705,706,709,710,610,713,716],{},"The tagged form, ",[607,707,708],{},"log.info('mylib.client', 'GET \u002Fusers')",", prints through the host's pretty printer when pretty is on (the development default) and reaches neither a drain nor redaction there. In JSON mode it becomes a small wide event carrying ",[607,711,712],{},"tag",[607,714,715],{},"message",".",[588,718,719],{},"If the host may be draining, prefer the object form and keep your package name in a field so the event stays filterable:",[721,722,728],"pre",{"className":723,"code":724,"filename":725,"language":726,"meta":727,"style":727},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { log } from 'evlog'\n\nexport function fetchRecords(path: string): void {\n  log.info({ source: 'mylib.client', message: `GET ${path}` })\n}\n","src\u002Fsync.ts","typescript","",[607,729,730,763,770,807,864],{"__ignoreMap":727},[731,732,735,739,743,747,750,753,756,760],"span",{"class":733,"line":734},"line",1,[731,736,738],{"class":737},"s7zQu","import",[731,740,742],{"class":741},"sMK4o"," {",[731,744,746],{"class":745},"sTEyZ"," log",[731,748,749],{"class":741}," }",[731,751,752],{"class":737}," from",[731,754,755],{"class":741}," '",[731,757,759],{"class":758},"sfazB","evlog",[731,761,762],{"class":741},"'\n",[731,764,766],{"class":733,"line":765},2,[731,767,769],{"emptyLinePlaceholder":768},true,"\n",[731,771,773,776,780,784,787,791,794,798,801,804],{"class":733,"line":772},3,[731,774,775],{"class":737},"export",[731,777,779],{"class":778},"spNyl"," function",[731,781,783],{"class":782},"s2Zo4"," fetchRecords",[731,785,786],{"class":741},"(",[731,788,790],{"class":789},"sHdIc","path",[731,792,793],{"class":741},":",[731,795,797],{"class":796},"sBMFI"," string",[731,799,800],{"class":741},"):",[731,802,803],{"class":796}," void",[731,805,806],{"class":741}," {\n",[731,808,810,813,815,818,821,824,827,829,831,834,837,840,843,845,848,851,854,856,859,861],{"class":733,"line":809},4,[731,811,812],{"class":745},"  log",[731,814,716],{"class":741},[731,816,817],{"class":782},"info",[731,819,786],{"class":820},"swJcz",[731,822,823],{"class":741},"{",[731,825,826],{"class":820}," source",[731,828,793],{"class":741},[731,830,755],{"class":741},[731,832,833],{"class":758},"mylib.client",[731,835,836],{"class":741},"'",[731,838,839],{"class":741},",",[731,841,842],{"class":820}," message",[731,844,793],{"class":741},[731,846,847],{"class":741}," `",[731,849,850],{"class":758},"GET ",[731,852,853],{"class":741},"${",[731,855,790],{"class":745},[731,857,858],{"class":741},"}`",[731,860,749],{"class":741},[731,862,863],{"class":820},")\n",[731,865,867],{"class":733,"line":866},5,[731,868,869],{"class":741},"}\n",[680,871,873],{"id":872},"attribute-wide-events-to-your-package","Attribute wide events to your package",[588,875,876,877,879,880,882],{},"When an operation deserves one wide event instead of individual messages, build it with ",[607,878,613],{}," and put the package name in a field the host can query. ",[607,881,617],{}," is a convention, not an API: pick one field name and document it in your package's README.",[721,884,886],{"className":723,"code":885,"filename":725,"language":726,"meta":727,"style":727},"import { createLogger } from 'evlog'\n\nexport function syncRecords(records: number): void {\n  const log = createLogger({ source: 'mylib', operation: 'sync-records' })\n  log.set({ records: { total: records } })\n  \u002F\u002F ...\n  log.emit()\n}\n",[607,887,888,907,911,936,981,1014,1021,1034],{"__ignoreMap":727},[731,889,890,892,894,897,899,901,903,905],{"class":733,"line":734},[731,891,738],{"class":737},[731,893,742],{"class":741},[731,895,896],{"class":745}," createLogger",[731,898,749],{"class":741},[731,900,752],{"class":737},[731,902,755],{"class":741},[731,904,759],{"class":758},[731,906,762],{"class":741},[731,908,909],{"class":733,"line":765},[731,910,769],{"emptyLinePlaceholder":768},[731,912,913,915,917,920,922,925,927,930,932,934],{"class":733,"line":772},[731,914,775],{"class":737},[731,916,779],{"class":778},[731,918,919],{"class":782}," syncRecords",[731,921,786],{"class":741},[731,923,924],{"class":789},"records",[731,926,793],{"class":741},[731,928,929],{"class":796}," number",[731,931,800],{"class":741},[731,933,803],{"class":796},[731,935,806],{"class":741},[731,937,938,941,943,946,948,950,952,954,956,958,961,963,965,968,970,972,975,977,979],{"class":733,"line":809},[731,939,940],{"class":778},"  const",[731,942,746],{"class":745},[731,944,945],{"class":741}," =",[731,947,896],{"class":782},[731,949,786],{"class":820},[731,951,823],{"class":741},[731,953,826],{"class":820},[731,955,793],{"class":741},[731,957,755],{"class":741},[731,959,960],{"class":758},"mylib",[731,962,836],{"class":741},[731,964,839],{"class":741},[731,966,967],{"class":820}," operation",[731,969,793],{"class":741},[731,971,755],{"class":741},[731,973,974],{"class":758},"sync-records",[731,976,836],{"class":741},[731,978,749],{"class":741},[731,980,863],{"class":820},[731,982,983,985,987,990,992,994,997,999,1001,1004,1006,1008,1010,1012],{"class":733,"line":866},[731,984,812],{"class":745},[731,986,716],{"class":741},[731,988,989],{"class":782},"set",[731,991,786],{"class":820},[731,993,823],{"class":741},[731,995,996],{"class":820}," records",[731,998,793],{"class":741},[731,1000,742],{"class":741},[731,1002,1003],{"class":820}," total",[731,1005,793],{"class":741},[731,1007,996],{"class":745},[731,1009,749],{"class":741},[731,1011,749],{"class":741},[731,1013,863],{"class":820},[731,1015,1017],{"class":733,"line":1016},6,[731,1018,1020],{"class":1019},"sHwdD","  \u002F\u002F ...\n",[731,1022,1024,1026,1028,1031],{"class":733,"line":1023},7,[731,1025,812],{"class":745},[731,1027,716],{"class":741},[731,1029,1030],{"class":782},"emit",[731,1032,1033],{"class":820},"()\n",[731,1035,1037],{"class":733,"line":1036},8,[731,1038,869],{"class":741},[588,1040,1041,1042,1045,1046,1048],{},"If your fields benefit from compile-time checking, type the context: ",[607,1043,1044],{},"createLogger\u003CSyncContext>()",". ",[661,1047,76],{"href":77}," covers the patterns.",[680,1050,1052],{"id":1051},"contribute-to-the-hosts-request-event","Contribute to the host's request event",[588,1054,1055],{},"Inside a host application, the framework integration already builds one wide event per request and emits it at the end of the lifecycle. A package that creates its own logger during a request forks that into two unrelated events. Instead, accept the request logger as a parameter and add your context to the event the host already owns:",[721,1057,1060],{"className":723,"code":1058,"filename":1059,"language":726,"meta":727,"style":727},"import type { AuditableLogger } from 'evlog'\n\nexport function chargePayment(log: AuditableLogger, amount: number): void {\n  log.set({ payment: { amount, provider: 'stripe' } })\n  \u002F\u002F ...\n}\n","src\u002Fcheckout.ts",[607,1061,1062,1084,1088,1120,1161,1165],{"__ignoreMap":727},[731,1063,1064,1066,1069,1071,1074,1076,1078,1080,1082],{"class":733,"line":734},[731,1065,738],{"class":737},[731,1067,1068],{"class":737}," type",[731,1070,742],{"class":741},[731,1072,1073],{"class":745}," AuditableLogger",[731,1075,749],{"class":741},[731,1077,752],{"class":737},[731,1079,755],{"class":741},[731,1081,759],{"class":758},[731,1083,762],{"class":741},[731,1085,1086],{"class":733,"line":765},[731,1087,769],{"emptyLinePlaceholder":768},[731,1089,1090,1092,1094,1097,1099,1101,1103,1105,1107,1110,1112,1114,1116,1118],{"class":733,"line":772},[731,1091,775],{"class":737},[731,1093,779],{"class":778},[731,1095,1096],{"class":782}," chargePayment",[731,1098,786],{"class":741},[731,1100,609],{"class":789},[731,1102,793],{"class":741},[731,1104,1073],{"class":796},[731,1106,839],{"class":741},[731,1108,1109],{"class":789}," amount",[731,1111,793],{"class":741},[731,1113,929],{"class":796},[731,1115,800],{"class":741},[731,1117,803],{"class":796},[731,1119,806],{"class":741},[731,1121,1122,1124,1126,1128,1130,1132,1135,1137,1139,1141,1143,1146,1148,1150,1153,1155,1157,1159],{"class":733,"line":809},[731,1123,812],{"class":745},[731,1125,716],{"class":741},[731,1127,989],{"class":782},[731,1129,786],{"class":820},[731,1131,823],{"class":741},[731,1133,1134],{"class":820}," payment",[731,1136,793],{"class":741},[731,1138,742],{"class":741},[731,1140,1109],{"class":745},[731,1142,839],{"class":741},[731,1144,1145],{"class":820}," provider",[731,1147,793],{"class":741},[731,1149,755],{"class":741},[731,1151,1152],{"class":758},"stripe",[731,1154,836],{"class":741},[731,1156,749],{"class":741},[731,1158,749],{"class":741},[731,1160,863],{"class":820},[731,1162,1163],{"class":733,"line":866},[731,1164,1020],{"class":1019},[731,1166,1167],{"class":733,"line":1016},[731,1168,869],{"class":741},[588,1170,1171,1172,1175,1176,1179,1180,1183,1184,1187,1188,1190],{},"The host resolves the request logger with ",[607,1173,1174],{},"useLogger()"," from the framework subpath it uses (",[607,1177,1178],{},"evlog\u002Fhono",", ",[607,1181,1182],{},"evlog\u002Fnext",", ...) or with the framework-native accessor, then passes it to your package. Every ",[607,1185,1186],{},"log.set()"," you call merges into the request's wide event, so the host sees the whole operation in one place. ",[661,1189,51],{"href":52}," explains the accumulation model.",[672,1192,1193,1194,1197,1198,1201,1202,1205],{"color":817,"icon":13},"Request loggers from some framework integrations also carry ",[607,1195,1196],{},"log.fork()"," for background work that needs its own event, correlated with the parent request. Integrations attach it when they run a logger storage (Hono, oRPC, Express, Fastify, NestJS, SvelteKit, React Router, Next.js, Elysia); Nitro and Nuxt do not attach it yet. A standalone ",[607,1199,1200],{},"createLogger()"," instance never has it. ",[661,1203,1204],{"href":236},"Framework Integrations"," documents what each one attaches.",[680,1207,1209],{"id":1208},"throw-errors-the-host-can-act-on","Throw errors the host can act on",[588,1211,1212,1213,1216,1217,1220],{},"Your package's failures are more useful as ",[661,1214,1215],{"href":57},"structured errors"," than as bare ",[607,1218,1219],{},"Error"," instances. Define a catalog with a prefix your package owns:",[721,1222,1225],{"className":723,"code":1223,"filename":1224,"language":726,"meta":727,"style":727},"import { defineErrorCatalog } from 'evlog'\n\nexport const errors = defineErrorCatalog('mylib', {\n  RATE_LIMITED: {\n    status: 429,\n    message: 'Too many requests',\n    why: 'The upstream provider returned HTTP 429',\n    fix: 'Retry with exponential backoff',\n  },\n})\n","src\u002Ferrors.ts",[607,1226,1227,1246,1250,1277,1286,1300,1316,1332,1348,1354],{"__ignoreMap":727},[731,1228,1229,1231,1233,1236,1238,1240,1242,1244],{"class":733,"line":734},[731,1230,738],{"class":737},[731,1232,742],{"class":741},[731,1234,1235],{"class":745}," defineErrorCatalog",[731,1237,749],{"class":741},[731,1239,752],{"class":737},[731,1241,755],{"class":741},[731,1243,759],{"class":758},[731,1245,762],{"class":741},[731,1247,1248],{"class":733,"line":765},[731,1249,769],{"emptyLinePlaceholder":768},[731,1251,1252,1254,1257,1260,1263,1265,1267,1269,1271,1273,1275],{"class":733,"line":772},[731,1253,775],{"class":737},[731,1255,1256],{"class":778}," const",[731,1258,1259],{"class":745}," errors ",[731,1261,1262],{"class":741},"=",[731,1264,1235],{"class":782},[731,1266,786],{"class":745},[731,1268,836],{"class":741},[731,1270,960],{"class":758},[731,1272,836],{"class":741},[731,1274,839],{"class":741},[731,1276,806],{"class":741},[731,1278,1279,1282,1284],{"class":733,"line":809},[731,1280,1281],{"class":820},"  RATE_LIMITED",[731,1283,793],{"class":741},[731,1285,806],{"class":741},[731,1287,1288,1291,1293,1297],{"class":733,"line":866},[731,1289,1290],{"class":820},"    status",[731,1292,793],{"class":741},[731,1294,1296],{"class":1295},"sbssI"," 429",[731,1298,1299],{"class":741},",\n",[731,1301,1302,1305,1307,1309,1312,1314],{"class":733,"line":1016},[731,1303,1304],{"class":820},"    message",[731,1306,793],{"class":741},[731,1308,755],{"class":741},[731,1310,1311],{"class":758},"Too many requests",[731,1313,836],{"class":741},[731,1315,1299],{"class":741},[731,1317,1318,1321,1323,1325,1328,1330],{"class":733,"line":1023},[731,1319,1320],{"class":820},"    why",[731,1322,793],{"class":741},[731,1324,755],{"class":741},[731,1326,1327],{"class":758},"The upstream provider returned HTTP 429",[731,1329,836],{"class":741},[731,1331,1299],{"class":741},[731,1333,1334,1337,1339,1341,1344,1346],{"class":733,"line":1036},[731,1335,1336],{"class":820},"    fix",[731,1338,793],{"class":741},[731,1340,755],{"class":741},[731,1342,1343],{"class":758},"Retry with exponential backoff",[731,1345,836],{"class":741},[731,1347,1299],{"class":741},[731,1349,1351],{"class":733,"line":1350},9,[731,1352,1353],{"class":741},"  },\n",[731,1355,1357,1360],{"class":733,"line":1356},10,[731,1358,1359],{"class":741},"}",[731,1361,863],{"class":745},[588,1363,1364,1365,1368,1369,1371,1372,1375],{},"The wire format is ",[607,1366,1367],{},"${prefix}.${KEY}",", so a host running several evlog-instrumented packages never sees two error codes collide as long as each package owns one prefix. The ",[661,1370,81],{"href":82}," page covers the packaging recipe for shipping a catalog as its own npm package, including the ",[607,1373,1374],{},"declare module 'evlog'"," augmentation block that gives your consumers autocomplete on the codes.",[680,1377,1379],{"id":1378},"what-the-host-application-controls","What the host application controls",[588,1381,1382,1383,1385],{},"Everything about where events go, which ones survive, and what gets scrubbed is decided by the application's ",[607,1384,624],{}," call. Library events pass through the same pipeline as the application's own:",[1387,1388,1389,1405],"table",{},[1390,1391,1392],"thead",{},[1393,1394,1395,1399,1402],"tr",{},[1396,1397,1398],"th",{},"Setting",[1396,1400,1401],{},"Decides",[1396,1403,1404],{},"Applies to library events",[1406,1407,1408,1426,1445,1462,1474,1486],"tbody",{},[1393,1409,1410,1416,1423],{},[1411,1412,1413],"td",{},[607,1414,1415],{},"enabled",[1411,1417,1418,1419,1422],{},"Whether anything is emitted at all. When ",[607,1420,1421],{},"false",", every emit and tagged log is a no-op.",[1411,1424,1425],{},"Yes, all of them",[1393,1427,1428,1433,1442],{},[1411,1429,1430],{},[607,1431,1432],{},"minLevel",[1411,1434,1435,1436,1438,1439,716],{},"Minimum severity for the global ",[607,1437,609],{}," API. Does not apply to ",[607,1440,1441],{},"createLogger().emit()",[1411,1443,1444],{},"Tagged logs yes, wide events no",[1393,1446,1447,1452,1459],{},[1411,1448,1449],{},[607,1450,1451],{},"sampling",[1411,1453,1454,1455,1458],{},"Head rates per level, plus ",[607,1456,1457],{},"keep"," conditions that force retention.",[1411,1460,1461],{},"Yes",[1393,1463,1464,1469,1472],{},[1411,1465,1466],{},[607,1467,1468],{},"redact",[1411,1470,1471],{},"Which fields and patterns are scrubbed before console output and drains.",[1411,1473,1461],{},[1393,1475,1476,1481,1484],{},[1411,1477,1478],{},[607,1479,1480],{},"drain",[1411,1482,1483],{},"Where events are sent.",[1411,1485,1461],{},[1393,1487,1488,1493,1496],{},[1411,1489,1490],{},[607,1491,1492],{},"silent",[1411,1494,1495],{},"Whether built-in console output is suppressed.",[1411,1497,1461],{},[588,1499,1500,1501,1503,1504,1506],{},"evlog has no category tree that routes one package's events to a different drain. Filter on what the package emits instead: the ",[607,1502,712],{}," on tagged logs, the ",[607,1505,617],{}," field on wide events, either in your drain or in whatever consumes the events downstream.",[680,1508,1510],{"id":1509},"test-the-events-your-library-emits","Test the events your library emits",[588,1512,1513],{},"Your events are part of your package's public behavior, so test them. Two ways, both relying on the fact that the test process is the host:",[588,1515,1516],{},"Collect events with a drain function in your test setup:",[721,1518,1521],{"className":723,"code":1519,"filename":1520,"language":726,"meta":727,"style":727},"import { initLogger } from 'evlog'\nimport type { DrainContext, WideEvent } from 'evlog'\n\nconst events: WideEvent[] = []\n\ninitLogger({ drain: (ctx: DrainContext) => { events.push(ctx.event) } })\n\n\u002F\u002F run the operation under test, then assert\n\u002F\u002F events[0].source === 'mylib'\n","test\u002Fevents.test.ts",[607,1522,1523,1542,1568,1572,1592,1596,1652,1656,1661],{"__ignoreMap":727},[731,1524,1525,1527,1529,1532,1534,1536,1538,1540],{"class":733,"line":734},[731,1526,738],{"class":737},[731,1528,742],{"class":741},[731,1530,1531],{"class":745}," initLogger",[731,1533,749],{"class":741},[731,1535,752],{"class":737},[731,1537,755],{"class":741},[731,1539,759],{"class":758},[731,1541,762],{"class":741},[731,1543,1544,1546,1548,1550,1553,1555,1558,1560,1562,1564,1566],{"class":733,"line":765},[731,1545,738],{"class":737},[731,1547,1068],{"class":737},[731,1549,742],{"class":741},[731,1551,1552],{"class":745}," DrainContext",[731,1554,839],{"class":741},[731,1556,1557],{"class":745}," WideEvent",[731,1559,749],{"class":741},[731,1561,752],{"class":737},[731,1563,755],{"class":741},[731,1565,759],{"class":758},[731,1567,762],{"class":741},[731,1569,1570],{"class":733,"line":772},[731,1571,769],{"emptyLinePlaceholder":768},[731,1573,1574,1577,1580,1582,1584,1587,1589],{"class":733,"line":809},[731,1575,1576],{"class":778},"const",[731,1578,1579],{"class":745}," events",[731,1581,793],{"class":741},[731,1583,1557],{"class":796},[731,1585,1586],{"class":745},"[] ",[731,1588,1262],{"class":741},[731,1590,1591],{"class":745}," []\n",[731,1593,1594],{"class":733,"line":866},[731,1595,769],{"emptyLinePlaceholder":768},[731,1597,1598,1601,1603,1605,1608,1610,1613,1616,1618,1620,1622,1625,1627,1629,1631,1634,1636,1638,1640,1643,1646,1648,1650],{"class":733,"line":1016},[731,1599,1600],{"class":782},"initLogger",[731,1602,786],{"class":745},[731,1604,823],{"class":741},[731,1606,1607],{"class":782}," drain",[731,1609,793],{"class":741},[731,1611,1612],{"class":741}," (",[731,1614,1615],{"class":789},"ctx",[731,1617,793],{"class":741},[731,1619,1552],{"class":796},[731,1621,646],{"class":741},[731,1623,1624],{"class":778}," =>",[731,1626,742],{"class":741},[731,1628,1579],{"class":745},[731,1630,716],{"class":741},[731,1632,1633],{"class":782},"push",[731,1635,786],{"class":820},[731,1637,1615],{"class":745},[731,1639,716],{"class":741},[731,1641,1642],{"class":745},"event",[731,1644,1645],{"class":820},") ",[731,1647,1359],{"class":741},[731,1649,749],{"class":741},[731,1651,863],{"class":745},[731,1653,1654],{"class":733,"line":1023},[731,1655,769],{"emptyLinePlaceholder":768},[731,1657,1658],{"class":733,"line":1036},[731,1659,1660],{"class":1019},"\u002F\u002F run the operation under test, then assert\n",[731,1662,1663],{"class":733,"line":1350},[731,1664,1665],{"class":1019},"\u002F\u002F events[0].source === 'mylib'\n",[588,1667,1668,1669,1672],{},"Or use the memory drain, which keeps events in a ring buffer you can read and clear. Draining is asynchronous: ",[607,1670,1671],{},"emit()"," hands the event to the drain without waiting for it, so give the promise a tick before reading or the buffer is still empty:",[721,1674,1676],{"className":723,"code":1675,"filename":1520,"language":726,"meta":727,"style":727},"import { createMemoryDrain, readMemoryLogs } from 'evlog\u002Fmemory'\nimport { initLogger } from 'evlog'\n\ninitLogger({ drain: createMemoryDrain({ store: 'test' }) })\n\n\u002F\u002F run the operation under test, then give the drain a tick\nawait new Promise(resolve => setTimeout(resolve, 0))\n\nconst events = readMemoryLogs({ store: 'test', filter: e => e.source === 'mylib' })\n",[607,1677,1678,1702,1720,1724,1762,1766,1771,1803,1807],{"__ignoreMap":727},[731,1679,1680,1682,1684,1687,1689,1692,1694,1696,1698,1700],{"class":733,"line":734},[731,1681,738],{"class":737},[731,1683,742],{"class":741},[731,1685,1686],{"class":745}," createMemoryDrain",[731,1688,839],{"class":741},[731,1690,1691],{"class":745}," readMemoryLogs",[731,1693,749],{"class":741},[731,1695,752],{"class":737},[731,1697,755],{"class":741},[731,1699,656],{"class":758},[731,1701,762],{"class":741},[731,1703,1704,1706,1708,1710,1712,1714,1716,1718],{"class":733,"line":765},[731,1705,738],{"class":737},[731,1707,742],{"class":741},[731,1709,1531],{"class":745},[731,1711,749],{"class":741},[731,1713,752],{"class":737},[731,1715,755],{"class":741},[731,1717,759],{"class":758},[731,1719,762],{"class":741},[731,1721,1722],{"class":733,"line":772},[731,1723,769],{"emptyLinePlaceholder":768},[731,1725,1726,1728,1730,1732,1734,1736,1738,1740,1742,1745,1747,1749,1752,1754,1756,1758,1760],{"class":733,"line":809},[731,1727,1600],{"class":782},[731,1729,786],{"class":745},[731,1731,823],{"class":741},[731,1733,1607],{"class":820},[731,1735,793],{"class":741},[731,1737,1686],{"class":782},[731,1739,786],{"class":745},[731,1741,823],{"class":741},[731,1743,1744],{"class":820}," store",[731,1746,793],{"class":741},[731,1748,755],{"class":741},[731,1750,1751],{"class":758},"test",[731,1753,836],{"class":741},[731,1755,749],{"class":741},[731,1757,1645],{"class":745},[731,1759,1359],{"class":741},[731,1761,863],{"class":745},[731,1763,1764],{"class":733,"line":866},[731,1765,769],{"emptyLinePlaceholder":768},[731,1767,1768],{"class":733,"line":1016},[731,1769,1770],{"class":1019},"\u002F\u002F run the operation under test, then give the drain a tick\n",[731,1772,1773,1776,1779,1782,1784,1787,1789,1792,1795,1797,1800],{"class":733,"line":1023},[731,1774,1775],{"class":737},"await",[731,1777,1778],{"class":741}," new",[731,1780,1781],{"class":796}," Promise",[731,1783,786],{"class":745},[731,1785,1786],{"class":789},"resolve",[731,1788,1624],{"class":778},[731,1790,1791],{"class":782}," setTimeout",[731,1793,1794],{"class":745},"(resolve",[731,1796,839],{"class":741},[731,1798,1799],{"class":1295}," 0",[731,1801,1802],{"class":745},"))\n",[731,1804,1805],{"class":733,"line":1036},[731,1806,769],{"emptyLinePlaceholder":768},[731,1808,1809,1811,1814,1816,1818,1820,1822,1824,1826,1828,1830,1832,1834,1837,1839,1842,1844,1846,1848,1851,1854,1856,1858,1860,1862],{"class":733,"line":1350},[731,1810,1576],{"class":778},[731,1812,1813],{"class":745}," events ",[731,1815,1262],{"class":741},[731,1817,1691],{"class":782},[731,1819,786],{"class":745},[731,1821,823],{"class":741},[731,1823,1744],{"class":820},[731,1825,793],{"class":741},[731,1827,755],{"class":741},[731,1829,1751],{"class":758},[731,1831,836],{"class":741},[731,1833,839],{"class":741},[731,1835,1836],{"class":782}," filter",[731,1838,793],{"class":741},[731,1840,1841],{"class":789}," e",[731,1843,1624],{"class":778},[731,1845,1841],{"class":745},[731,1847,716],{"class":741},[731,1849,1850],{"class":745},"source ",[731,1852,1853],{"class":741},"===",[731,1855,755],{"class":741},[731,1857,960],{"class":758},[731,1859,836],{"class":741},[731,1861,749],{"class":741},[731,1863,863],{"class":745},[588,1865,1866,1867,1869,1870,1045,1873,1875],{},"For catalog errors, compare on the factory's ",[607,1868,607],{}," property rather than a string literal, so a rename becomes a TypeScript error: ",[607,1871,1872],{},"expect(err.code).toBe(errors.RATE_LIMITED.code)",[661,1874,66],{"href":67}," covers what the host's sampling configuration can do to events, including dropping them entirely.",[680,1877,1879],{"id":1878},"where-to-go-next","Where to go next",[588,1881,1882,1883,1886,1887,610,1890,1893],{},"If your package wraps a framework instead of running inside one, ",[661,1884,1885],{"href":464},"Extend Overview"," maps the extension points: custom drains, enrichers, and plugins follow the same emit-only contract. To debug a host application that uses your package, the host's ",[661,1888,1889],{"href":469},"stream",[661,1891,1892],{"href":479},"diagnostics channel"," let you subscribe to every event in the process, including yours.",[1895,1896,1897],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":727,"searchDepth":765,"depth":765,"links":1899},[1900,1901,1902,1903,1904,1905,1906],{"id":682,"depth":765,"text":683},{"id":872,"depth":765,"text":873},{"id":1051,"depth":765,"text":1052},{"id":1208,"depth":765,"text":1209},{"id":1378,"depth":765,"text":1379},{"id":1509,"depth":765,"text":1510},{"id":1878,"depth":765,"text":1879},"Ship evlog inside a reusable package: attribute your events, throw catalog errors, and leave drains and sampling to the host application.","md",[1910,1914],{"label":1911,"icon":79,"to":301,"color":1912,"variant":1913},"Standalone TypeScript","neutral","subtle",{"label":1915,"icon":84,"to":82,"color":1912,"variant":1913},"Error Catalogs",{},{"title":454,"icon":457},{"title":583,"description":1907},"PwmYQfilt9OOoZKmqTqAK6vHRe-z2smhw-GY9rK2J5A",[1921,1923],{"title":450,"path":451,"stem":452,"description":1922,"icon":434,"children":-1},"Build a Node.js HTTP handler with structured request logs, explicit outcomes, error context, and a JSON event you can query.",{"title":41,"path":464,"stem":465,"description":1924,"icon":466,"children":-1},"Observe what flows through the pipeline, plug into it, or build your own bricks. The map of every extension point evlog exposes.",1789074370874]