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 +3 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +7 -7
- package/dist/intercept.js +7 -7
- package/dist/preload.js +7 -7
- package/dist/types.d.ts +3 -0
- package/package.json +1 -1
- package/src/index.ts +41 -10
- package/src/types.ts +10 -0
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
|
|
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
|
|
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
|
|
2
|
-
`);else if(
|
|
3
|
-
`);if(
|
|
4
|
-
${
|
|
5
|
-
Caused by: ${
|
|
6
|
-
${
|
|
7
|
-
Caused by: ${
|
|
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
|
|
2
|
-
`);else if(
|
|
3
|
-
`);if(o)Deno.stderr.writeSync(
|
|
4
|
-
${
|
|
5
|
-
Caused by: ${
|
|
6
|
-
${
|
|
7
|
-
Caused by: ${
|
|
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"},
|
|
2
|
-
`);else if(
|
|
3
|
-
`);if(o)Deno.stderr.writeSync(
|
|
4
|
-
${
|
|
5
|
-
Caused by: ${
|
|
6
|
-
${
|
|
7
|
-
Caused by: ${
|
|
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
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
|
|
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(
|
|
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
|
-
|
|
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}
|
|
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.
|
|
220
|
+
this.emit('debug', message, meta)
|
|
190
221
|
}
|
|
191
222
|
|
|
192
223
|
info(message: string, meta?: LogContext): void {
|
|
193
|
-
this.
|
|
224
|
+
this.emit('info', message, meta)
|
|
194
225
|
}
|
|
195
226
|
|
|
196
227
|
warn(message: string, meta?: LogContext): void {
|
|
197
|
-
this.
|
|
228
|
+
this.emit('warn', message, meta)
|
|
198
229
|
}
|
|
199
230
|
|
|
200
231
|
error(message: string, meta?: LogContext, error?: Error): void {
|
|
201
|
-
this.
|
|
232
|
+
this.emit('error', message, meta, error)
|
|
202
233
|
}
|
|
203
234
|
|
|
204
235
|
fatal(message: string, meta?: LogContext, error?: Error): void {
|
|
205
|
-
this.
|
|
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
|
}
|