jsonl-logger 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -23,10 +23,11 @@ npm install jsonl-logger
23
23
  import { logger } from 'jsonl-logger'
24
24
 
25
25
  logger.info('Server started', { port: 3000 })
26
+ logger.log('Neutral message', { note: 'no level icon' })
26
27
  logger.error('Request failed', { path: '/api' }, new Error('timeout'))
27
28
  ```
28
29
 
29
- Without `LOG_FORMAT`, the logger outputs colored plain text — ideal for local development. Set `LOG_FORMAT` to enable structured JSON for production (see Formatters below).
30
+ Without `LOG_FORMAT`, the logger outputs colored plain text with Unicode icons — ideal for local development. Set `LOG_FORMAT` to enable structured JSON for production (see Formatters below).
30
31
 
31
32
  ## Formatters
32
33
 
@@ -191,7 +192,7 @@ logger.error('API call failed', { endpoint: '/users' }, outer)
191
192
 
192
193
  **Dev mode** (no `LOG_FORMAT`) — colored plain text with full stack:
193
194
  ```
194
- 18:42:05 ERROR API call failed {"endpoint":"/users"}
195
+ 18:42:05 API call failed {"endpoint":"/users"}
195
196
  Error: fetch failed
196
197
  at handler (/app/api/route.ts:42:5)
197
198
  Caused by: Error: ECONNREFUSED
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ErrorInfo, LogContext, LoggerOptions } from './types';
2
- export type { ErrorInfo, Formatter, FormatterName, InterceptOptions, LogContext, LoggerOptions, LogLevel, LogRecord, TraceContext, } from './types';
2
+ export type { ErrorInfo, Formatter, FormatterName, InterceptOptions, LabelStyle, LogContext, LoggerOptions, LogLevel, LogRecord, TraceContext, } from './types';
3
3
  export { logLevelValues, stripAnsi } from './types';
4
4
  export declare function errorInfo(err: Error): ErrorInfo;
5
5
  export declare class Logger {
@@ -7,11 +7,13 @@ export declare class Logger {
7
7
  private min;
8
8
  private json;
9
9
  private fmt;
10
+ private labels;
10
11
  private tc?;
11
12
  constructor(context?: LogContext, options?: LoggerOptions);
12
13
  child(context: LogContext): Logger;
13
- private log;
14
+ private emit;
14
15
  private logPlain;
16
+ log(message: string, meta?: LogContext): void;
15
17
  debug(message: string, meta?: LogContext): void;
16
18
  info(message: string, meta?: LogContext): void;
17
19
  warn(message: string, meta?: LogContext): void;
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- var k={debug:"DEBUG",info:"INFO",warn:"WARNING",error:"ERROR",fatal:"CRITICAL"},f={messageKey:"message",format(t){let o={message:t.message,timestamp:t.timestamp,severity:k[t.level],...t.context};if(t.trace){if(o["logging.googleapis.com/trace"]=t.trace.traceId,o["logging.googleapis.com/spanId"]=t.trace.spanId,t.trace.traceFlags!==void 0)o["logging.googleapis.com/trace_sampled"]=(t.trace.traceFlags&1)===1}return o}};var d={messageKey:"_msg",format(t){let o={_msg:t.message,_time:t.timestamp,level:t.level,...t.context};if(t.trace){if(o.trace_id=t.trace.traceId,o.span_id=t.trace.spanId,t.trace.traceFlags!==void 0)o.trace_flags=t.trace.traceFlags}return o}};var i=process.env.LOG_FORMAT,C=!!i,a={debug:0,info:1,warn:2,error:3,fatal:4},$=/\x1b\[[0-9;]*m/g;function u(t){return t.replace($,"")}function p(t,o,e="error"){if(t[`${e}.name`]=o.name,t[`${e}.message`]=o.message,o.stack)t[`${e}.stack`]=o.stack;if(o.cause)p(t,o.cause,`${e}.cause`)}var L=typeof process<"u"&&process.stdout&&typeof process.stdout.write==="function"?"node":typeof Deno<"u"&&Deno.stdout?"deno":"browser",x=L==="deno"?new TextEncoder:null;function R(t,o){if(L==="node")(o?process.stderr??process.stdout:process.stdout).write(`${t}
2
- `);else if(L==="deno"&&x){let e=x.encode(`${t}
3
- `);if(o)Deno.stderr.writeSync(e);else Deno.stdout.writeSync(e)}else if(o)console.error(t);else console.log(t)}var E={"google-cloud-logging":f,"victoria-logs":d},O=i&&E[i]||f,w=C,S=process.env.LOG_LEVEL||(w?"info":"debug"),y={debug:!1,info:!1,warn:!1,error:!0,fatal:!0};function b(t,o){return o.add(t),{name:t.name,message:t.message,stack:t.stack,...t.cause instanceof Error&&!o.has(t.cause)?{cause:b(t.cause,o)}:{}}}function j(t){return b(t,new WeakSet)}class h{ctx;min;json;fmt;tc;constructor(t,o){this.ctx=t||{},this.json=o?.json??w,this.fmt=o?.formatter??O,this.tc=o?.traceContext;let e=o?.level??S;this.min=a[e]??a.info}child(t){let o=new h({...this.ctx,...t},{json:this.json,formatter:this.fmt,traceContext:this.tc});return o.min=this.min,o}log(t,o,e,c){if(a[t]<this.min)return;let s={level:t,message:this.json?u(o).trim():o,timestamp:new Date().toISOString(),context:e?{...this.ctx,...e}:this.ctx};if(this.tc)s.trace=this.tc();if(c)s.error=j(c);if(this.json){let g=this.fmt.format(s);if(s.error)p(g,s.error);R(JSON.stringify(g),y[t])}else this.logPlain(t,s)}logPlain(t,o){let e={debug:"\x1B[36m",info:"\x1B[32m",warn:"\x1B[33m",error:"\x1B[31m",fatal:"\x1B[35m"},c="\x1B[0m",s=e[t],g=new Date(o.timestamp).toLocaleTimeString("en-US",{hour12:!1}),I=t.toUpperCase().padEnd(5),v=o.context,F=Object.keys(v).length>0?` ${JSON.stringify(v)}`:"",m="";if(o.error){let n=o.error,l=!0;while(n){if(n.stack)m+=l?`
4
- ${n.stack}`:`
5
- Caused by: ${n.stack}`;else m+=l?`
6
- ${n.name}: ${n.message}`:`
7
- Caused by: ${n.name}: ${n.message}`;n=n.cause,l=!1}}let r=`${s}${g} ${I}\x1B[0m ${o.message}${F}${m}`;switch(t){case"debug":console.debug(r);break;case"warn":console.warn(r);break;case"error":case"fatal":console.error(r);break;default:console.log(r)}}debug(t,o){this.log("debug",t,o)}info(t,o){this.log("info",t,o)}warn(t,o){this.log("warn",t,o)}error(t,o,e){this.log("error",t,o,e)}fatal(t,o,e){this.log("fatal",t,o,e)}}var J=new h;export{u as stripAnsi,J as logger,a as logLevelValues,j as errorInfo,h as Logger};
1
+ var y={debug:"DEBUG",info:"INFO",warn:"WARNING",error:"ERROR",fatal:"CRITICAL"},L={messageKey:"message",format(t){let e={message:t.message,timestamp:t.timestamp,severity:y[t.level],...t.context};if(t.trace){if(e["logging.googleapis.com/trace"]=t.trace.traceId,e["logging.googleapis.com/spanId"]=t.trace.spanId,t.trace.traceFlags!==void 0)e["logging.googleapis.com/trace_sampled"]=(t.trace.traceFlags&1)===1}return e}};var x={messageKey:"_msg",format(t){let e={_msg:t.message,_time:t.timestamp,level:t.level,...t.context};if(t.trace){if(e.trace_id=t.trace.traceId,e.span_id=t.trace.spanId,t.trace.traceFlags!==void 0)e.trace_flags=t.trace.traceFlags}return e}};var R=process.env.LOG_LABELS==="text"?"text":process.env.LOG_LABELS==="none"?"none":"icon",c=process.env.LOG_FORMAT,w=!!c,a={debug:0,info:1,warn:2,error:3,fatal:4},S=/\x1b\[[0-9;]*m/g;function p(t){return t.replace(S,"")}function d(t,e,o="error"){if(t[`${o}.name`]=e.name,t[`${o}.message`]=e.message,e.stack)t[`${o}.stack`]=e.stack;if(e.cause)d(t,e.cause,`${o}.cause`)}var u=typeof process<"u"&&process.stdout&&typeof process.stdout.write==="function"?"node":typeof Deno<"u"&&Deno.stdout?"deno":"browser",C=u==="deno"?new TextEncoder:null;function I(t,e){if(u==="node")(e?process.stderr??process.stdout:process.stdout).write(`${t}
2
+ `);else if(u==="deno"&&C){let o=C.encode(`${t}
3
+ `);if(e)Deno.stderr.writeSync(o);else Deno.stdout.writeSync(o)}else if(e)console.error(t);else console.log(t)}var E={"google-cloud-logging":L,"victoria-logs":x},O=c&&E[c]||L,F=w,j=process.env.LOG_LEVEL||(F?"info":"debug"),N={debug:!1,info:!1,warn:!1,error:!0,fatal:!0};function $(t,e){return e.add(t),{name:t.name,message:t.message,stack:t.stack,...t.cause instanceof Error&&!e.has(t.cause)?{cause:$(t.cause,e)}:{}}}function _(t){return $(t,new WeakSet)}var G={debug:"◆",info:"●",warn:"▲",error:"✖",fatal:"‼"};class h{ctx;min;json;fmt;labels;tc;constructor(t,e){this.ctx=t||{},this.json=e?.json??F,this.fmt=e?.formatter??O,this.labels=e?.labels??R,this.tc=e?.traceContext;let o=e?.level??j;this.min=a[o]??a.info}child(t){let e=new h({...this.ctx,...t},{json:this.json,formatter:this.fmt,labels:this.labels,traceContext:this.tc});return e.min=this.min,e}emit(t,e,o,i,b){if(a[t]<this.min)return;let n={level:t,message:this.json?p(e).trim():e,timestamp:new Date().toISOString(),context:o?{...this.ctx,...o}:this.ctx};if(this.tc)n.trace=this.tc();if(i)n.error=_(i);if(this.json){let g=this.fmt.format(n);if(n.error)d(g,n.error);I(JSON.stringify(g),N[t])}else this.logPlain(t,n,b)}logPlain(t,e,o){let i={debug:"\x1B[36m",info:"\x1B[32m",warn:"\x1B[33m",error:"\x1B[31m",fatal:"\x1B[35m"},b="\x1B[0m",n=i[t],g=new Date(e.timestamp).toLocaleTimeString("en-US",{hour12:!1}),r;if(this.labels==="none")r="";else if(this.labels==="text")r=o?" ":` ${t.toUpperCase().padEnd(5)}`;else r=o?" ":` ${G[t]}`;let v=e.context,k=Object.keys(v).length>0?` ${JSON.stringify(v)}`:"",m="";if(e.error){let s=e.error,f=!0;while(s){if(s.stack)m+=f?`
4
+ ${s.stack}`:`
5
+ Caused by: ${s.stack}`;else m+=f?`
6
+ ${s.name}: ${s.message}`:`
7
+ Caused by: ${s.name}: ${s.message}`;s=s.cause,f=!1}}let l=`${n}${g}${r}\x1B[0m ${e.message}${k}${m}`;switch(t){case"debug":console.debug(l);break;case"warn":console.warn(l);break;case"error":case"fatal":console.error(l);break;default:console.log(l)}}log(t,e){this.emit("info",t,e,void 0,!0)}debug(t,e){this.emit("debug",t,e)}info(t,e){this.emit("info",t,e)}warn(t,e){this.emit("warn",t,e)}error(t,e,o){this.emit("error",t,e,o)}fatal(t,e,o){this.emit("fatal",t,e,o)}}var K=new h;export{p as stripAnsi,K as logger,a as logLevelValues,_ as errorInfo,h as Logger};
package/dist/intercept.js CHANGED
@@ -1,7 +1,7 @@
1
- var j={debug:"DEBUG",info:"INFO",warn:"WARNING",error:"ERROR",fatal:"CRITICAL"},u={messageKey:"message",format(t){let o={message:t.message,timestamp:t.timestamp,severity:j[t.level],...t.context};if(t.trace){if(o["logging.googleapis.com/trace"]=t.trace.traceId,o["logging.googleapis.com/spanId"]=t.trace.spanId,t.trace.traceFlags!==void 0)o["logging.googleapis.com/trace_sampled"]=(t.trace.traceFlags&1)===1}return o}};var w={messageKey:"_msg",format(t){let o={_msg:t.message,_time:t.timestamp,level:t.level,...t.context};if(t.trace){if(o.trace_id=t.trace.traceId,o.span_id=t.trace.spanId,t.trace.traceFlags!==void 0)o.trace_flags=t.trace.traceFlags}return o}};var x=process.env.LOG_FORMAT,$=!!x,m={debug:0,info:1,warn:2,error:3,fatal:4},_=/\x1b\[[0-9;]*m/g;function h(t){return t.replace(_,"")}function p(t,o,n="error"){if(t[`${n}.name`]=o.name,t[`${n}.message`]=o.message,o.stack)t[`${n}.stack`]=o.stack;if(o.cause)p(t,o.cause,`${n}.cause`)}var b=typeof process<"u"&&process.stdout&&typeof process.stdout.write==="function"?"node":typeof Deno<"u"&&Deno.stdout?"deno":"browser",k=b==="deno"?new TextEncoder:null;function l(t,o){if(b==="node")(o?process.stderr??process.stdout:process.stdout).write(`${t}
2
- `);else if(b==="deno"&&k){let n=k.encode(`${t}
3
- `);if(o)Deno.stderr.writeSync(n);else Deno.stdout.writeSync(n)}else if(o)console.error(t);else console.log(t)}var E={"google-cloud-logging":u,"victoria-logs":w},N=x&&E[x]||u,v=$,T=process.env.LOG_LEVEL||(v?"info":"debug"),y={debug:!1,info:!1,warn:!1,error:!0,fatal:!0};function d(t,o){return o.add(t),{name:t.name,message:t.message,stack:t.stack,...t.cause instanceof Error&&!o.has(t.cause)?{cause:d(t.cause,o)}:{}}}function F(t){return d(t,new WeakSet)}class I{ctx;min;json;fmt;tc;constructor(t,o){this.ctx=t||{},this.json=o?.json??v,this.fmt=o?.formatter??N,this.tc=o?.traceContext;let n=o?.level??T;this.min=m[n]??m.info}child(t){let o=new I({...this.ctx,...t},{json:this.json,formatter:this.fmt,traceContext:this.tc});return o.min=this.min,o}log(t,o,n,e){if(m[t]<this.min)return;let c={level:t,message:this.json?h(o).trim():o,timestamp:new Date().toISOString(),context:n?{...this.ctx,...n}:this.ctx};if(this.tc)c.trace=this.tc();if(e)c.error=F(e);if(this.json){let a=this.fmt.format(c);if(c.error)p(a,c.error);l(JSON.stringify(a),y[t])}else this.logPlain(t,c)}logPlain(t,o){let n={debug:"\x1B[36m",info:"\x1B[32m",warn:"\x1B[33m",error:"\x1B[31m",fatal:"\x1B[35m"},e="\x1B[0m",c=n[t],a=new Date(o.timestamp).toLocaleTimeString("en-US",{hour12:!1}),i=t.toUpperCase().padEnd(5),L=o.context,R=Object.keys(L).length>0?` ${JSON.stringify(L)}`:"",f="";if(o.error){let s=o.error,C=!0;while(s){if(s.stack)f+=C?`
4
- ${s.stack}`:`
5
- Caused by: ${s.stack}`;else f+=C?`
6
- ${s.name}: ${s.message}`:`
7
- Caused by: ${s.name}: ${s.message}`;s=s.cause,C=!1}}let g=`${c}${a} ${i}\x1B[0m ${o.message}${R}${f}`;switch(t){case"debug":console.debug(g);break;case"warn":console.warn(g);break;case"error":case"fatal":console.error(g);break;default:console.log(g)}}debug(t,o){this.log("debug",t,o)}info(t,o){this.log("info",t,o)}warn(t,o){this.log("warn",t,o)}error(t,o,n){this.log("error",t,o,n)}fatal(t,o,n){this.log("fatal",t,o,n)}}var H=new I;var D={log:console.log.bind(console),info:console.info.bind(console),warn:console.warn.bind(console),error:console.error.bind(console),debug:console.debug.bind(console)};function G(...t){let o="";for(let n=0;n<t.length;n++){if(n>0)o+=" ";let e=t[n];if(typeof e==="string")o+=h(e);else if(e instanceof Error)o+=e.message;else try{o+=JSON.stringify(e)}catch{o+=String(e)}}return o.trim()}function A(...t){let o;for(let n of t)if(typeof n==="object"&&n!==null&&!(n instanceof Error)&&!Array.isArray(n)){if(!o)o={};Object.assign(o,n)}return o}function J(...t){for(let o of t)if(o instanceof Error)return o}var O={debug:!1,info:!1,warn:!1,error:!0,fatal:!0};function U(t,o,n,e,c){let a=`"${o.messageKey}"`;return(...i)=>{if(i.length===1&&typeof i[0]==="string"&&i[0].charCodeAt(0)===123&&i[0].includes(a)){l(i[0],O[t]);return}if(m[t]<n)return;let L=G(...i);if(e&&!e(t,L))return;let R=A(...i),f=J(...i),g={level:t,message:L,timestamp:new Date().toISOString(),context:R||{},error:f?F(f):void 0,trace:c?.()},s=o.format(g);if(g.error)p(s,g.error);l(JSON.stringify(s),O[t])}}var S="__jsonlLoggerIntercepted";function K(t){if(globalThis[S])return;globalThis[S]=!0;let o=t?.formatter??u,n=m[t?.level??"debug"],e=t?.filter,c=t?.traceContext,a=[["log","info"],["info","info"],["warn","warn"],["error","error"],["debug","debug"]];for(let[i,L]of a)console[i]=U(L,o,n,e,c)}export{D as originalConsole,K as intercept};
1
+ var y={debug:"DEBUG",info:"INFO",warn:"WARNING",error:"ERROR",fatal:"CRITICAL"},l={messageKey:"message",format(t){let o={message:t.message,timestamp:t.timestamp,severity:y[t.level],...t.context};if(t.trace){if(o["logging.googleapis.com/trace"]=t.trace.traceId,o["logging.googleapis.com/spanId"]=t.trace.spanId,t.trace.traceFlags!==void 0)o["logging.googleapis.com/trace_sampled"]=(t.trace.traceFlags&1)===1}return o}};var F={messageKey:"_msg",format(t){let o={_msg:t.message,_time:t.timestamp,level:t.level,...t.context};if(t.trace){if(o.trace_id=t.trace.traceId,o.span_id=t.trace.spanId,t.trace.traceFlags!==void 0)o.trace_flags=t.trace.traceFlags}return o}};var k=process.env.LOG_LABELS==="text"?"text":process.env.LOG_LABELS==="none"?"none":"icon",R=process.env.LOG_FORMAT,v=!!R,m={debug:0,info:1,warn:2,error:3,fatal:4},_=/\x1b\[[0-9;]*m/g;function b(t){return t.replace(_,"")}function u(t,o,e="error"){if(t[`${e}.name`]=o.name,t[`${e}.message`]=o.message,o.stack)t[`${e}.stack`]=o.stack;if(o.cause)u(t,o.cause,`${e}.cause`)}var I=typeof process<"u"&&process.stdout&&typeof process.stdout.write==="function"?"node":typeof Deno<"u"&&Deno.stdout?"deno":"browser",$=I==="deno"?new TextEncoder:null;function h(t,o){if(I==="node")(o?process.stderr??process.stdout:process.stdout).write(`${t}
2
+ `);else if(I==="deno"&&$){let e=$.encode(`${t}
3
+ `);if(o)Deno.stderr.writeSync(e);else Deno.stdout.writeSync(e)}else if(o)console.error(t);else console.log(t)}var E={"google-cloud-logging":l,"victoria-logs":F},N=R&&E[R]||l,S=v,T=process.env.LOG_LEVEL||(S?"info":"debug"),G={debug:!1,info:!1,warn:!1,error:!0,fatal:!0};function O(t,o){return o.add(t),{name:t.name,message:t.message,stack:t.stack,...t.cause instanceof Error&&!o.has(t.cause)?{cause:O(t.cause,o)}:{}}}function d(t){return O(t,new WeakSet)}var A={debug:"◆",info:"●",warn:"▲",error:"✖",fatal:"‼"};class w{ctx;min;json;fmt;labels;tc;constructor(t,o){this.ctx=t||{},this.json=o?.json??S,this.fmt=o?.formatter??N,this.labels=o?.labels??k,this.tc=o?.traceContext;let e=o?.level??T;this.min=m[e]??m.info}child(t){let o=new w({...this.ctx,...t},{json:this.json,formatter:this.fmt,labels:this.labels,traceContext:this.tc});return o.min=this.min,o}emit(t,o,e,n,f){if(m[t]<this.min)return;let i={level:t,message:this.json?b(o).trim():o,timestamp:new Date().toISOString(),context:e?{...this.ctx,...e}:this.ctx};if(this.tc)i.trace=this.tc();if(n)i.error=d(n);if(this.json){let s=this.fmt.format(i);if(i.error)u(s,i.error);h(JSON.stringify(s),G[t])}else this.logPlain(t,i,f)}logPlain(t,o,e){let n={debug:"\x1B[36m",info:"\x1B[32m",warn:"\x1B[33m",error:"\x1B[31m",fatal:"\x1B[35m"},f="\x1B[0m",i=n[t],s=new Date(o.timestamp).toLocaleTimeString("en-US",{hour12:!1}),a;if(this.labels==="none")a="";else if(this.labels==="text")a=e?" ":` ${t.toUpperCase().padEnd(5)}`;else a=e?" ":` ${A[t]}`;let p=o.context,x=Object.keys(p).length>0?` ${JSON.stringify(p)}`:"",g="";if(o.error){let c=o.error,C=!0;while(c){if(c.stack)g+=C?`
4
+ ${c.stack}`:`
5
+ Caused by: ${c.stack}`;else g+=C?`
6
+ ${c.name}: ${c.message}`:`
7
+ Caused by: ${c.name}: ${c.message}`;c=c.cause,C=!1}}let L=`${i}${s}${a}\x1B[0m ${o.message}${x}${g}`;switch(t){case"debug":console.debug(L);break;case"warn":console.warn(L);break;case"error":case"fatal":console.error(L);break;default:console.log(L)}}log(t,o){this.emit("info",t,o,void 0,!0)}debug(t,o){this.emit("debug",t,o)}info(t,o){this.emit("info",t,o)}warn(t,o){this.emit("warn",t,o)}error(t,o,e){this.emit("error",t,o,e)}fatal(t,o,e){this.emit("fatal",t,o,e)}}var X=new w;var tt={log:console.log.bind(console),info:console.info.bind(console),warn:console.warn.bind(console),error:console.error.bind(console),debug:console.debug.bind(console)};function J(...t){let o="";for(let e=0;e<t.length;e++){if(e>0)o+=" ";let n=t[e];if(typeof n==="string")o+=b(n);else if(n instanceof Error)o+=n.message;else try{o+=JSON.stringify(n)}catch{o+=String(n)}}return o.trim()}function U(...t){let o;for(let e of t)if(typeof e==="object"&&e!==null&&!(e instanceof Error)&&!Array.isArray(e)){if(!o)o={};Object.assign(o,e)}return o}function V(...t){for(let o of t)if(o instanceof Error)return o}var j={debug:!1,info:!1,warn:!1,error:!0,fatal:!0};function W(t,o,e,n,f){let i=`"${o.messageKey}"`;return(...s)=>{if(s.length===1&&typeof s[0]==="string"&&s[0].charCodeAt(0)===123&&s[0].includes(i)){h(s[0],j[t]);return}if(m[t]<e)return;let a=J(...s);if(n&&!n(t,a))return;let p=U(...s),x=V(...s),g={level:t,message:a,timestamp:new Date().toISOString(),context:p||{},error:x?d(x):void 0,trace:f?.()},L=o.format(g);if(g.error)u(L,g.error);h(JSON.stringify(L),j[t])}}var r="__jsonlLoggerIntercepted";function ot(t){if(globalThis[r])return;globalThis[r]=!0;let o=t?.formatter??l,e=m[t?.level??"debug"],n=t?.filter,f=t?.traceContext,i=[["log","info"],["info","info"],["warn","warn"],["error","error"],["debug","debug"]];for(let[s,a]of i)console[s]=W(a,o,e,n,f)}export{tt as originalConsole,ot as intercept};
package/dist/preload.js CHANGED
@@ -1,7 +1,7 @@
1
- var N={debug:"DEBUG",info:"INFO",warn:"WARNING",error:"ERROR",fatal:"CRITICAL"},g={messageKey:"message",format(t){let o={message:t.message,timestamp:t.timestamp,severity:N[t.level],...t.context};if(t.trace){if(o["logging.googleapis.com/trace"]=t.trace.traceId,o["logging.googleapis.com/spanId"]=t.trace.spanId,t.trace.traceFlags!==void 0)o["logging.googleapis.com/trace_sampled"]=(t.trace.traceFlags&1)===1}return o}};var x={messageKey:"_msg",format(t){let o={_msg:t.message,_time:t.timestamp,level:t.level,...t.context};if(t.trace){if(o.trace_id=t.trace.traceId,o.span_id=t.trace.spanId,t.trace.traceFlags!==void 0)o.trace_flags=t.trace.traceFlags}return o}};var l=process.env.LOG_FORMAT,d=!!l,f={debug:0,info:1,warn:2,error:3,fatal:4},S=/\x1b\[[0-9;]*m/g;function r(t){return t.replace(S,"")}function u(t,o,n="error"){if(t[`${n}.name`]=o.name,t[`${n}.message`]=o.message,o.stack)t[`${n}.stack`]=o.stack;if(o.cause)u(t,o.cause,`${n}.cause`)}var C=typeof process<"u"&&process.stdout&&typeof process.stdout.write==="function"?"node":typeof Deno<"u"&&Deno.stdout?"deno":"browser",I=C==="deno"?new TextEncoder:null;function h(t,o){if(C==="node")(o?process.stderr??process.stdout:process.stdout).write(`${t}
2
- `);else if(C==="deno"&&I){let n=I.encode(`${t}
3
- `);if(o)Deno.stderr.writeSync(n);else Deno.stdout.writeSync(n)}else if(o)console.error(t);else console.log(t)}var _={"google-cloud-logging":g,"victoria-logs":x},j=l&&_[l]||g,v=d,y=process.env.LOG_LEVEL||(v?"info":"debug"),G={debug:!1,info:!1,warn:!1,error:!0,fatal:!0};function k(t,o){return o.add(t),{name:t.name,message:t.message,stack:t.stack,...t.cause instanceof Error&&!o.has(t.cause)?{cause:k(t.cause,o)}:{}}}function b(t){return k(t,new WeakSet)}class w{ctx;min;json;fmt;tc;constructor(t,o){this.ctx=t||{},this.json=o?.json??v,this.fmt=o?.formatter??j,this.tc=o?.traceContext;let n=o?.level??y;this.min=f[n]??f.info}child(t){let o=new w({...this.ctx,...t},{json:this.json,formatter:this.fmt,traceContext:this.tc});return o.min=this.min,o}log(t,o,n,e){if(f[t]<this.min)return;let i={level:t,message:this.json?r(o).trim():o,timestamp:new Date().toISOString(),context:n?{...this.ctx,...n}:this.ctx};if(this.tc)i.trace=this.tc();if(e)i.error=b(e);if(this.json){let a=this.fmt.format(i);if(i.error)u(a,i.error);h(JSON.stringify(a),G[t])}else this.logPlain(t,i)}logPlain(t,o){let n={debug:"\x1B[36m",info:"\x1B[32m",warn:"\x1B[33m",error:"\x1B[31m",fatal:"\x1B[35m"},e="\x1B[0m",i=n[t],a=new Date(o.timestamp).toLocaleTimeString("en-US",{hour12:!1}),c=t.toUpperCase().padEnd(5),L=o.context,R=Object.keys(L).length>0?` ${JSON.stringify(L)}`:"",p="";if(o.error){let s=o.error,F=!0;while(s){if(s.stack)p+=F?`
4
- ${s.stack}`:`
5
- Caused by: ${s.stack}`;else p+=F?`
6
- ${s.name}: ${s.message}`:`
7
- Caused by: ${s.name}: ${s.message}`;s=s.cause,F=!1}}let m=`${i}${a} ${c}\x1B[0m ${o.message}${R}${p}`;switch(t){case"debug":console.debug(m);break;case"warn":console.warn(m);break;case"error":case"fatal":console.error(m);break;default:console.log(m)}}debug(t,o){this.log("debug",t,o)}info(t,o){this.log("info",t,o)}warn(t,o){this.log("warn",t,o)}error(t,o,n){this.log("error",t,o,n)}fatal(t,o,n){this.log("fatal",t,o,n)}}var P=new w;var K={log:console.log.bind(console),info:console.info.bind(console),warn:console.warn.bind(console),error:console.error.bind(console),debug:console.debug.bind(console)};function T(...t){let o="";for(let n=0;n<t.length;n++){if(n>0)o+=" ";let e=t[n];if(typeof e==="string")o+=r(e);else if(e instanceof Error)o+=e.message;else try{o+=JSON.stringify(e)}catch{o+=String(e)}}return o.trim()}function V(...t){let o;for(let n of t)if(typeof n==="object"&&n!==null&&!(n instanceof Error)&&!Array.isArray(n)){if(!o)o={};Object.assign(o,n)}return o}function A(...t){for(let o of t)if(o instanceof Error)return o}var $={debug:!1,info:!1,warn:!1,error:!0,fatal:!0};function J(t,o,n,e,i){let a=`"${o.messageKey}"`;return(...c)=>{if(c.length===1&&typeof c[0]==="string"&&c[0].charCodeAt(0)===123&&c[0].includes(a)){h(c[0],$[t]);return}if(f[t]<n)return;let L=T(...c);if(e&&!e(t,L))return;let R=V(...c),p=A(...c),m={level:t,message:L,timestamp:new Date().toISOString(),context:R||{},error:p?b(p):void 0,trace:i?.()},s=o.format(m);if(m.error)u(s,m.error);h(JSON.stringify(s),$[t])}}var O="__jsonlLoggerIntercepted";function E(t){if(globalThis[O])return;globalThis[O]=!0;let o=t?.formatter??g,n=f[t?.level??"debug"],e=t?.filter,i=t?.traceContext,a=[["log","info"],["info","info"],["warn","warn"],["error","error"],["debug","debug"]];for(let[c,L]of a)console[c]=J(L,o,n,e,i)}if(l){let o={"google-cloud-logging":g,"victoria-logs":x}[l]??g,n=process.env.LOG_LEVEL||"info";E({formatter:o,level:n})}
1
+ var N={debug:"DEBUG",info:"INFO",warn:"WARNING",error:"ERROR",fatal:"CRITICAL"},m={messageKey:"message",format(t){let o={message:t.message,timestamp:t.timestamp,severity:N[t.level],...t.context};if(t.trace){if(o["logging.googleapis.com/trace"]=t.trace.traceId,o["logging.googleapis.com/spanId"]=t.trace.spanId,t.trace.traceFlags!==void 0)o["logging.googleapis.com/trace_sampled"]=(t.trace.traceFlags&1)===1}return o}};var R={messageKey:"_msg",format(t){let o={_msg:t.message,_time:t.timestamp,level:t.level,...t.context};if(t.trace){if(o.trace_id=t.trace.traceId,o.span_id=t.trace.spanId,t.trace.traceFlags!==void 0)o.trace_flags=t.trace.traceFlags}return o}};var v=process.env.LOG_LABELS==="text"?"text":process.env.LOG_LABELS==="none"?"none":"icon",l=process.env.LOG_FORMAT,$=!!l,g={debug:0,info:1,warn:2,error:3,fatal:4},_=/\x1b\[[0-9;]*m/g;function u(t){return t.replace(_,"")}function p(t,o,e="error"){if(t[`${e}.name`]=o.name,t[`${e}.message`]=o.message,o.stack)t[`${e}.stack`]=o.stack;if(o.cause)p(t,o.cause,`${e}.cause`)}var F=typeof process<"u"&&process.stdout&&typeof process.stdout.write==="function"?"node":typeof Deno<"u"&&Deno.stdout?"deno":"browser",I=F==="deno"?new TextEncoder:null;function b(t,o){if(F==="node")(o?process.stderr??process.stdout:process.stdout).write(`${t}
2
+ `);else if(F==="deno"&&I){let e=I.encode(`${t}
3
+ `);if(o)Deno.stderr.writeSync(e);else Deno.stdout.writeSync(e)}else if(o)console.error(t);else console.log(t)}var j={"google-cloud-logging":m,"victoria-logs":R},G=l&&j[l]||m,k=$,T=process.env.LOG_LEVEL||(k?"info":"debug"),V={debug:!1,info:!1,warn:!1,error:!0,fatal:!0};function S(t,o){return o.add(t),{name:t.name,message:t.message,stack:t.stack,...t.cause instanceof Error&&!o.has(t.cause)?{cause:S(t.cause,o)}:{}}}function C(t){return S(t,new WeakSet)}var A={debug:"◆",info:"●",warn:"▲",error:"✖",fatal:"‼"};class w{ctx;min;json;fmt;labels;tc;constructor(t,o){this.ctx=t||{},this.json=o?.json??k,this.fmt=o?.formatter??G,this.labels=o?.labels??v,this.tc=o?.traceContext;let e=o?.level??T;this.min=g[e]??g.info}child(t){let o=new w({...this.ctx,...t},{json:this.json,formatter:this.fmt,labels:this.labels,traceContext:this.tc});return o.min=this.min,o}emit(t,o,e,n,r){if(g[t]<this.min)return;let i={level:t,message:this.json?u(o).trim():o,timestamp:new Date().toISOString(),context:e?{...this.ctx,...e}:this.ctx};if(this.tc)i.trace=this.tc();if(n)i.error=C(n);if(this.json){let s=this.fmt.format(i);if(i.error)p(s,i.error);b(JSON.stringify(s),V[t])}else this.logPlain(t,i,r)}logPlain(t,o,e){let n={debug:"\x1B[36m",info:"\x1B[32m",warn:"\x1B[33m",error:"\x1B[31m",fatal:"\x1B[35m"},r="\x1B[0m",i=n[t],s=new Date(o.timestamp).toLocaleTimeString("en-US",{hour12:!1}),c;if(this.labels==="none")c="";else if(this.labels==="text")c=e?" ":` ${t.toUpperCase().padEnd(5)}`;else c=e?" ":` ${A[t]}`;let h=o.context,x=Object.keys(h).length>0?` ${JSON.stringify(h)}`:"",f="";if(o.error){let a=o.error,d=!0;while(a){if(a.stack)f+=d?`
4
+ ${a.stack}`:`
5
+ Caused by: ${a.stack}`;else f+=d?`
6
+ ${a.name}: ${a.message}`:`
7
+ Caused by: ${a.name}: ${a.message}`;a=a.cause,d=!1}}let L=`${i}${s}${c}\x1B[0m ${o.message}${x}${f}`;switch(t){case"debug":console.debug(L);break;case"warn":console.warn(L);break;case"error":case"fatal":console.error(L);break;default:console.log(L)}}log(t,o){this.emit("info",t,o,void 0,!0)}debug(t,o){this.emit("debug",t,o)}info(t,o){this.emit("info",t,o)}warn(t,o){this.emit("warn",t,o)}error(t,o,e){this.emit("error",t,o,e)}fatal(t,o,e){this.emit("fatal",t,o,e)}}var Y=new w;var ot={log:console.log.bind(console),info:console.info.bind(console),warn:console.warn.bind(console),error:console.error.bind(console),debug:console.debug.bind(console)};function J(...t){let o="";for(let e=0;e<t.length;e++){if(e>0)o+=" ";let n=t[e];if(typeof n==="string")o+=u(n);else if(n instanceof Error)o+=n.message;else try{o+=JSON.stringify(n)}catch{o+=String(n)}}return o.trim()}function U(...t){let o;for(let e of t)if(typeof e==="object"&&e!==null&&!(e instanceof Error)&&!Array.isArray(e)){if(!o)o={};Object.assign(o,e)}return o}function W(...t){for(let o of t)if(o instanceof Error)return o}var y={debug:!1,info:!1,warn:!1,error:!0,fatal:!0};function B(t,o,e,n,r){let i=`"${o.messageKey}"`;return(...s)=>{if(s.length===1&&typeof s[0]==="string"&&s[0].charCodeAt(0)===123&&s[0].includes(i)){b(s[0],y[t]);return}if(g[t]<e)return;let c=J(...s);if(n&&!n(t,c))return;let h=U(...s),x=W(...s),f={level:t,message:c,timestamp:new Date().toISOString(),context:h||{},error:x?C(x):void 0,trace:r?.()},L=o.format(f);if(f.error)p(L,f.error);b(JSON.stringify(L),y[t])}}var O="__jsonlLoggerIntercepted";function E(t){if(globalThis[O])return;globalThis[O]=!0;let o=t?.formatter??m,e=g[t?.level??"debug"],n=t?.filter,r=t?.traceContext,i=[["log","info"],["info","info"],["warn","warn"],["error","error"],["debug","debug"]];for(let[s,c]of i)console[s]=B(c,o,e,n,r)}if(l){let o={"google-cloud-logging":m,"victoria-logs":R}[l]??m,e=process.env.LOG_LEVEL||"info";E({formatter:o,level:e})}
package/dist/types.d.ts CHANGED
@@ -23,9 +23,12 @@ export type Formatter = {
23
23
  format: (record: LogRecord) => Record<string, unknown>;
24
24
  messageKey: string;
25
25
  };
26
+ export type LabelStyle = 'icon' | 'none' | 'text';
27
+ export declare const defaultLabelStyle: LabelStyle;
26
28
  export type LoggerOptions = {
27
29
  formatter?: Formatter;
28
30
  json?: boolean;
31
+ labels?: LabelStyle;
29
32
  level?: LogLevel;
30
33
  traceContext?: () => TraceContext | undefined;
31
34
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsonl-logger",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "description": "Lightweight ESM-only JSON Lines logger with pluggable formatters for Google Cloud Logging, VictoriaLogs, and more",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/index.ts CHANGED
@@ -3,6 +3,7 @@ import type {
3
3
  ErrorInfo,
4
4
  Formatter,
5
5
  FormatterName,
6
+ LabelStyle,
6
7
  LogContext,
7
8
  LoggerOptions,
8
9
  LogLevel,
@@ -11,6 +12,7 @@ import type {
11
12
  } from './types'
12
13
  import {
13
14
  defaultFormat,
15
+ defaultLabelStyle,
14
16
  flattenError,
15
17
  isJsonMode,
16
18
  logLevelValues,
@@ -24,6 +26,7 @@ export type {
24
26
  Formatter,
25
27
  FormatterName,
26
28
  InterceptOptions,
29
+ LabelStyle,
27
30
  LogContext,
28
31
  LoggerOptions,
29
32
  LogLevel,
@@ -68,17 +71,27 @@ export function errorInfo(err: Error): ErrorInfo {
68
71
  return extractErrorInfo(err, new WeakSet())
69
72
  }
70
73
 
74
+ const levelIcons: Record<LogLevel, string> = {
75
+ debug: '◆',
76
+ info: '●',
77
+ warn: '▲',
78
+ error: '✖',
79
+ fatal: '‼',
80
+ }
81
+
71
82
  export class Logger {
72
83
  private ctx: LogContext
73
84
  private min: number
74
85
  private json: boolean
75
86
  private fmt: Formatter
87
+ private labels: LabelStyle
76
88
  private tc?: () => TraceContext | undefined
77
89
 
78
90
  constructor(context?: LogContext, options?: LoggerOptions) {
79
91
  this.ctx = context || {}
80
92
  this.json = options?.json ?? defaultJson
81
93
  this.fmt = options?.formatter ?? defaultFormatter
94
+ this.labels = options?.labels ?? defaultLabelStyle
82
95
  this.tc = options?.traceContext
83
96
  const level: LogLevel = options?.level ?? defaultLevel
84
97
  this.min = logLevelValues[level] ?? logLevelValues.info
@@ -90,6 +103,7 @@ export class Logger {
90
103
  {
91
104
  json: this.json,
92
105
  formatter: this.fmt,
106
+ labels: this.labels,
93
107
  traceContext: this.tc,
94
108
  },
95
109
  )
@@ -97,11 +111,12 @@ export class Logger {
97
111
  return child
98
112
  }
99
113
 
100
- private log(
114
+ private emit(
101
115
  level: LogLevel,
102
116
  message: string,
103
117
  meta?: LogContext,
104
118
  err?: Error,
119
+ neutral?: boolean,
105
120
  ): void {
106
121
  if (logLevelValues[level] < this.min) return
107
122
 
@@ -125,11 +140,15 @@ export class Logger {
125
140
  if (record.error) flattenError(formatted, record.error)
126
141
  write(JSON.stringify(formatted), isErrorLevel[level])
127
142
  } else {
128
- this.logPlain(level, record)
143
+ this.logPlain(level, record, neutral)
129
144
  }
130
145
  }
131
146
 
132
- private logPlain(level: LogLevel, record: LogRecord): void {
147
+ private logPlain(
148
+ level: LogLevel,
149
+ record: LogRecord,
150
+ neutral?: boolean,
151
+ ): void {
133
152
  const colors: Record<LogLevel, string> = {
134
153
  debug: '\x1b[36m',
135
154
  info: '\x1b[32m',
@@ -143,7 +162,15 @@ export class Logger {
143
162
  const time = new Date(record.timestamp).toLocaleTimeString('en-US', {
144
163
  hour12: false,
145
164
  })
146
- const levelStr = level.toUpperCase().padEnd(5)
165
+
166
+ let label: string
167
+ if (this.labels === 'none') {
168
+ label = ''
169
+ } else if (this.labels === 'text') {
170
+ label = neutral ? ' ' : ` ${level.toUpperCase().padEnd(5)}`
171
+ } else {
172
+ label = neutral ? ' ' : ` ${levelIcons[level]}`
173
+ }
147
174
 
148
175
  const ctx = record.context
149
176
  const metaStr = Object.keys(ctx).length > 0 ? ` ${JSON.stringify(ctx)}` : ''
@@ -167,7 +194,7 @@ export class Logger {
167
194
  }
168
195
  }
169
196
 
170
- const output = `${color}${time} ${levelStr}${reset} ${record.message}${metaStr}${errStr}`
197
+ const output = `${color}${time}${label}${reset} ${record.message}${metaStr}${errStr}`
171
198
 
172
199
  switch (level) {
173
200
  case 'debug':
@@ -185,24 +212,28 @@ export class Logger {
185
212
  }
186
213
  }
187
214
 
215
+ log(message: string, meta?: LogContext): void {
216
+ this.emit('info', message, meta, undefined, true)
217
+ }
218
+
188
219
  debug(message: string, meta?: LogContext): void {
189
- this.log('debug', message, meta)
220
+ this.emit('debug', message, meta)
190
221
  }
191
222
 
192
223
  info(message: string, meta?: LogContext): void {
193
- this.log('info', message, meta)
224
+ this.emit('info', message, meta)
194
225
  }
195
226
 
196
227
  warn(message: string, meta?: LogContext): void {
197
- this.log('warn', message, meta)
228
+ this.emit('warn', message, meta)
198
229
  }
199
230
 
200
231
  error(message: string, meta?: LogContext, error?: Error): void {
201
- this.log('error', message, meta, error)
232
+ this.emit('error', message, meta, error)
202
233
  }
203
234
 
204
235
  fatal(message: string, meta?: LogContext, error?: Error): void {
205
- this.log('fatal', message, meta, error)
236
+ this.emit('fatal', message, meta, error)
206
237
  }
207
238
  }
208
239
 
package/src/types.ts CHANGED
@@ -29,9 +29,19 @@ export type Formatter = {
29
29
  messageKey: string
30
30
  }
31
31
 
32
+ export type LabelStyle = 'icon' | 'none' | 'text'
33
+
34
+ export const defaultLabelStyle: LabelStyle =
35
+ (process.env.LOG_LABELS as LabelStyle) === 'text'
36
+ ? 'text'
37
+ : (process.env.LOG_LABELS as LabelStyle) === 'none'
38
+ ? 'none'
39
+ : 'icon'
40
+
32
41
  export type LoggerOptions = {
33
42
  formatter?: Formatter
34
43
  json?: boolean
44
+ labels?: LabelStyle
35
45
  level?: LogLevel
36
46
  traceContext?: () => TraceContext | undefined
37
47
  }