保护我方输出nodejs(三)

node(14.2) 官网API

进阶API

进阶模块主要包括 性能分析模块和实验模块

assert

assert 模块提供了一组断言函数,用于验证不变量。

  • 断言

    断言是对程序某些假设的检查,用来精确捕获程序逻辑的错误,能够做一些类似预处理的事情

  • 断言与异常

    断言注重程序逻辑的错误,异常注重语法,环境等不可控因素导致的错误

断言以及单元测试库

断言经常被应用在单元测试中,下面列举常用的node断言和测试框架

  • 断言库

    1. assert node自带断言库,提供简单的断言处理
    2. shouldjs should拥有丰富的断言类型,提供符合语义描述的语法
    3. expectjs expectjs 是fb开源的断言库,现已合并到jest框架中
    4. chai chai提供了should、expect和assert三种风格的断言方式
  • 单元测试框架

    1. jest fb开源的测试框架,只支持expect
    2. mocha 生态丰富的测试框架,不限制断言库,常配合chai使用

async_hooks / domain

async_hooks 和 domain 提供了对异步资源追踪和处理的能力,domain模块已被官方废弃,async_hooks作为domian的补充,但当前仍是实验性模块

  • 异常和监控

    try...catch...可以捕获大部分的异常,但不能捕获异步错误,所以对于异步错误的处理更多是通过监听异常事件process.on('uncaughtException', function (err) {});来完成,这导致node的异常处理和监控变得很棘手,所以相继推出了 domain 和 async_hooks 来完成对node异步的监控

  • async_hooks 生成traceId

    async_hooks 对每一个函数(不论异步还是同步)提供了一个 async scope,我们可以通过调用 async_hooks.executionAsyncId() 来获取函数当前的 async scope 的 id(称为 asyncId),通过调用 async_hooks.triggerAsyncId() 来获取当前函数调用者的 asyncId(即triggerAsyncId)。

    async_hooks.createHook 可以注册 4 个方法来跟踪所有异步资源的初始化(init)、回调之前(before)、回调之后(after)、销毁后(destroy)事件,并通过调用 .enable() 启用,调用 .disable() 关闭。

    异步资源在创建时触发 init 事件函数,init 函数中的第 1 个参数代表该异步资源的 asyncId,type 表示异步资源的类型(例如 TCPWRAP、PROMISE、Timeout、Immediate、TickObject 等等),triggerAsyncId 表示该异步资源的调用者的 asyncId。异步资源在销毁时触发 destroy 事件函数,该函数只接收一个参数,即该异步资源的 asyncId。

    在以上特性的支持下,就可以根据triggerAsyncId和asyncId的关系定位到函数之间的调用链关系,随即可以生成traceId完成链路调用的日志记录,以下是构造全链路traceId的代码

    'use strict'
    const asyncHooks = require('async_hooks');
    const fs = require('fs')
    const uuid = require('uuid').v4
    const writStream = fs.createWriteStream('trace.log')
    
    // 存储上下文
    const logCtxs = new Map()
    // 通过asyncHooks的init 和 destroy 维护和追踪上下文关系
    asyncHooks.createHook({
         
        init,
        destroy
    }).enable();
    
    // 维护异步调用关系
    function init(asyncId, type, triggerAsyncId) {
         
        const ctx = getCtx(triggerAsyncId)
        if (ctx) {
         
            logCtxs.set(asyncId, ctx)
        } else {
         
            logCtxs.set(asyncId, triggerAsyncId)
        }
    
    }
    // 删除失效对象
    function destroy(asyncId) {
         
        logCtxs.delete(asyncId)
    }
    
    function getCtx(tid) {
         
        if (!tid) {
         
            return
        }
        if (typeof tid === 'object') {
         
            return tid
        }
    
        return getCtx(logCtxs.get(tid))
    }
    
    function log(args){
         
        const [trigger, asyncId] = [asyncHooks.triggerAsyncId(), asyncHooks.executionAsyncId()]
        const ctx = getCtx(asyncId)
        fs.writeSync(1, `{asyncId: ${
           asyncId}, trigger: ${
           trigger}, ctx: ${
           JSON.stringify(ctx)} }: ${
           args}\n\n`)
    }
    
    exports.log = log
    exports.logger =  function logger() {
         
    
        return async (ctx, next) => {
         
            let reqContent = {
         main:ctx, traceId
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值