@stacksjs/logging 0.73.2 → 0.73.3
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/dist/index.d.ts +21 -3
- package/dist/index.js +9 -9
- package/package.json +8 -7
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Logger } from '@stacksjs/clarity';
|
|
1
2
|
import type { LogContext, LogLevel, LogRecord, LogTransport } from '@stacksjs/types';
|
|
2
3
|
// Request context propagation for structured logging, and the transport
|
|
3
4
|
// contract. Both are declared in `@stacksjs/types` so `config/logging.ts` can
|
|
@@ -25,6 +26,20 @@ export declare function transports(): readonly LogTransport[];
|
|
|
25
26
|
* for clarity's `warning`.
|
|
26
27
|
*/
|
|
27
28
|
export declare function parseLogLevel(raw: string | undefined, fallback?: LogLevel): LogLevel;
|
|
29
|
+
/**
|
|
30
|
+
* The level in force right now, at the same precedence the logger itself was
|
|
31
|
+
* built with: **env var > config file > default**.
|
|
32
|
+
*
|
|
33
|
+
* Exists because the synchronous fast paths need an answer without awaiting
|
|
34
|
+
* the logger, and the env var is the only part of that answer available
|
|
35
|
+
* synchronously. The config half arrives later and is filled in by the
|
|
36
|
+
* refresh; until then this reports what the logger is actually doing.
|
|
37
|
+
*
|
|
38
|
+
* Env is re-read per call rather than snapshotted: `LOG_LEVEL` is routinely
|
|
39
|
+
* set from inside a process (tests, `buddy` subcommands) after this module has
|
|
40
|
+
* loaded, and a snapshot would ignore it.
|
|
41
|
+
*/
|
|
42
|
+
export declare function currentLevel(): LogLevel;
|
|
28
43
|
/** Parse + validate `LOG_FORMAT`; defaults to json in prod, text in dev. */
|
|
29
44
|
export declare function parseLogFormat(raw: string | undefined): LogFormat;
|
|
30
45
|
/**
|
|
@@ -70,7 +85,12 @@ export declare function withLogContext<T>(context: LogContext, fn: () => T): T;
|
|
|
70
85
|
* ambient one.
|
|
71
86
|
*/
|
|
72
87
|
export declare function getLogContext(): LogContext | undefined;
|
|
73
|
-
|
|
88
|
+
/*.ts` file,
|
|
89
|
+
* or from a module one of them imports at evaluation time: it waits on the
|
|
90
|
+
* very load those files are part of. The `log.*` methods have no such
|
|
91
|
+
* restriction - they never wait on config - and are what that code wants.
|
|
92
|
+
*/
|
|
93
|
+
export declare function logger(): Promise<Logger>;
|
|
74
94
|
// Helper function to format message for logging, including request context.
|
|
75
95
|
// Exported for direct unit testing of arg handling (stacksjs/stacks#2047).
|
|
76
96
|
export declare function formatMessage(...args: unknown[]): string;
|
|
@@ -212,5 +232,3 @@ export declare interface ReportOptions {
|
|
|
212
232
|
declare interface StructuredFields { [key: string]: unknown }
|
|
213
233
|
export type LogFormat = 'json' | 'text';
|
|
214
234
|
export type ErrorMessage = string;
|
|
215
|
-
// Export logger getter for debugging
|
|
216
|
-
export { getLogger as logger };
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var
|
|
3
|
-
`),null;if(typeof
|
|
4
|
-
`),null;return u.push(
|
|
5
|
-
`)}}}}async function
|
|
6
|
-
`),
|
|
7
|
-
`);return s.env.NODE_ENV==="production"?"json":"text"}function
|
|
8
|
-
caused by: ${
|
|
2
|
+
var d=import.meta.require;import{AsyncLocalStorage as M}from"async_hooks";import s from"process";import{Logger as A}from"@stacksjs/clarity";import{handleError as J}from"@stacksjs/error-handling";import{ExitCode as v}from"@stacksjs/types";var c=null,f=null,b=new Set;function O(e){return b.add(e),e.finally(()=>b.delete(e)).catch(()=>{}),e}var R=!1;function Y(){if(R)return;R=!0,s.on("beforeExit",()=>{g.flush()})}var u=[],_=new Set,j={debug:0,info:1,success:1,warning:2,error:3};function z(e){let n=e;if(!n||typeof n!=="object"||typeof n.log!=="function")return s.stderr.write(`[logging] Ignoring a transport without a log() function.
|
|
3
|
+
`),null;if(typeof n.name!=="string"||!n.name)return s.stderr.write(`[logging] Ignoring a transport without a name.
|
|
4
|
+
`),null;return u.push(n),()=>{let t=u.indexOf(n);if(t!==-1)u.splice(t,1)}}function le(e){let n=z(e);if(!n)return()=>{};return E(),n}function fe(){return[...u]}function l(e,n,t){if(u.length===0)return;let o;try{o={level:e,message:n,args:t,context:T(),timestamp:new Date().toISOString()}}catch{return}for(let r of u){if(r.level&&j[e]<j[r.level])continue;try{r.log(o)}catch(i){if(!_.has(r.name)){_.add(r.name);let L=i instanceof Error?i.message:String(i);s.stderr.write(`[logging] Transport "${r.name}" threw: ${L}. Further throws from it are silent.
|
|
5
|
+
`)}}}}async function B(){let e=u.filter((n)=>typeof n.flush==="function").map((n)=>n.flush().catch(()=>{}));if(e.length>0)await Promise.allSettled(e)}var N=new Set(["debug","info","success","warning","error"]);function x(e,n="info"){if(!e)return n;let t=e.toLowerCase();if(t==="warn")return"warning";if(N.has(t))return t;return s.stderr.write(`[logging] Ignoring invalid LOG_LEVEL="${e}" (expected: ${[...N].join(", ")}); using "${n}".
|
|
6
|
+
`),n}var P,D,I;function K(){let e=s.env.LOG_LEVEL;if(e){if(e!==D)D=e,I=x(e);return I}return P??"info"}function U(e){if(e==="json"||e==="text")return e;if(e)s.stderr.write(`[logging] Ignoring invalid LOG_FORMAT="${e}" (expected "json" or "text").
|
|
7
|
+
`);return s.env.NODE_ENV==="production"?"json":"text"}function H(e){let n=e.envLevel?x(e.envLevel):e.cfgLevel?x(e.cfgLevel):"info",t=e.envFormat?U(e.envFormat):e.cfgFormat==="json"||e.cfgFormat==="text"?e.cfgFormat:e.isProduction?"json":"text";return{level:n,format:t,writeToFile:e.cfgWriteToFile??!0}}function w(e,n=0){if(n>8)return{name:"Error",message:"[cause chain truncated]"};if(e instanceof Error)return{name:e.name,message:e.message,stack:e.stack,cause:e.cause!=null?w(e.cause,n+1):void 0};if(typeof e==="string")return{name:"Error",message:e};if(e==null)return{name:"Error",message:String(e)};try{return{name:"Error",message:JSON.stringify(y(e))}}catch{return{name:"Error",message:String(e)}}}function S(e){let n=e.stack||`${e.name}: ${e.message}`,t=e.cause;while(t)n+=`
|
|
8
|
+
caused by: ${t.stack||`${t.name}: ${t.message}`}`,t=t.cause;return n}function y(e,n=0){if(e instanceof Error)return w(e);if(n>=4||e===null||typeof e!=="object")return e;if(Array.isArray(e))return e.map((r)=>y(r,n+1));let t=Object.getPrototypeOf(e);if(t!==Object.prototype&&t!==null)return e;let o={};for(let[r,i]of Object.entries(e))o[r]=y(i,n+1);return o}function q(e){return y(e)}var F=new M;function de(e,n){return F.run(e,n)}function T(){let e=F.getStore(),n=Q();if(!n)return e;return{trace_id:n,...e}}function Q(){try{let n=globalThis[Symbol.for("stacks.router.traceStorage")]?.getStore?.();if(n)return n;return globalThis[Symbol.for("stacks.router.requestStorage")]?.getStore?.()?._requestId}catch{return}}var X=Symbol.for("@stacksjs/config:overridesReady"),k=null;async function Z(){try{return(await import("@stacksjs/config")).logging??null}catch{return null}}function ee(){let e=globalThis[X];if(!e||typeof e.then!=="function")return null;return e}async function V(e,n){let{level:t,format:o,writeToFile:r}=H({envLevel:s.env.LOG_LEVEL,envFormat:s.env.LOG_FORMAT,cfgLevel:e?.level,cfgFormat:e?.format,cfgWriteToFile:typeof e?.writeToFile==="boolean"?e.writeToFile:void 0,isProduction:s.env.NODE_ENV==="production"}),i;if(e?.logsPath)i=(await import("path")).dirname(e.logsPath);if(!i)i=n;if(!i)try{i=(await import("@stacksjs/path")).projectPath("storage/logs")}catch{i="storage/logs"}return{level:t,format:o,writeToFile:r,logDirectory:i}}function W(e){if(!Array.isArray(e?.transports))return;for(let n of e.transports)if(!u.includes(n))z(n)}var h=null;function C(){if(h)return;let e=ee();if(!e)return;h=e.then(async(n)=>{let t=n?.logging;if(!t)return;if(W(t),t.level)P=x(t.level);let o=k;if(!o||!c)return;let r=await V(t,o.logDirectory);if(o.level===r.level&&o.format===r.format&&o.writeToFile===r.writeToFile&&o.logDirectory===r.logDirectory)return;let i=c;c=new A("stacks",{level:r.level,logDirectory:r.logDirectory,showTags:!1,fancy:r.format!=="json",format:r.format,writeToFile:r.writeToFile}),k=r;try{await i.flush?.(),await i.destroy?.()}catch{}}).catch(()=>{})}async function E(){if(c)return;if(f)return f;return Y(),f=(async()=>{let e=await Z();if(W(e),e?.level)P=x(e.level);let n=await V(e);c=new A("stacks",{level:n.level,logDirectory:n.logDirectory,showTags:!1,fancy:n.format!=="json",format:n.format,writeToFile:n.writeToFile}),k=n})(),f.then(C),f}async function a(){return await E(),c}async function me(){if(await E(),C(),h)await h;return c}function m(...e){let n=e.filter((o)=>o!==void 0).map((o)=>{if(o instanceof Error)return S(w(o));if(typeof o==="object"&&o!==null)return JSON.stringify(y(o),null,2);return String(o)}).join(" "),t=F.getStore();if(t?.requestId)return`[${t.requestId}] ${n}`;return n}var ne=new Set(["shouldExit","silent","message"]);function te(e){if(!e||typeof e!=="object"||e instanceof Error)return!1;if(!(("shouldExit"in e)||("silent"in e)))return!1;return Object.keys(e).every((n)=>ne.has(n))}var g={info:async(...e)=>{let n=m(...e),t=await a();l("info",n,e),await t.info(n)},success:async(e)=>{let n=await a();l("success",e,[e]),await n.success(e)},warn:async(e,n)=>{let t=await a();if(l("warning",e,n===void 0?[e]:[e,n]),n==null){await t.warn(e);return}let o=y(n);await t.warn(e,o)},warning:async(e)=>{let n=await a();l("warning",e,[e]),await n.warn(e)},error:async(e,n,t)=>{let o=te(n)?n:void 0,r;if(typeof e==="string")r=e;else r=S(w(e));if(n!==void 0&&!o)r=`${r} ${S(w(n))}`;let i={...T(),...t};if(Object.keys(i).length>0)try{r=`${r} ${JSON.stringify(q(i))}`}catch{}let L=await a();if(l("error",r,o?[e]:[e,n,t].filter((G)=>G!==void 0)),await L.error(r),o?.shouldExit)J(e,o)},debug:async(...e)=>{let n=K()!=="debug";if(n&&u.length===0){if(!c&&!f)E();else if(!h)C();return}let t=m(...e);if(n){l("debug",t,e);return}let o=await a();l("debug",t,e),await o.debug(t)},dump:async(...e)=>{let n=m(...e);await(await a()).debug(`DUMP: ${n}`)},dd:async(...e)=>{let n=m(...e);await(await a()).error(n),s.exit(v.FatalError)},echo:async(...e)=>{let n=m(...e);await(await a()).info(`ECHO: ${n}`)},time:(e)=>{let n=performance.now();return async(t)=>{let o=performance.now()-n,r=await a(),i=t?` ${JSON.stringify(q(t))}`:"";await r.info(`${e}: ${o.toFixed(2)}ms${i}`)}},syncWarn:(e)=>{s.stderr.write(`${e}
|
|
9
9
|
`)},syncError:(e)=>{s.stderr.write(`${e}
|
|
10
|
-
`)},fatal:(e,
|
|
11
|
-
`),s.exit(
|
|
10
|
+
`)},fatal:(e,n=v.FatalError)=>{s.stderr.write(`${e}
|
|
11
|
+
`),s.exit(n)},exit:async(e,n=v.Success)=>{if(e)await(n===v.Success?g.success(e):g.error(e));await g.flush(),s.exit(n)},flush:async()=>{if(b.size>0)await Promise.allSettled([...b]);if(await B(),!c&&!f)return;try{let e=await a(),n=e.flush;if(typeof n==="function")await n.call(e)}catch{}}};async function we(...e){for(let n of e)await g.debug(n)}async function ye(...e){let n=m(...e);console.log(n),s.exit(v.FatalError)}async function Le(...e){await g.debug(...e)}function re(e){if(e&&typeof e==="object"){let n=e;if(typeof n.status==="number")return n.status;if(typeof n.statusCode==="number")return n.statusCode}return}function pe(e,n={}){let t=n.status??re(e),o=typeof t==="number"&&t>=400&&t<500,r=n.label??"Unhandled error",i={...n.context,...t!=null?{status:t}:{}};if(o){g.debug(`${r} (client error ${t}): ${w(e).message}`);return}g.error(r,e,i)}function p(e,n,t){let o=T(),r={event:n,traceId:o?.requestId,...t};if(e==="warn")O(g.warn(`[${n}]`,r));else O(g[e](r))}var oe={request(e,n,t,o,r={}){let i=t>=500?"error":t>=400?"warn":"info";p(i,"http.request",{method:e,path:n,status:t,durationMs:o,...r})},query(e,n,t={}){p("debug","db.query",{sql:e,durationMs:n,...t})},slowQuery(e,n,t={}){p("warn","db.slow_query",{sql:e,durationMs:n,...t})},job(e,n,t={}){p(n==="failed"?"error":"info",`job.${n}`,{jobName:e,...t})},cache(e,n,t={}){p("debug",`cache.${e}`,{key:n,...t})}};g.struct=oe;export{K as currentLevel,ye as dd,we as dump,Le as echo,m as formatMessage,T as getLogContext,g as log,me as logger,q as normalizeContext,w as normalizeError,U as parseLogFormat,x as parseLogLevel,le as registerTransport,S as renderNormalizedError,pe as report,H as resolveLogSettings,oe as struct,fe as transports,de as withLogContext};
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/logging",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.73.
|
|
5
|
+
"version": "0.73.3",
|
|
6
6
|
"description": "The Stacks logging system.",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -58,15 +58,16 @@
|
|
|
58
58
|
"prepublishOnly": "bun run build"
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
+
"@loghq/stacks": "^0.2.3",
|
|
61
62
|
"@stacksjs/clarity": "^0.3.33"
|
|
62
63
|
},
|
|
63
64
|
"devDependencies": {
|
|
64
|
-
"@stacksjs/cli": "0.73.
|
|
65
|
-
"@stacksjs/config": "0.73.
|
|
66
|
-
"@stacksjs/error-handling": "0.73.
|
|
67
|
-
"@stacksjs/path": "0.73.
|
|
68
|
-
"@stacksjs/storage": "0.73.
|
|
69
|
-
"@stacksjs/validation": "0.73.
|
|
65
|
+
"@stacksjs/cli": "0.73.3",
|
|
66
|
+
"@stacksjs/config": "0.73.3",
|
|
67
|
+
"@stacksjs/error-handling": "0.73.3",
|
|
68
|
+
"@stacksjs/path": "0.73.3",
|
|
69
|
+
"@stacksjs/storage": "0.73.3",
|
|
70
|
+
"@stacksjs/validation": "0.73.3",
|
|
70
71
|
"better-dx": "^0.2.24"
|
|
71
72
|
}
|
|
72
73
|
}
|