返回顶部
首页 > 资讯 > 前端开发 > JavaScript >如何用node优雅地打印全链路日志
  • 472
分享到

如何用node优雅地打印全链路日志

2024-04-02 19:04:59 472人浏览 八月长安
摘要

目录前言一、原理和实践二、性能开销总结前言 当用户报问题:线上某个功能使用报错时,如何快速准确地定位?当某个请求接口返回数据缓慢时,如何有效地追踪优化? 一、原理和实践 众所周知,当

前言

当用户报问题:线上某个功能使用报错时,如何快速准确地定位?当某个请求接口返回数据缓慢时,如何有效地追踪优化

一、原理和实践

众所周知,当一个请求到来时,大概会有以下日志产生:

1、AceesLog:用户访问日志

2、Exception:代码异常日志

3、sql:sql查询日志

4、ThirdParty:第三方服务日志

该如何追踪一条请求产生的所有日志?

一般做法是使用一个requestId来做唯一标识,

然后写一个中间件,把requestId注入到context上下文中,当需要打日志时,再从context中取出打印,

在第三方服务和SQL日志中,还需要把requestId传入到相应的函数里面打印,这样层层传递,实在太麻烦,代码侵入性也比较强。

我们的目标是降低代码侵入性,一次注入,自动跟踪。

经过调研,async_hooks可以追踪异步行为的生命周期,在每个异步资源(每个请求都是一个异步资源)中,它都有2个ID,

分别是asyncId(异步资源当前生命周期ID),trigerAsyncId(父级异步资源ID)。

async_hooks提供了以下生命周期钩子来监听异步资源:

asyncHook = async_hook.createHook({
  // 监听异步资源的创建
  init(asyncId,type,triggerAsyncId,resource){},
  // 异步资源回调函数开始执行之前
  before(asyncId){},
  // 异步资源回调函数开始执行后
  after(asyncId){},
  // 监听异步资源的销毁
  destroy(asyncId){}
})

那如果我们做一个映射,每个asyncId映射一个storage,storage里面再存储对应的requestId,那requestId就可以很容易获取了。

正好cls-hooked这个库已经基于async_hooks做好了封装,在同一份异步资源维护一份数据,以键值对的形式存储。(注意:async_hooked需要在高版本node>=8.2.1使用)当然社区中还有其他的实现,比如cls-session,node-continuation-local-storage等。

下面讲下我把cls-hooked运用在我项目中的实例:

/session.js 创建命名存储空间

const createNamespace = require('cls-hooked').createNamespace 
const session = createNamespace('requestId-store') 
module.exports = session

/logger.js 打印日志

const session = require('./session') 
module.exports = { 
info: (message) => 
{ 
const requestId = session.get('requestId')
console.log(`requestId:${requestId}`, message) 
}, 
error: (message) => 
{ 
const requestId = session.get('requestId') 
console.error(`requestId:${requestId}`, message) 
} 
}

/sequelize.js sql调用logger打印日志

const logger = require("./logger") 
new Sequelize( 
logging: function (sql, costtime) { 
logger.error( `sql exe : ${sql} | costtime ${costtime} ms` ); 
} )

/app.js 设置requestId、设置requestId返回响应头、打印访问日志

const session = require('./session') 
const logger = require('./logger') 
async function accesshandler(ctx, next) 
{ 
const requestId = ctx.header['x-request-id'] || uuid()
const params = ctx.request.body ? JSON.stringify(ctx.request.body) : JSON.stringify(ctx.request.query)
// 设置requestId session.run(() => { session.set('requestId', requestId)
logger.info(`url:${ctx.request.path};params:${params}`) next()
// 设置返回响应头
ctx.res.setHeader('X-Request-Id',requestId)
}) }

我们看下当一条请求路径是/home?a=1到来时的日志:

访问日志:
requestId:79f422a6-6151-4bfd-93ca-3c6f892fb9ac url:/home;params:{"a":"1"}

Sql日志:
requestId:79f422a6-6151-4bfd-93ca-3c6f892fb9ac sql exe :
Executed (default): SELECT `id` FROM t_user

可以看到同一条请求整个链路的日志requestId是一样的。如果后面有告警发到告警平台,那么我们根据requestId就可以找到这条请求执行的整个链路了。

细心的同学可能会观察到我在接口返回的响应头里面也设置了requestId,目的就是为了后续如果发现某条请求响应缓慢或者有问题,那直接从浏览器就可以知道requestId,就可以做分析了。

二、性能开销

我本地做了一下压测,

这是内存的占用对比:

比未使用async_hook多了约10%。

对于我们qps是百级别的系统还好,但是如果是高并发的服务,可能要慎重考虑下了。

总结

到此这篇关于如何用node优雅地打印全链路日志的文章就介绍到这了,更多相关node打印全链路日志内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 如何用node优雅地打印全链路日志

本文链接: https://lsjlt.com/news/141621.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何用node优雅地打印全链路日志
    目录前言一、原理和实践二、性能开销总结前言 当用户报问题:线上某个功能使用报错时,如何快速准确地定位?当某个请求接口返回数据缓慢时,如何有效地追踪优化? 一、原理和实践 众所周知,当...
    99+
    2024-04-02
  • 在node中如何打印全链路日志
    这篇文章给大家分享的是有关在node中如何打印全链路日志的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。当用户报问题:线上某个功能使用报错时,如何快速准确地定位?当某个请求接口返回...
    99+
    2024-04-02
  • idea如何打印全部的日志
    要打印全部的日志,可以参考以下方法: 设置日志级别:将日志级别设置为最低级别(如DEBUG),确保所有日志信息都会被记录。 ...
    99+
    2023-10-25
    idea
  • Java 程序如何正确地打印日志?
    在 Java 开发中,打印日志是一项非常重要的工作。正确的打印日志可以帮助我们快速定位问题,并提高代码的可维护性和可读性。本文将为大家介绍 Java 程序如何正确地打日志,希望对大家有所帮助。 一、为什么需要打印日志 在开发过程中,我们...
    99+
    2023-09-28
    java log4j apache 开发语言 docker
  • Java开发中如何优雅地处理日志?
    在Java开发中,日志处理是非常重要的一环。它可以帮助我们及时发现并解决系统中的问题,提升系统的可靠性和稳定性。但是,如果不合理地处理日志,就会造成不必要的性能浪费,甚至会给系统带来安全隐患。那么,在Java开发中,如何优雅地处理日志呢?...
    99+
    2023-09-05
    日志 开发技术 分布式
  • 如何在PHP编程中优雅地处理日志文件?
    在PHP编程中,日志文件是一个非常重要的部分。它可以记录系统的状态、错误信息、访问记录等,对于开发者来说,日志文件是调试程序以及分析问题的重要工具。然而,处理日志文件却是一个枯燥乏味的过程,因此本篇文章将介绍如何在PHP编程中优雅地处理日志...
    99+
    2023-06-18
    日志 编程算法 文件
  • 如何在ASP教程中优雅地处理框架日志?
    ASP.NET 是一个广泛使用的 Web 应用程序框架,它提供了一种简单和高效的方式来构建可靠的 Web 应用程序。但是,在构建 ASP.NET 应用程序时,处理框架日志是一个必不可少的任务。在本文中,我们将介绍如何在 ASP.NET 教程...
    99+
    2023-07-02
    教程 框架 日志
  • Go 函数在 Bash 中的应用:如何优雅地记录日志?
    日志是软件开发中不可或缺的一部分,记录应用程序的运行状态、错误信息以及用户行为等,是排查问题、优化性能、做出决策的重要依据。在 Bash 脚本中,记录日志也是必不可少的一项任务。本文将介绍如何使用 Go 函数在 Bash 中优雅地记录日志...
    99+
    2023-06-30
    函数 bash 日志
  • 精通Python中的Numpy容器:如何优雅地记录日志?
    Python是一门强大的编程语言,被广泛应用于数据分析、机器学习、人工智能等领域。在Python中,Numpy是一个非常重要的容器,它提供了高效的数值计算和矩阵运算功能。在实际开发中,我们经常需要记录程序的运行情况和输出结果,这就需要使用日...
    99+
    2023-09-08
    容器 numpy 日志
  • 如何使用logback实现日志打印过滤
    这篇文章主要为大家展示了“如何使用logback实现日志打印过滤”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何使用logback实现日志打印过滤”这篇文章吧。logback日志打印过滤1.只...
    99+
    2023-06-20
  • PHP 并发处理中如何优雅地实现日志重定向?
    随着互联网的快速发展,Web 应用程序的规模越来越大,处理的数据量也越来越大。在这种情况下,为了提高应用程序的性能和响应速度,我们需要采用并发处理技术来处理大量的请求。 然而,并发处理也带来了一些问题,例如:多个并发请求可能会同时写入日志...
    99+
    2023-06-30
    并发 日志 重定向
  • 如何使用配置文件优雅地配置 Logger,同时支持日志轮转
    php小编子墨将为大家分享如何使用配置文件来优雅地配置Logger,并实现日志轮转的方法。Logger是一个常用的日志记录工具,它可以帮助我们记录应用程序的运行状态,便于排查问题和追踪...
    99+
    2024-02-10
  • GO语言的异步编程模型:如何优雅地处理文件和日志?
    随着互联网的发展,异步编程模型在软件开发中变得越来越常见。GO语言作为一种高效的编程语言,也具备了异步编程的能力。在这篇文章中,我们将探讨GO语言的异步编程模型,并展示如何使用它来优雅地处理文件和日志。 一、GO语言的异步编程模型 在传统...
    99+
    2023-09-27
    异步编程 文件 日志
  • SpringMVC框架中如何使用Filter实现请求日志打印
    这篇文章主要为大家展示了“SpringMVC框架中如何使用Filter实现请求日志打印”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“SpringMVC框架中如何使用Filter实现请求日志打印”...
    99+
    2023-06-25
  • 如何在Java项目中优雅地使用NPM和LeetCode进行打包?
    Java是一种广泛使用的编程语言,而NPM和LeetCode则是两个非常强大的工具,用于在Java项目中进行打包和测试。在本文中,我们将讨论如何在Java项目中优雅地使用NPM和LeetCode进行打包。 首先,让我们来了解一下NPM是什么...
    99+
    2023-07-30
    npm leetcode 打包
  • Python日志打包load:如何在项目中更好地使用它?
    日志是软件开发中必不可少的一部分。它可以帮助开发人员快速定位问题并调试程序。Python作为一种流行的编程语言,自然也有自己的日志系统。Python的日志系统非常灵活,可以根据不同的需求进行配置和使用。本文将介绍Python的日志系统中的...
    99+
    2023-10-29
    日志 打包 load
  • Bash重定向的全面解析:Python如何优雅地在Linux中应用?
    Bash是Linux和macOS操作系统中广泛使用的命令行解释器。它提供了一种强大的机制来处理文件和输入/输出流。其中一个最重要的机制是重定向。在本文中,我们将探讨Bash重定向的工作原理,并演示如何使用Python在Linux中优雅地应...
    99+
    2023-08-30
    linux bash 重定向
  • 如何使用PHP响应路径日志来提高网站安全性?
    随着互联网的普及,网站安全性成为了一个越来越重要的话题。为了保护网站免受恶意攻击,网站管理员需要不断寻找新的方法来提高网站的安全性。其中一种常见的方法是使用PHP响应路径日志。 什么是PHP响应路径日志? PHP响应路径日志是一种记录服务器...
    99+
    2023-08-03
    响应 path 日志
  • 如何在 ASP 中有效地使用打包函数和日志记录功能?
    ASP是一种流行的服务器端脚本语言,用于构建动态网站和Web应用程序。在ASP中,打包函数和日志记录功能是非常重要的组成部分,它们可以帮助程序员更有效地编写代码和诊断问题。在本文中,我们将探讨如何在ASP中使用这些功能。 一、打包函数 打包...
    99+
    2023-06-28
    打包 函数 日志
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作