nest日志包pino、winston配置-懒人的折腾

news2024/11/20 21:35:35

nest日志

三种node服务端日志选型

  • winston
  • pino
  • log4js

2023年5月23日

看star数:winston > pino > log4js

使用体验:

  1. pino 格式简洁,速度快,支持输入日志到任意数据库,日志暂无自动清理(可能是我方式不对?知道的朋友评论下告诉我,十分感谢~)
  2. winston 通用,稳定,日志可自动清理。
  3. 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-function
      quietReqLogger: true,
      genReqId: (req: IncomingMessage): ReqId =>
        (<Request>req).header('X-Request-id') || nanoid(),
      ...(process.env.NODE_ENV === 'production'
        ? {
            // https://www.npmjs.com/package/pino-roll
            level: '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-pretty
              target: '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:

  1. nanoid esm 问题,直接降级处理
    官方issues

“nanoid”: “^.4.x.x” => “nanoid”: “^3.3.6”,

参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/562254.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI是怎么帮我写代码,写SQL的?(本文不卖课)

近期&#xff0c;ChatGPT风起云涌&#xff0c;“再不入局&#xff0c;就要被时代淘汰”的言论甚嚣尘上&#xff0c;借着这一波创业的朋友都不止3-4个&#xff0c;如果没记错&#xff0c;前几次抛出该言论的风口似乎是区块链&#xff0c;元宇宙&#xff0c;WEB3.0。 画外音&…

动态规划问题实验:数塔问题

目录 前言实验内容实验流程实验过程实验分析伪代码代码实现分析算法复杂度用例测试 总结 前言 动态规划是一种解决复杂问题的方法&#xff0c;它将一个问题分解为若干个子问题&#xff0c;然后从最简单的子问题开始求解&#xff0c;逐步推导出更复杂的子问题的解&#xff0c;最…

绝世内功秘籍《调试技巧》

本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 内容专栏&#xff1a;这里是《C知识系统分享》专栏&#xff0c;笔者用重金(时间和精力)打造&#xff0c;基础知识一网打尽&#xff0c;希望可以帮到读者们哦。 内…

CloudQuery v2.0.0 发布 新增数据保护、数据变更、连接管理等功能

哈喽社区的小伙伴们&#xff0c;经过一个月的努力&#xff0c;CloudQuery 社区版发布了全新 v2.0.0系列&#xff01; 对比 v1.5.0&#xff0c;v2.0.0 在整体 UI 界面上就做了很大调整&#xff0c;功能排布我们做了重新梳理&#xff0c;可以说&#xff0c;社区版 v2.0.0 带领 C…

Linux——makefile自动化构建工具

一. 前言 一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;makefile定义了一系列的 规则来指定&#xff0c;哪些文件需要先编译&#xff0c;哪些文件需要后编译&#xff0c;哪些文件需要重新编译&#xff0c;甚至于进行更复杂 的功能…

数据结构的定义

主要的定义 数据 描述客观事物的数和字符的集合&#xff0c;比如文字&#xff0c;数字和特殊符号 基本单元&#xff1a;数据元素 一个数据单元由若干个数据项构成 数据项&#xff1a;具有独立含义的数据最小单元&#xff0c;也称字段或域 数据元素&…

Spring Boot 中的 Starter 是什么?如何创建自定义 Starter?

Spring Boot 中的 Starter 是什么&#xff1f;如何创建自定义 Starter&#xff1f; Spring Boot 是一个快速构建应用程序的框架&#xff0c;它提供了一种简单的方式来快速启动和配置 Spring 应用程序。Spring Boot Starter 是 Spring Boot 的一个重要概念&#xff0c;它可以帮…

计算机网络详细笔记(四)网际控制报文协议ICMP

文章目录 4.网际控制报文协议ICMP4.1.ICMP报文的种类4.2.ICMP应用举例 4.网际控制报文协议ICMP 网际控制报文协议概述&#xff1a;&#xff1a; 作用&#xff1a;更有效地转发IP数据报和提高交付成功的机会。原理&#xff1a;允许主机或路由器报告差错情况和提供有关异常情况…

maven_SSM项目如何实现验证码功能

验证码的作用 防止恶意注册&#xff0c;自动化程序批量注册。防止暴力破解。 1、这里我们使用goole的验证码生成器 由于直接在maven中引入依赖&#xff0c;没有找到。所以只能直接去下载jar包了。 链接&#xff1a;https://pan.baidu.com/s/1KANhJKI4sQCfkiroTVr0WA?pwd29iv …

Oracle数据库环境变量配置修改数据库密码

1.设置环境变量&#xff1a; 必须设置环境变量才可以用CMD命令访问Oracle数据库 1.1.首先找到你Oracle安装位置路径 C:\app\Administrator\product\11.2.0\dbhome_1 1.2.设置环境变量 1.2.1 设置Adimistrator变量 变量名&#xff1a; ORACLE_HOME 变量值&#xff1a;C:\app…

嵌入式学习之Linux驱动(第九期_设备模型_教程更新了)_基于RK3568

驱动视频全新升级&#xff0c;并持续更新~更全&#xff0c;思路更科学&#xff0c;入门更简单。 迅为基于iTOP-RK3568开发板进行讲解&#xff0c;本次更新内容为第九期&#xff0c;主要讲解设备模型&#xff0c;共计29讲。视频选集 0.课程规划 06:35 1.抛砖引玉-设备模型…

K8s in Action 阅读笔记——【3】Pods: running containers in Kubernetes

K8s in Action 阅读笔记——【3】Pods: running containers in Kubernetes 3.1 Introducing pods 在Kubernetes中&#xff0c;Pod是基本构建块之一&#xff0c;由容器集合组成。与独立部署容器不同&#xff0c;你总是要部署和操作一个Pod。Pod并不总是包含多个容器&#xff0…

Python数据分析案例28——西雅图交通事故预测(不平衡样本处理)

本次案例适合机器学习数据科学方向的同学。 引言(废话集) 交通事故是一个严重的公共安全问题&#xff0c;在全球范围内每年都有成千上万的人死于交通事故。随着交通运输的发展和城市化进程的加速&#xff0c;交通事故已成为制约城市发展和人民幸福的主要因素之一。因此&#x…

【蓝桥杯选拔赛真题57】Scratch计数游戏 少儿编程scratch图形化编程 蓝桥杯选拔赛真题讲解

目录 scratch计数游戏 一、题目要求 编程实现 二、案例分析 1、角色分析

Java版本企业电子招标采购系统源码:营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展

营造全面规范安全的电子招投标环境&#xff0c;促进招投标市场健康可持续发展 传统采购模式面临的挑战 一、立项管理 1、招标立项申请 功能点&#xff1a;招标类项目立项申请入口&#xff0c;用户可以保存为草稿&#xff0c;提交。 2、非招标立项申请 功能点&#xff1a;非招标…

设计模式之【解释器模式】,用语言定义一门语言

文章目录 一、什么是解释器模式1、常见文法&#xff08;语法&#xff09;规则2、抽象语法树3、解释器模式的使用场景4、解释器模式的四大角色5、解释器模式优缺点 二、实例1、解释器模式的一般写法2、数学表达式案例 三、源码中的解释器模式1、Pattern正则2、Spring的Expressio…

jupyter notebook零散操作整理

1 修改Jupyter Notebook打开路径 1.1 永久修改 jupyter notebook --generate-config 打开相应的.py文件&#xff0c;修改c.NotebookApp.notebook_dir 1.2 临时修改 .切换到需要的临时目录&#xff0c;打开jupyter notebook 2 使用Matplotlib绘图时输出矢量图 %config Inli…

MT4期货软件怎么使用?有哪些MT4期货软件使用知识?

现在MT4软件在投资市场上应用广泛&#xff0c;当然也包括期货交易市场&#xff0c;但有不少投资者不知道为什么一定要选择MT4期货软件&#xff0c;其实选择MT4期货软件的理由有很多&#xff0c;MT4作为一款交易软件&#xff0c;不仅能够为投资者提供准确的市场信息&#xff0c;…

PyQt5实现父窗口内点击按钮显示子窗口(窗口嵌套功能)

摘要&#xff1a;在软件中&#xff0c;常会有点击某个按钮&#xff0c;显示一个新的子界面的需求&#xff0c;本文介绍如何在PyQt5中实现这一功能&#xff0c;主要涉及知识点是“信号与槽函数的自动绑定”。 程序说明&#xff1a; 1.开发环境&#xff1a;win10系统&#xff0c…

【C++】C++11线程库 和 C++IO流

春风若有怜花意&#xff0c;可否许我再少年。 文章目录 一、C11线程库1.thread类介绍2.mutex互斥锁 和 CAS原子操作&#xff08;compare and set&#xff09;3.lock_guard和unique_lock4.两个线程交替打印&#xff0c;一个打印奇数&#xff0c;一个打印偶数&#xff08;线程同步…