当运营向我们上报BUG时,我们第一时间是捕获相关的接口。从监控系统中,就可以查到用户使用时接口的请求和响应数据。

  若接口的请求正常,那么就需要深入到接口代码中,查看相关的日志,通常会先浏览数据库查询语句以及内部接口的通信日志。

  在本地也可以查看到上述日志,但有个问题,有时候打开某个页面会报错,那是因为本地的数据库没有与测试或正式环境的同步。

  可能是有些字段缺失了,也可能是某张表缺失了,情况比较多。所以,最保险的是在测试或正式环境查看。

  在这两个环境中,都有日志管理系统,但日志量是非常巨大的,若要查找某一条记录,就得有非常精确的过滤条件,并且日志无法连续。

  这条日志下面的一条,很可能是另外一个接口留下的,因此,需要一个小工具能查看到指定接口的日志,解决日常开发的一个痛点。

一、搜集日志

1)管理系统

  首先需要将需要的日志搜集起来,我使用了一个比较简单的方法。

  就是在启动文件中,新增一个全局的logMessages变量,声明为一个空数组。

global.logMessages = [];

  然后在MongoDB、MySQL、请求内部接口函数中,将他们的查询语句日志和通信日志塞入logMessages数组内。

mongoose.set('debug', (...args) => {
logger.debug(...args);
global.logMessages.push(args);
});
new Sequelize(database, username, password, {
...options,
logging: (msg, benchmark) => {
logger.debug(msg, `${benchmark}ms`);
global.logMessages.push(msg);
}
});

  再新增一个中间件(Server项目基于KOA2),这个中间件的作用就是清空logMessages数组,免得将所有接口的日志都搜集起来,因为我只要一个接口的日志。

export default () => async (ctx, next) => {
//每次请求清空要读取的日志数组
global.logMessages.length = 0;
await next();
};

  这么设计会有一个问题,服务器在处理多个请求(高并发)时,互相会影响各自的日志搜集,可能会出现这个接口日志中夹杂着另一个接口的日志,也可能是搜集到一半的日志就被清除了。

  当然,在测试环境,这种情况可以控制住。但是测试环境有时候数据不完整,逻辑可能走不下去,得上生产环境,那生产环境就有概率出现上述问题。

  后面将中间件去除,logMessages变量在一个接口中声明,这个接口就是下面界面中点提交时请求的接口,能解决日志被无故清除的问题,但还是会出现串线的问题。

  生产环境暂时无解,好在还有一个预发环境,它使用的数据源和生产是相同的,只要保证代码和生产同步,那么就能得到想要的日志列表。

2)Web API

  Web API是另一个接口服务,也需要监控其中的日志,但是它与之前的管理系统不同,它是一个独立的服务。

  也就是说,我无法直接在管理系统中通过 global.logMessages 读取日志。

  一开始是想将日志写入缓存中,然后在管理系统中读取缓存中的日志,不过这样做不仅太绕,平添复杂度,而且日志写法也会与之前的不一致。

  于是否决了此方案,改用一个中间件,日志的写入和读取与之前保持一致。不同点是在一个中间件中,将日志作为响应的参数返回。

  在下面的代码中,当需要日志时,我会带上一个特殊的参数:isLogMessages,只有这个参数存在时,才表示需要返回记录。

export default () => async (ctx, next) => {
// 只有带了特殊参数的请求,才会把接口日志带上
const isLogMessages = ctx.query.isLogMessages || ctx.request.body.isLogMessages;
if(isLogMessages) {
global.logMessages = [];
}
await next();
if(isLogMessages) {
const { body } = ctx;
if(typeof body === 'string') {
ctx.body = {
data: body
};
}else {
ctx.body = {
...body
}
}
ctx.body.logMessages = global.logMessages;
delete global.logMessages;
}

二、界面

  在完成上述的日志搜集之后,就需要有一张操作界面(如图所示),提升我们组自己的用户体验,借助之前封装的模板组件,搭建这样一个页面几十分钟就好了。

  

  界面中包括API路径、方法、项目和参数,其中参数可动态增加,点击提交就会开始模拟请求接口,得到日志(如图所示)和响应。

  

  这样一套操作之后,就能马上知道接口内的细节,可帮助我们快速定位问题,也是一种降低时间成本的手段。

Node.js躬行记(10)——接口日志查询的更多相关文章

  1. Node.js躬行记(21)——花10分钟入门Node.js

    Node.js 不是一门语言,而是一个基于 V8 引擎的运行时环境,下图是一张架构图. 由图可知,Node.js 底层除了 JavaScript 代码之外,还有大量的 C/C++ 代码. 常说 Nod ...

  2. Node.js躬行记(8)——通用接口

    一.GraphQL 最近服务端的同事分享了GraphQL,他分享的目的就是要把我们与他们的数据库隔离,这么做我们也求之不得. 我们组目前维护着一个后台管理系统,会直接读取数据库中的表,如果能隔离的话, ...

  3. Node.js躬行记(1)——Buffer、流和EventEmitter

    一.Buffer Buffer是一种Node的内置类型,不需要通过require()函数额外引入.它能读取和写入二进制数据,常用于解析网络数据流.文件等. 1)创建 通过new关键字初始化Buffer ...

  4. Node.js躬行记(2)——文件系统和网络

    一.文件系统 fs模块可与文件系统进行交互,封装了常规的POSIX函数.POSIX(Portable Operating System Interface,可移植操作系统接口)是UNIX系统的一个设计 ...

  5. Node.js躬行记(4)——自建前端监控系统

    这套前端监控系统用到的技术栈是:React+MongoDB+Node.js+Koa2.将性能和错误量化.因为自己平时喜欢吃菠萝,所以就取名叫菠萝系统.其实在很早以前就有这个想法,当时已经实现了前端的参 ...

  6. Node.js躬行记(6)——自制短链系统

    短链顾名思义是一种很短的地址,应用广泛,例如页面中有一张二维码图片,包含的是一个原始地址(如下所示),如果二维码中的链接需要修改,那么就得发代码替换掉. 原始地址:https://github.com ...

  7. Node.js躬行记(19)——KOA源码分析(上)

    本次分析的KOA版本是2.13.1,它非常轻量,诸如路由.模板等功能默认都不提供,需要自己引入相关的中间件. 源码的目录结构比较简单,主要分为3部分,__tests__,lib和docs,从名称中就可 ...

  8. Node.js躬行记(23)——Worker threads

    Node.js 官方提供了 Cluster 和 Child process 创建子进程,通过 Worker threads 模块创建子线程.但前者无法共享内存,通信必须使用 JSON 格式,有一定的局 ...

  9. Node.js躬行记(15)——活动规则引擎

    在日常的业务开发中,会包含许多的业务规则,一般就是用if-else硬编码的方式实现,这样就会增加逻辑的维护成本,若无注释,可能都无法理解规则意图. 因为一旦规则有所改变,那么就需要修改代码再发布代码, ...

随机推荐

  1. 流动的观察者模式 | Flutter 设计模式

    观察者模式,又称发布订阅模式,是一种行为设计模式--你可以定义一种订阅机制,可在对象事件发生时通知多个 观察 该对象的其他对象. 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主 ...

  2. S3C2440—6.串口的printf实现

    文章目录 一.框架 二.printf函数原理 2.1 printf的声明 2.2 参数解读 2.3 如何得到可变参数的值 2.4 解决变参的宏定义 2.5 完成printf函数的封装 三.结合UART ...

  3. 内存吞金兽(Elasticsearch)的那些事儿 -- 常见问题痛点及解决方案

    1.大数据量的查询效率如何保证: 查询的流程:往 ES 里写的数据,实际上都写到磁盘文件里去了,查询的时候,操作系统会将磁盘文件里的数据自动缓存到 Filesystem Cache 里面去 最佳的情况 ...

  4. 题解 party?

    传送门 挺遗憾的一个题 考场上想到的思路是题解的退化版,可以有71pts(赛时以为只有20pts),但因为这一场的策略原因没有打-- 首先发现颜色种类数很少,可以直接bitset上树剖维护,炸不了空间 ...

  5. mysql事务的4大特性

    事务的四大特性(简称ACID) 1.原子性(Atomicity) 事务是数据库的逻辑工作单位,事务中包括的诸操作要么全做,要么全不做. 2.一致性(Consistency) 事务执行的结果必须是使数据 ...

  6. elasticsearch可视化工具-dejavu

    https://github.com/appbaseio/dejavu docker run -p 1358:1358 -d appbaseio/dejavu http.port: 9200 http ...

  7. javascript,html,正则表达式,邮箱密码验证

    <!DOCTYPE html> <html>     <head>         <meta charset="utf-8">   ...

  8. reduce使用技巧

    一.使用reduce同时执行map(循环)和filter(过滤) 例如,将数组中的项的值加倍,然后只选择那些大于50的项 const numbers = [10, 20, 30, 40]; const ...

  9. 流媒体 Ubuntu部署srs、windows部署nginx

    一.获取项目//码云克隆git clone https://gitee.com/winlinvip/srs.oschina.git srs//githubgit clone https://githu ...

  10. (二)js基础。。。freecodecamp笔记

    个人需要注意的点 当 JavaScript 中的变量被声明的时候,程序内部会给它一个初始值undefined.当你对一个值为undefined的变量进行运算操作的时候,算出来的结果将会是NaN,NaN ...