Node.js躬行記(10)——接口日志查詢


  當運營向我們上報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路徑、方法、項目和參數,其中參數可動態增加,點擊提交就會開始模擬請求接口,得到日志(如圖所示)和響應。

  

  這樣一套操作之后,就能馬上知道接口內的細節,可幫助我們快速定位問題,也是一種降低時間成本的手段。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM