Sentry(v20.12.1) K8S 雲原生架構探索,SENTRY FOR JAVASCRIPT 故障排除

為少發表於2021-01-17

系列

  1. Sentry-Go SDK 中文實踐指南
  2. 一起來刷 Sentry For Go 官方文件之 Enriching Events
  3. Snuba:Sentry 新的搜尋基礎設施(基於 ClickHouse 之上)
  4. Sentry 10 K8S 雲原生架構探索,Vue App 1 分鐘快速接入
  5. Sentry(v20.12.1) K8S雲原生架構探索,玩轉前/後端監控與事件日誌大資料分析,高效能高可用+可擴充套件可伸縮叢集部署
  6. Sentry(v20.12.1) K8S 雲原生架構探索,Sentry JavaScript SDK 三種安裝載入方式
  7. Sentry(v20.12.1) K8S 雲原生架構探索,SENTRY FOR JAVASCRIPT SDK 配置詳解
  8. Sentry(v20.12.1) K8S 雲原生架構探索, SENTRY FOR JAVASCRIPT 手動捕獲事件基本用法
  9. Sentry(v20.12.1) K8S 雲原生架構探索,SENTRY FOR JAVASCRIPT Source Maps 詳解

如果您需要有關 Sentry JavaScript SDK 整合的解決 issues 的幫助,則可以閱讀此處記錄的一些案例。

Debugging Additional Data

您可以檢視事件的 JSON payload,以瞭解 Sentry 如何在事件中儲存其他資料。資料的形狀可能與描述不完全匹配。

有關詳細資訊,請參閱關於 Event Payload 文件

Max JSON Payload Size

maxValueLength 的預設值為 250,但是如果您的訊息較長,則可以根據需要調整此值。請注意,並非每個單個值都受此選項影響。

CORS Attributes and Headers

要了解來自不同來源的指令碼引發的 JavaScript 異常,請執行以下兩項操作:

  1. 新增一個 crossorigin=”anonymous” 指令碼屬性
 <script src="http://another-domain.com/app.js" crossorigin="anonymous"></script>

script 屬性告訴瀏覽器 “anonymously” 地獲取目標檔案。當請求此檔案時,潛在的使用者識別資訊(如 cookie 或 HTTP 憑據)不會被瀏覽器傳輸到伺服器。

  1. 新增一個 Cross-Origin HTTP header
Access-Control-Allow-Origin: *

跨域資源共享(CORS)是一組 API(主要是 HTTP headers),這些 API 決定了應如何跨源下載和服務檔案。

通過設定 Access-Control-Allow-Origin: *,伺服器向瀏覽器指示任何來源都可以獲取該檔案。另外,您可以將其限制為您控制的已知來源:

 Access-Control-Allow-Origin: https://www.example.com

大多數社群 CDN 正確設定了 Access-Control-Allow-Origin 標頭。

 $ curl --head https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.js | \
 grep -i "access-control-allow-origin"

 Access-Control-Allow-Origin: *

instrument.js Line Numbers for Console Log statements

如果在除錯時在控制檯顯示 instrument.js,新增 Sentry 到你的框架 blackboxing ,設定如下:/@sentry/,這樣 Chrome 在除錯時忽略 SDK stackframes。

Dealing with Ad-Blockers

當您使用我們的 CDN 時,廣告攔截(ad-blocking)或指令碼攔截(script-blocking)擴充套件程式可能會阻止我們的 SDK 無法正確獲取和初始化。因此,對 SDKs API 的任何呼叫都將失敗,並可能導致您的應用程式行為異常。如果這適用於您的用例,則以下任何一種解決方案都可以緩解此問題。

處理指令碼阻止擴充套件的最好方法是直接通過 npm 使用SDK軟體包,並將其與您的應用程式捆綁在一起。這樣,您可以確保程式碼將始終如您所願地存在。

第二種方法是從 CDN 下載 SDK 並自己託管。這樣,SDK 仍將與您的其餘程式碼分開,但是您可以確定它不會被阻止,因為它的來源與您網站的來源相同。

您可以使用 curl 或任何其他類似的工具輕鬆獲取它:

curl https://browser.sentry-cdn.com/5.20.1/bundle.min.js -o sentry.browser.5.20.1.min.js -s

最後一個選項是使用 Proxy 防護,即使您呼叫被阻止的 SDK,也可以確保您的程式碼不會中斷。除 Internet Explorer 之外,所有瀏覽器均支援 Proxy,儘管該瀏覽器沒有擴充套件。同樣,如果您的使用者瀏覽器中沒有安裝 Proxy,它也會被靜默跳過,因此您不必擔心它會破壞任何東西。

將此片段放在包含我們的 CDN bundle 軟體的 <script> 標記上方。可讀格式的程式碼段顯示如下:

if ("Proxy" in window) {
  var handler = {
    get: function(_, key) {
      return new Proxy(function(cb) {
        if (key === "flush" || key === "close") return Promise.resolve();
        if (typeof cb === "function") return cb(window.Sentry);
        return window.Sentry;
      }, handler);
    },
  };
  window.Sentry = new Proxy({}, handler);
}

如果你想直接複製和貼上程式碼片段,這裡是縮小過後的:

<script>
  if ("Proxy" in window) {
    var n = {
      get: function(o, e) {
        return new Proxy(function(n) {
          return "flush" === e || "close" === e
            ? Promise.resolve()
            : "function" == typeof n
            ? n(window.Sentry)
            : window.Sentry;
        }, n);
      },
    };
    window.Sentry = new Proxy({}, n);
  }
</script>

Using a Client directly

為了能夠管理多個 Sentry 例項而彼此之間沒有任何衝突,您需要建立自己的 Client。如果您的應用程式整合在其中,這也有助於防止跟蹤任何父應用程式錯誤。在此示例中,我們使用 @sentry/browser,但它也適用於 @sentry/node

import { BrowserClient } from "@sentry/browser";

const client = new BrowserClient({
  dsn: "___PUBLIC_DSN___",
});

client.captureException(new Error("example"));

儘管上面的示例工作得很好,但是 Client 上缺少諸如 configureScopewithScope 的某些方法,因為 Hub 負責狀態管理。這就是為什麼建立一個新的 Hub 並將其 Client 繫結到它上可能更容易的原因。結果是相同的,但是您還將獲得狀態管理。

import { BrowserClient, Hub } from "@sentry/browser";

const client = new BrowserClient({
  dsn: "___PUBLIC_DSN___",
});

const hub = new Hub(client);

hub.configureScope(function(scope) {
  scope.setTag("a", "b");
});

hub.addBreadcrumb({ message: "crumb 1" });
hub.captureMessage("test");

try {
  a = b;
} catch (e) {
  hub.captureException(e);
}

hub.withScope(function(scope) {
  hub.addBreadcrumb({ message: "crumb 2" });
  hub.captureMessage("test2");
});

Dealing with integrations

Integrations 是在 Client 上設定的,如果你需要處理多個 clients 和 hubs,你必須確保也正確地進行整合處理。下面是一個工作示例,演示如何使用多個 clients 和多個 hubs 執行全域性整合。

import * as Sentry from "@sentry/browser";

// Very happy integration that'll prepend and append very happy stick figure to the message
class HappyIntegration {
  constructor() {
    this.name = "HappyIntegration";
  }

  setupOnce() {
    Sentry.addGlobalEventProcessor(event => {
      const self = Sentry.getCurrentHub().getIntegration(HappyIntegration);
      // Run the integration ONLY when it was installed on the current Hub
      if (self) {
        event.message = `\\o/ ${event.message} \\o/`;
      }
      return event;
    });
  }
}

HappyIntegration.id = "HappyIntegration";

const client1 = new Sentry.BrowserClient({
  dsn: "___PUBLIC_DSN___",
  integrations: [...Sentry.defaultIntegrations, new HappyIntegration()],
  beforeSend(event) {
    console.log("client 1", event);
    return null; // Returning null does not send the event
  },
});
const hub1 = new Sentry.Hub(client1);

const client2 = new Sentry.BrowserClient({
  dsn: "___PUBLIC_DSN___", // Can be a different DSN
  integrations: [...Sentry.defaultIntegrations, new HappyIntegration()],
  beforeSend(event) {
    console.log("client 2", event);
    return null; // Returning null does not send the event
  },
});
const hub2 = new Sentry.Hub(client2);

hub1.run(currentHub => {
  // The hub.run method makes sure that Sentry.getCurrentHub() returns this hub during the callback
  currentHub.captureMessage("a");
  currentHub.configureScope(function(scope) {
    scope.setTag("a", "b");
  });
});

hub2.run(currentHub => {
  // The hub.run method makes sure that Sentry.getCurrentHub() returns this hub during the callback
  currentHub.captureMessage("x");
  currentHub.configureScope(function(scope) {
    scope.setTag("c", "d");
  });
});

Third Party Promise Libraries

當您包含並配置 Sentry 時,我們的 JavaScript SDK 會自動將 global handlers 附加到 capture 未捕獲的 exceptions 和未處理的 promise rejections。您可以通過在 GlobalHandlers 整合中將 onunhandledrejection 選項設定為 false 來禁用此預設行為,並手動掛鉤到每個事件 handler,然後直接呼叫 Sentry.captureExceptionSentry.captureMessage

如果您使用第三方庫來實現 promises,則可能還需要管理您的配置。另外,請記住,瀏覽器經常實施安全措施,當提供來自不同來源的指令碼檔案時,這些措施會阻止錯誤報告。

Supported Browsers

Sentry 的 JavaScript SDK 支援以下瀏覽器:

Android Firefox Chrome IE iPhone Edge Safari
4.4 latest latest IE 10 iOS12 latest latest
5.0 IE 11 iOS13
6.0
7.1
8.1
9.0
10.0

Support for <= IE 11

在 5.7.0 版之前,我們的 JavaScript SDK 需要為舊版瀏覽器(如IE 11和更低版本)提供一些 polyfill。如果您正在使用它,請先升級到最新版本或在下面新增指令碼標籤,然後再載入我們的 SDK。

<script src="https://polyfill.io/v3/polyfill.min.js?features=Promise%2CObject.assign%2CString.prototype.includes%2CNumber.isNaN"></script>

我們需要以下polyfill:

  • Promise
  • Object.assign
  • Number.isNaN
  • String.prototype.includes

此外,請記住在 HTML 頁面頂部定義一個有效的 HTML 文件型別,以確保 IE 不會進入相容模式。

中文文件陸續同步到:

我是為少。
微信:uuhells123。
公眾號:黑客下午茶。
謝謝點贊支援???!

相關文章