nest日志包pino、winston配置-懒人的折腾
nest日志
三种node服务端日志选型
- winston
- pino
- log4js
2023年5月23日
看star数:winston > pino > log4js
使用体验:
- pino 格式简洁,速度快,支持输入日志到任意数据库,日志暂无自动清理(可能是我方式不对?知道的朋友评论下告诉我,十分感谢~)
- winston 通用,稳定,日志可自动清理。
- log4js 不知为啥,不想使用,除非你劝我。
pino
目前使用 pino
npm install pino nestjs-pino pino-http
npm install nanoid
npm install pino-pretty -D
npm install pino-roll -D
pino-pretty: 格式化用
pino-roll: 日志,设置文件大小,分割周期,日志名。
特点:
- Pino的内部架构基于Worker Threads
- 配置简单
- 支持日志类型指定输出到不同文件(会导致速度慢)
- 支持输出日志到任意数据库中
问题:日志需要自己做定时任务清理,避免占用内存。
main.ts
import { Logger } from 'nestjs-pino';
const app = await NestFactory.create<NestExpressApplication>(AppModule, {bufferLogs: true, // 使用外部的日志包pino});app.useLogger(app.get(Logger));app.flushLogs();
logger.config.ts
import { nanoid } from 'nanoid';
import type { Request } from 'express';
import { IncomingMessage } from 'http';
import type { Params } from 'nestjs-pino';
import { multistream } from 'pino';
import type { ReqId } from 'pino-http';
import { join } from 'path';
import { format } from 'date-fns';
const passUrl = new Set(['./health']);
export const loggerOptions: Params = {pinoHttp: [{// https://getpino.io/#/docs/api?id=timestamp-boolean-functionquietReqLogger: true,genReqId: (req: IncomingMessage): ReqId =>(<Request>req).header('X-Request-id') || nanoid(),...(process.env.NODE_ENV === 'production'? {// https://www.npmjs.com/package/pino-rolllevel: 'error',transport: {target: 'pino-roll',options: {file: join('logs', 'log'),size: '10m',// 周期frequency: 'daily',mkdir: true,extension: `.${format(new Date(), 'yyyy-MM-dd')}.json`,},},}: {level: 'debug',transport: {// https://github.com/pinojs/pino-prettytarget: 'pino-pretty',options: { sync: true, colorize: true },// options: { sync: true, singleLine: true, colorize: true }, // 生产环境再设置压缩为一行},}),autoLogging: {ignore: (req: IncomingMessage) =>passUrl.has((<Request>req).originalUrl),},},multistream([{ level: 'debug', stream: process.stdout },{ level: 'error', stream: process.stdout },{ level: 'fatal', stream: process.stdout },],{ dedupe: true }, // 删除重复输出),],
};
其他设置模式,不如上面的设置,少了日志分割和文件大小配置,但pino还有流操作,里面可以写逻辑,自己写怎么分割日志或者限制文件大小等,等于自配。
// 1. pino/file
const file =process.cwd() + `/logs/log-${format(new Date(), 'yyyy-MM-dd')}.json`;
{level: 'info',transport: {target: 'pino/file',options: {destination: file, // 1 是直接输出, 2是错误时输出,其他为自己设置的目录文件mkdir: true,},},
}
// 使用内置的pino/file传输和使用pino.destination的区别在于,pino.destination在主线程中运行,而pino/file在工作线程中设置pino.destimation// 2. pino/file
target: 'pino-pretty',
使用 winston
- [nest-winston][nest-winston] 日志记录
- [winston-daily-rotate-file][winston-daily-rotate-file] 配置生产环境日志
npm install --save nest-winston winston
npm install winston-daily-rotate-file
采用[bootstrap配置方式][replacing-the-nest-logger-also-for-bootstrapping]
main.ts
const app = await NestFactory.create<NestExpressApplication>(AppModule, {logger: WinstonModule.createLogger({instance: createLogger({ ...loggerOptions }),}),
});
logger.config.ts
import * as winston from 'winston';
import { utilities as nestWinstonModuleUtilities } from 'nest-winston';
import DailyRotateFile from 'winston-daily-rotate-file';
const format = (label?: string) => {switch (label) {case 'isDev':return {format: winston.format.combine(winston.format.timestamp(),winston.format.ms(),nestWinstonModuleUtilities.format.nestLike('nestBk', {colors: true,prettyPrint: true,}),),};default:return {format: winston.format.combine(winston.format.timestamp(),winston.format.ms(),),};}
};
const prodLoggerConfig = [new DailyRotateFile({level: 'warn',filename: 'nestBk-%DATE%.log',dirname: 'logs',datePattern: 'YYYY-MM-DD-HH',maxSize: '20m',maxFiles: '14d',zippedArchive: true,...format(),}),new DailyRotateFile({level: 'info',filename: 'info-%DATE%.log',dirname: 'logs',datePattern: 'YYYY-MM-DD-HH',maxSize: '20m',maxFiles: '14d',zippedArchive: true,...format(),}),
];export const loggerOptions = {transports: [new winston.transports.Console({level: 'info',...format('isDev'),}),...(IsProMode ? prodLoggerConfig : []),],
};
使用时
xxx.module.ts
providers: [CatsService, Logger],
xxx.controller.ts
import { Logger } from '@nestjs/common';private readonly logger: Logger,this.logger.log('请求成功');this.logger.warn('请求警告');this.logger.error('请求错误');

样式没啥变化(反而喜欢pino的简洁样式)
主要是多了个自动到期删除的配置,不用自己手动删除日志

QA:
- nanoid esm 问题,直接降级处理
官方issues
“nanoid”: “^.4.x.x” => “nanoid”: “^3.3.6”,
参考
相关文章:
nest日志包pino、winston配置-懒人的折腾
nest日志 三种node服务端日志选型 winstonpinolog4js 2023年5月23日 看star数:winston > pino > log4js 使用体验: pino 格式简洁,速度快,支持输入日志到任意数据库,日志暂无自动清理(可能是我…...
一文看懂增值税发票识别OCR:从技术原理到 API Java 示例代码接入
引言 增值税发票识别OCR API是一项重要的技术创新,它在如今信息化的商业环境中发挥着重要作用。通过利用该API,企业和机构能够实现增值税发票的自动化识别和信息提取,从而在财务管理、票据核对、报销流程等方面带来许多好处。 本文将详细介…...
消息队列对比
目录 什么是消息队列 常用的消息队列工具对比 1 、ActiveMQ 2 、RabbitMQ 3、Kafka 4、 RocketMQ 什么是消息队列 消息队列是分布式应用间交换信息的重要组件,消息队列可驻留在内存或磁盘上, 队列可以存储消息直到它们被应用程序读走。通过消息队列࿰…...
Ceph对象存储的基本概念,使用以及优点
Ceph对象存储的基本概念,使用以及优点 Ceph是一种基于分布式架构的对象存储系统,它可以提供高可靠性、高扩展性和高性能的存储服务。这种存储系统可以用于处理大量的数据,例如大型数据库、云存储、视频流、图像数据等。Ceph对象存储系统的基…...
工业互联网UWB定位系统源码,支持自定义开发
工厂人员定位系统,采用UWB定位技术,通过在厂区内部署一定数量的定位基站,以及为人员、车辆、物资佩戴标签卡的形式,实时获取人员精确位置,精度高达10cm。 文末获取联系 工厂人员定位系统可实现物资/车辆实时定位&#…...
VIC模型教程
详情点击链接:RVIC模型融合实践技术应用及未来气候变化模型预测 一:VIC模型的原理与特点 1.VIC模型各模块的主要原理 2.VIC模型的特点及优势 3.VIC模型的适用范围及其限制 4.VIC模型主要输入和输出文件解析案例一 :基于QGIS的VIC模型建模…...
软件著作权容易搞吗?
没有代码、材料,只有一个软件名字就能拿证,你说容易不… 当然这是对我们软著一级代理来说,每年申请下证几千个软著。下面说说下证要点给大家避坑。人群覆盖高新企业、大学生、大学老师、互联网公司。 软件著作权想要轻松下证,必…...
Mac打出特殊字符
optionq:œ ---------optionw:∑ optione: ---------optionr: optiont:† ---------optiony: optionu: ---------optionI:无 optiono: ---------optionP:π o…...
java设计模式之单例设计模式的前世今生
单例设计模式是什么? 单例设计模式是一种创建型模式,它保证一个类只有一个实例,并且该实例提供了全局访问点。这意味着即使在不同的地方,访问这个单例实例的代码得到的都是同一个对象。 单例模式的特点如下: - 保证…...
小航助学2023年3月GESP_C++一级试卷(含题库答题软件账号)
GESP在线模拟训练系统请点击 电子学会-全国青少年编程等级考试真题Scratch一级(2019年3月)在线答题_程序猿下山的博客-CSDN博客_小航答题助手 答案:B 第1题以下不属于计算机输入设备的有( )。 A、键盘B、音箱C、鼠标D、传感器 …...
好程序员:女生学Java好学吗?女生学Java有什么优势?
小源经常会听到女生咨询适不适合学习Java开发的问题,提出这种问题归根结底还是缺乏性别自信,默认女性比男性弱。实际上这个问题并不存在,男女平等才是正确的思维,当然,也为了解开女生们的心结,这里好程序员…...
为Eclipse安装lombok插件
原生的Eclipse没有lombok插件,即使项目引入了lombok依赖也无法正常使用Data等常用标签。下面介绍一下如何手动为Eclipse添加lombok插件,具体操作步骤如下: (1)打开Download地址,点击页面中间的超链接下载最…...
spring-boot 实现接口转发服务,同时支持get 和 post等多种请求
spring-boot 实现接口转发服务,同时支持get 和 post等多种请求 (1)新建类:ProxyController.java package com.taobao.product.controller;import com.taobao.framework.HttpResult; import io.swagger.annotations.Api; import …...
About JDKFlightRecorder--人工翻译
JFR是什么 JDK Flight Recorder是一个工具,用于收集有关JVM以及在JVM上运行的Java程序的诊断和分析数据。 集成到Java虚拟机(JVM)中,使用默认设置时,性能影响小于1%。几乎不产生性能开销,因此即使在负载很…...
【计算机系统基础3】数据的存储与运算
【计算机系统基础3】数据的存储与运算 3.程序调试与实践:数据存储与运算3.1真值与机器数3.1.1整数的编码 3.2数据的存储3.3数组的对齐3.4数据类型的转换3.4.1整数之间的数据类型转换3.4.2整数与浮点数之间的转换3.4.3自动类型转换 3.5浮点数的表示和运算--IEEE 7543…...
【算法】快速排序
目录 核心思想: 过程: 演示: 第一趟: 第二趟: 代码: 核心思想: 从待排序列中取一个元素作为中心,所有比它小或相等的元素一律放在前面, 所有比它大的元素放在后面&…...
【移动端网页布局】流式布局案例 ③ ( 实现搜索栏功能 | 伪元素选择器 | 子绝父相 | 外边距塌陷处理 | 二倍精灵图处理方案 )
文章目录 一、搜索栏样式及核心要点1、实现效果2、自动伸缩搜索栏实现3、搜索栏父容器设置4、搜索栏左右两侧的按钮盒子5、搜索栏盒子6、二倍精灵图处理方案 二、完整代码示例1、HTML 标签结构2、CSS 样式3、展示效果 一、搜索栏样式及核心要点 1、实现效果 上一篇博客中 , 完成…...
【C++修炼之路】30.可变参数模板包装器
每一个不曾起舞的日子都是对生命的辜负 C11之可变参数模板&&包装器 前言一.可变参数模板的首次登场二.参数包展开2.1 递归函数方式展开参数包2.2 逗号表达式展开参数包 三.容器的emplace方法四.包装器4.1 什么是function4.2 function包装器的作用4.3 function的实际用途…...
Linux防火墙之firewalld基础
一、firewalld概述 firewalld防火墙是Centos7系统默认的防火墙管理工具,取代了之前的iptables防火墙,也是工作在网络层,属于包过滤防火墙。 firewalld和iptables都是用来管理防火墙的工具(属于用户态)来定义防火墙的…...
GitLab CI/CD
CI/CD 简介 CI/CD 简单来说就是可以自动化编译、测试、打包我们的代码。 GitLab CICD的使用 首先需要安装gitlab-runner。 在GitLab 中,runners 是运行 CI/CD 作业的代理。我们的对代码的作业都是在runner上去执行的。我们可以在本地、服务器、等任意一个联网设…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
