【NodeJS教程】第15节:日志记录与错误处理

🔥第15节:日志记录与错误处理


🌟 引言

大家好,我是老曹。上一节课我们学习了用户认证与 JWT 的实现方法,掌握了如何保护 API 安全。今天我们将进入后端开发的重要领域——日志记录与错误处理。本节课将介绍如何使用 winston 日志库记录应用运行状态、捕获全局异常以及设计统一的错误响应结构。通过本节课的学习,你将能够轻松地在应用中实现健壮的日志和错误管理机制。


📚 课程目标

  1. 掌握日志记录的基本概念和重要性。
  2. 学习如何使用 winston 记录日志。
  3. 理解全局异常捕获的实现方法。
  4. 设计统一的错误响应结构。
  5. 通过 10 道高频面试题巩固知识点。

🎯 教学内容

🔹 1. 什么是日志记录?

🌟 日志记录是记录应用程序运行状态的过程,包括调试信息、警告和错误等。它是排查问题和优化性能的重要工具。

(1) 核心作用
  • 问题排查:记录运行时的错误和异常。
  • 性能监控:分析请求耗时和资源使用情况。
  • 审计跟踪:记录用户操作行为。

🔹 2. 使用 winston 记录日志

📦 winston 是一个强大的 Node.js 日志库,支持多种传输方式(如文件、控制台)和日志级别。

(1) 安装命令
npm install winston
(2) 示例
const winston = require('winston');

// 创建日志器
const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.Console(), // 输出到控制台
    new winston.transports.File({ filename: 'app.log' }) // 输出到文件
  ]
});

// 记录日志
logger.info('This is an info message');
logger.warn('This is a warning message');
logger.error('This is an error message');

解释

  • level 定义日志级别(如 infowarnerror)。
  • transports 指定日志输出方式。

🔹 3. 全局异常捕获

📦 在 Node.js 中,未捕获的异常可能导致程序崩溃。我们需要实现全局异常捕获机制。

(1) 示例
process.on('uncaughtException', (err) => {
  console.error('Uncaught Exception:', err.message);
  logger.error('Uncaught Exception:', { error: err });
  process.exit(1); // 退出进程
});

process.on('unhandledRejection', (reason, promise) => {
  console.error('Unhandled Rejection at:', promise, 'reason:', reason);
  logger.error('Unhandled Rejection:', { error: reason });
});

解释

  • uncaughtException 捕获同步代码中的未捕获异常。
  • unhandledRejection 捕获 Promise 中的未处理拒绝。

🔹 4. 统一的错误响应结构

📦 设计一致的错误响应结构,提升 API 的可维护性和用户体验。

(1) 示例
class AppError extends Error {
  constructor(message, statusCode) {
    super(message);
    this.statusCode = statusCode;
    this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';
    this.isOperational = true; // 区分操作性错误和编程错误
  }
}

// 错误处理中间件
const errorHandler = (err, req, res, next) => {
  const statusCode = err.statusCode || 500;
  const message = err.message || 'Internal Server Error';

  res.status(statusCode).json({
    status: err.status,
    message
  });
};

module.exports = { AppError, errorHandler };

解释

  • AppError 自定义错误类,包含状态码和错误类型。
  • errorHandler 中间件统一处理错误并返回 JSON 响应。

🔹 5. 实现完整的日志与错误管理

📦 将日志记录和错误处理集成到 Express 应用中。

(1) 示例
const express = require('express');
const { logger } = require('./logger'); // 引入日志器
const { AppError, errorHandler } = require('./errors'); // 引入错误处理模块

const app = express();

// 测试路由
app.get('/test', (req, res, next) => {
  try {
    throw new AppError('Something went wrong!', 500);
  } catch (err) {
    next(err); // 将错误传递给错误处理中间件
  }
});

// 错误处理中间件
app.use(errorHandler);

// 启动服务器
app.listen(3000, () => {
  logger.info('Server is running on http://localhost:3000');
});

解释

  • next(err) 将错误传递给 errorHandler 中间件。
  • logger.info 记录服务器启动日志。

🔹 6. 10 大高频面试题

🎯 以下是关于日志记录与错误处理的常见面试问题及答案:

  1. 问:什么是日志记录?

    • 答:记录应用程序运行状态的过程,用于问题排查和性能监控。
  2. 问:winston 的作用是什么?

    • 答:winston 是一个日志库,支持多种传输方式和日志级别。
  3. 问:如何捕获全局异常?

    • 答:使用 process.on('uncaughtException')process.on('unhandledRejection')
  4. 问:什么是统一的错误响应结构?

    • 答:设计一致的 JSON 格式,包含状态码、错误类型和消息。
  5. 问:如何区分操作性错误和编程错误?

    • 答:通过自定义错误类(如 AppError)标记操作性错误。
  6. 问:如何记录日志到文件?

    • 答:使用 winston.transports.File
  7. 问:如何处理未捕获的 Promise 拒绝?

    • 答:监听 unhandledRejection 事件。
  8. 问:日志级别有哪些?

    • 答:常见的有 infowarnerrordebug
  9. 问:为什么需要统一的错误响应?

    • 答:提升 API 的可维护性和用户体验。
  10. 问:如何退出进程以防止未捕获异常导致的崩溃?

    • 答:调用 process.exit(1)

📝 练习任务

  1. 使用 winston 实现日志记录功能,并将日志输出到文件。
  2. 设计一个自定义错误类,并在 Express 应用中实现统一的错误响应。

🔁 拓展建议

✨ 如果你想进一步提升,可以尝试以下拓展任务:

  1. 学习如何将日志存储到远程服务(如 Elasticsearch)。
  2. 研究如何结合 APM 工具(如 New Relic)进行性能监控。
  3. 学习如何实现更细粒度的日志过滤和格式化。

🏆 总结

🎉 本节课我们学习了日志记录与错误处理的基本方法,掌握了如何使用 winston 记录日志、捕获全局异常以及设计统一的错误响应结构。通过实战案例和高频面试题,相信你已经能够在应用中实现健壮的日志和错误管理机制!下一节课我们将学习文件上传与下载的实现方法。期待与大家再次见面!


希望老曹这节课对你有所帮助,我们下节课见! 😊

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全栈前端老曹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值