返回顶部
首页 > 资讯 > 前端开发 > JavaScript >在node中如何打印全链路日志
  • 744
分享到

在node中如何打印全链路日志

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

这篇文章给大家分享的是有关在node中如何打印全链路日志的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。当用户报问题:线上某个功能使用报错时,如何快速准确地定位?当某个请求接口返回

这篇文章给大家分享的是有关在node中如何打印全链路日志的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

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

一、原理和实践

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

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,就可以做分析了。

二、性能开销

我本地做了一下压测,

这是内存的占用对比:

在node中如何打印全链路日志

比未使用async_hook多了约10%。

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

感谢各位的阅读!关于“在node中如何打印全链路日志”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: 在node中如何打印全链路日志

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

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

猜你喜欢
  • 在node中如何打印全链路日志
    这篇文章给大家分享的是有关在node中如何打印全链路日志的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。当用户报问题:线上某个功能使用报错时,如何快速准确地定位?当某个请求接口返回...
    99+
    2024-04-02
  • 如何用node优雅地打印全链路日志
    目录前言一、原理和实践二、性能开销总结前言 当用户报问题:线上某个功能使用报错时,如何快速准确地定位?当某个请求接口返回数据缓慢时,如何有效地追踪优化? 一、原理和实践 众所周知,当...
    99+
    2024-04-02
  • idea如何打印全部的日志
    要打印全部的日志,可以参考以下方法: 设置日志级别:将日志级别设置为最低级别(如DEBUG),确保所有日志信息都会被记录。 ...
    99+
    2023-10-25
    idea
  • python中如何打印日志信息
    日志打印方式 常见的Python日志打印方式为使用内置函数print()或者logging模块打印日志。 print()只能将日志打印至控制台,不推荐此方式logging模块默认将日志打印至控制台,也...
    99+
    2023-09-05
    python
  • Android中安全地打印日志的示例
    这篇文章主要介绍了Android中安全地打印日志的示例,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。在Android开发过程中,不管是写Demo还是实战项目中,都会打印一些日...
    99+
    2023-05-30
  • Log4j如何配置日志打印时区
    小编给大家分享一下Log4j如何配置日志打印时区,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!og4j版本:2.8.1开发桌面程序时遇到一个问题,idea中日志时间和CMD中jar包运行日志时间都正常,使用exe4j打成的...
    99+
    2023-05-30
  • Java 程序如何正确地打印日志?
    在 Java 开发中,打印日志是一项非常重要的工作。正确的打印日志可以帮助我们快速定位问题,并提高代码的可维护性和可读性。本文将为大家介绍 Java 程序如何正确地打日志,希望对大家有所帮助。 一、为什么需要打印日志 在开发过程中,我们...
    99+
    2023-09-28
    java log4j apache 开发语言 docker
  • 如何使用logback实现日志打印过滤
    这篇文章主要为大家展示了“如何使用logback实现日志打印过滤”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何使用logback实现日志打印过滤”这篇文章吧。logback日志打印过滤1.只...
    99+
    2023-06-20
  • linux日志打印无法更新如何解决
    要解决Linux日志打印无法更新的问题,可以尝试以下方法:1. 检查文件权限:确保日志文件的权限设置正确,允许写入操作。可以使用 `...
    99+
    2023-09-13
    linux
  • springboot如何整合mybatis将sql打印到日志
    这篇文章主要介绍了springboot如何整合mybatis将sql打印到日志,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。在前台请求数据的时候,sql语句一直都是打印到控制...
    99+
    2023-05-30
    mybatis spring boot
  • Log4j如何屏蔽某个类的日志打印
    目录Log4j屏蔽某个类的日志打印Log4j屏蔽指定日志Log4j屏蔽某个类的日志打印 项目中使用的是log4j.properties的方式配置,在项目启动后有一个任务每隔半小时会运...
    99+
    2024-04-02
  • springboot下mybatis-plus如何打印sql日志和参数到日志文件
    最近在使用springboot过程中用到了mybatis-plus ,springboot版本是2.3.1.RELEASE,mybatis-plus 版本3.2.0。 ...
    99+
    2024-04-02
  • 如何在 Go 中打印?
    学习Golang要努力,但是不要急!今天的这篇文章《如何在 Go 中打印?》将会介绍到等等知识点,如果你想深入学习Golang,可以关注我!我会持续更新相关文章的,希望对大家都能有所帮助!问题内容我...
    99+
    2024-04-04
  • 聊聊如何打印GC日志排查的问题
    目录如何打印GC日志排查问题先来看个示例那么上面打印出来的日志,具体是什么意思呢?小结一下gc日志打印时间戳如何打印GC日志排查问题 在工作当中,有时候我们会需要打印GC的相关信息来...
    99+
    2024-04-02
  • SpringMVC框架中如何使用Filter实现请求日志打印
    这篇文章主要为大家展示了“SpringMVC框架中如何使用Filter实现请求日志打印”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“SpringMVC框架中如何使用Filter实现请求日志打印”...
    99+
    2023-06-25
  • SpringBoot2中如何配置Log4j2实现不同环境日志打印
    这篇文章主要介绍了SpringBoot2中如何配置Log4j2实现不同环境日志打印,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、Log4j2日志简介日志打印是了解Web项...
    99+
    2023-06-02
  • 你知道如何在Java中打包Unix日志吗?
    在Java中打包Unix日志是一个非常常见的需求。Unix日志通常被存储在单独的文件中,每个文件代表一天或一周的日志。为了方便管理和传输,我们通常需要将这些日志文件打包成一个压缩文件,例如tar.gz或zip格式。本文将介绍如何使用Java...
    99+
    2023-11-14
    unix 日志 打包
  • 如何在Java中处理Unix日志打包问题?
    Unix系统是一种广泛使用的操作系统,它的日志文件格式也是非常常见的。在Unix系统中,日志文件的记录方式是以文本形式存储在文件中,这些日志文件有时需要被打包压缩,以便于传输或备份。在Java中,如何处理这些Unix日志打包问题呢?本文将...
    99+
    2023-11-14
    unix 日志 打包
  • 如何在Java中读取Unix系统中的路径日志?
    在Unix系统中,路径日志是一种非常有用的信息资源,它记录了系统中所有路径的使用情况,包括文件、目录、链接等等。在Java中,读取Unix系统中的路径日志也非常方便,本文将向您介绍如何实现这一功能。 一、了解Unix系统中的路径日志 Uni...
    99+
    2023-10-03
    unix 日志 path
  • java如何实现统一打印入参出参等日志
    这篇文章主要介绍“java如何实现统一打印入参出参等日志”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“java如何实现统一打印入参出参等日志”文章能帮助大家解决问题。1.背景   ...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作