@jvddavid/pino-rotating-file
Version:
A transport for pino that writes logs to rotating files
1 lines • 2.29 kB
JavaScript
"use strict";var t=require("close-with-grace"),e=require("pino-abstract-transport"),r=require("node:events"),n=require("node:path"),s=require("sonic-boom");class i extends r.EventEmitter{currentFile=0;currentSize=0;currentStream;options;writable=!0;constructor(t){super(),this.options={maxSize:10485760,path:"logs",pattern:"log-%Y-%M-%d-%H-%m-%s-%l-%N.log",sync:!1,fsync:!1,append:!0,mkdir:!0,...t},this.currentStream=this.createStream()}createStream(){const{path:t,pattern:e,maxSize:r,sync:i,fsync:a,mkdir:c,append:o}=this.options,u=new Date,h=n.join(t,e.replace(/%[a-zA-Z]/g,(t=>{switch(t){case"%Y":return u.getFullYear().toString();case"%M":return(u.getMonth()+1).toString().padStart(2,"0");case"%d":return u.getDate().toString().padStart(2,"0");case"%H":return u.getHours().toString().padStart(2,"0");case"%m":return u.getMinutes().toString().padStart(2,"0");case"%s":return u.getSeconds().toString().padStart(2,"0");case"%l":return u.getMilliseconds().toString().padStart(3,"0");case"%N":return this.currentFile.toString().padStart(3,"0");default:return t}}))),S=new s.SonicBoom({dest:h,append:o??!0,mkdir:c??!0,sync:i??!1,contentMode:"utf8",fsync:a,maxWrite:r});return this.currentFile++,S.on("error",(t=>this.emit("error",t))),S}rotateStream(){this.currentStream&&(this.currentStream.removeAllListeners(),this.currentStream.flush((t=>{t&&this.emit("error",t),this.currentStream.end()}))),this.currentStream=this.createStream()}flush(){return new Promise(((t,e)=>{this.currentStream.flush((r=>{r?e(r):t()}))}))}write(t){return!!this.writable&&(this.currentSize+=t.length,this.currentSize>=this.options.maxSize&&(this.rotateStream(),this.currentSize=t.length),this.currentStream.write(`${t}\n`))}close(){return this.writable=!1,new Promise(((t,e)=>{this.currentStream.once("close",t),this.currentStream.once("error",e),this.currentStream.flush((t=>{t?e(t):this.currentStream.end()}))}))}end(){return this.writable=!1,this.currentStream.once("close",(()=>this.emit("close"))),this.currentStream.once("error",(t=>this.emit("error",t))),this.currentStream.flush((t=>{t&&this.emit("error",t),this.currentStream.end()})),this}}module.exports=r=>{const n=new i(r);return t((()=>{n.end()})),e((t=>{t.pipe(n)}),{close(t,e){n.on("close",e.bind(null,t)),n.end()},parse:"lines",parseLine:t=>t})};