iT邦幫忙

2024 iThome 鐵人賽

DAY 11
1
DevOps

全端監控技術筆記---從Sentry到Opentelemetry系列 第 11

Day11---Sentry在NodeJS中的錯誤監控

  • 分享至 

  • xImage
  •  

前言

在前一篇的demo中,我們了解到Sentry在NodeJS+express的應用中,是用Sentry.setupExpressErrorHandler(app)來獲取應用中的錯誤。那麼為何要在所有controller之後才呼叫Sentry的錯誤處理中間件呢?這就要聊到express middleware的機制。

express middleware

一般來說,middleware可以分為三種主要類型:

  • 全局處理的middleware---如解析請求、跨域設定、記錄每個請求到log等
  • 特定路由的middleware---需要認證、限定權限的路由、特殊邏輯處理等等
  • 錯誤處理的middleware---專門處理應用中的錯誤

全局處理的 middleware

例如常見的

app.use(express.json());  // 處理 JSON body
app.use(cors());  // 處理 CORS
app.use(logger('dev'));  // 請求日誌

這些通常會放在controller之前,因為無論是什麼路由,這些操作都需要執行。

特定路由的 middleware

這些 middleware 只應用於某些路由,比如身份驗證、權限檢查或自定義邏輯處理。這些 middleware 可以和路由處理器一起使用,放置在相應的路由之前。

// 只對 `/admin` 路由進行身份驗證
app.use('/admin', authenticateAdmin);  
app.get('/admin/dashboard', (req, res) => {
    res.send('Welcome to the admin dashboard');
});

錯誤處理的 middleware

這類 middleware 必須放在所有路由和其他 middleware 之後,因為它需要捕捉前面的 controller 或 middleware 未處理的錯誤。放在最後確保錯誤可以被集中處理,避免應用崩潰。

// 所有路由和controller之後
app.use((err, req, res, next) => {
    console.error(err.stack);
    res.status(500).send('Something broke!');
});

所以Sentry.setupExpressErrorHandler(app);才需要放在所有controller之後,為了就是收集所有錯誤、並上傳到Sentry。

自己寫一個類似的

既然了解 Sentry.setupExpressErrorHandler就是express middleware的使用,就可以簡單寫一個了:

class SelfSentry {
    static setupExpressErrorHandler(expressApp) {
        expressApp.use(this._expressErrorHandler());
    }

    static _expressErrorHandler() {
        return (err, req, res, next) => {
            // 這邊就是處理Sentry上報error的邏輯,目前先console出來
            console.log('----in SelfSentry error middleware');
            console.error(err.stack);
            next(error);
        };
    }
}

module.exports = {
    SelfSentry,
};

然後我們來demo看看,運行看看有沒有捕捉到:

const express = require('express');
const cors = require('cors');

const { SelfSentry } = require('./self-sentry');

const app = express();
const PORT = 3060;

app.use(cors());

app.get('/', (req, res) => {
    res.send('hello self error catcher');
});

app.get('/demo-error', (req, res) => {
    throw new Error('---Mock Error');
});

SelfSentry.setupExpressErrorHandler(app);

app.listen(PORT, () => {
    console.log(`server on http://localhost:${PORT}`);
});

terminal console:

image

可以看到拋出的Mock Error已經被我們的錯誤捕捉middleware給捕獲、並console出來。

小結

今天這一篇,我們手寫了一個sdk,仿照Sentry的方式宣告、並成功捕獲了錯誤。本文的完成程式碼可以查看Github repository

接下來,我們將聊聊Sentry對後端服務的性能監控。

ref

ChangeLog

  • 20240925--初稿完成

上一篇
Day10--後端服務與Sentry---以NodeJS為例
下一篇
Day12---NodeJS 在Sentry上的性能監控
系列文
全端監控技術筆記---從Sentry到Opentelemetry13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言