開發與維運

Sentry(v20.12.1) K8S 雲原生架構探索,SENTRY FOR JAVASCRIPT Source Maps詳解(二)

Troubleshooting


Source maps 有時可能很難上手。如果您遇到問題:

Verify a release is configured in your SDK

要定位和應用已上傳的 source maps,需要通過 CLI 或 API 創建 release(以及上傳的正確 artifacts),並且需要在 SDK 配置中指定新創建的 release 的名稱。

要驗證這一點,請從 Sentry UI 打開 issue 並檢查是否配置了 release。如果屏幕右側的 Release 旁邊顯示 "not configured" 或 "N/A"(或如果你沒有看到一個 release 標籤在標籤列表),則需要返回並 tag your errors。如果設置正確,您將看到 "Release: my_example_release"。

Verify artifacts are uploaded

一旦您的 release 被正確配置並且問題被標記,您可以通過導航到 [Project] » Project Settings » Source Maps 來找到上傳到 Sentry 的工件(artifacts)。

此外,請確保所有必要的文件都可用。為了讓 Sentry 去 de-minify 你的堆棧跟蹤,您必須同時提供兩個壓縮的文件(例如,app.min.js)以及相應的 source maps。如果 source map 文件不包含原始 source code(sourcesContent),則必須另外提供原始 source code。或者,sentry-cli 會自動將源代碼(如果缺少)嵌入到 source maps 中。

Verify sourceMappingURL is present

一些 CDN 自動從靜態文件(包括 JavaScript 文件)中刪除註釋。這可能會導致 JavaScript 文件中沒有 sourceMappingURL 指令,因為它被視為註釋。例如,CloudFlare 有一個名為 Auto-Minify 的功能,如果它被啟用,它將剝離 sourceMappingURL

仔細檢查部署的最終 JavaScript 文件是否有 sourceMappingURL

或者,您可以在壓縮的文件上設置 SourceMap HTTP header,而不是 sourceMappingURL。如果存在此標頭,Sentry 將使用它來發現 source map 的位置。

Verify artifact names match sourceMappingURL value

bundled 或 minified 的 JavaScript 文件的最後一行的 sourceMappingURL 註釋告訴Sentry(或瀏覽器)在哪裡找到相應的 source map。這可以是絕對的 URL,相對路徑或文件名本身。將工件(artifacts)上傳到 Sentry 時,必須使用文件解析到的值來命名 source map 文件。

也就是說,如果你的文件類似於:

// -- end script.min.js
//# sourceMappingURL=script.min.js.map

並託管在 http://example.com/js/script.min.js 上,然後 Sentry 將在 http://example.com/js/script.min.js.map 上查找 source map 文件。因此,您上傳的工件(artifact)必須命名為 http://example.com/js/script.min.js.map (或 ~/js/script.min.js.map)。

或者,如果你的文件類似於:

//-- end script.min.js
//# sourceMappingURL=https://example.com/dist/js/script.min.js.map

然後你上傳的工件(artifact)也應該命名為 https://example.com/dist/js/script.min.js.map (或者 ~/dist/js/script.min.js.map )。

最後,如果你的文件類似於:

//-- end script.min.js
//# sourceMappingURL=../maps/script.min.js.map

然後你上傳的工件應該命名為 https://example.com/dist/maps/script.min.js.map (或者 ~/dist/maps/script.min.js.map)。

Verify artifact names match stack trace frames

如果您上傳了 source maps,但它們沒有應用到 Sentry 中的某個 issue 中的代碼中,請查看事件的 JSON 並查找 abs_path,以查看我們試圖解析文件的確切位置 — 例如,http://localhost:8000/scripts/script.js(對於堆棧跟蹤中的每一幀,abs_path 將出現一次 - 將其與未被非 deminified 的文件匹配。)。在事件發生日期旁邊的 issue 頁面頂部可以找到一個指向 JSON 視圖的鏈接。上載的工件名稱(uploaded artifact names)必須與這些值匹配。

如果您的 dynamic values in your path(路徑中有動態值)(例如:https://www.site.com/{some_value}/scripts/script.js),則可能需要使用 rewriteFrames integration 來更改 abs_path 值。

Using sentry-cli

如果您的 sourceMappingURL 註釋類似於:

// -- end script.min.js (located at http://localhost:8000/scripts/script.min.js)
//# sourceMappingURL=script.min.js.map

正確上傳這些文件的示例,sentry-cli 命令如下所示(假設您位於 /scripts 目錄中,並從一個更高的目錄運行 Web 服務器,這就是為什麼我們使用 --url-prefix 選項):

sentry-cli releases files VERSION upload-sourcemaps . --url-prefix '~/scripts'

此命令上傳當前目錄中的所有 JavaScript 文件。Sentry 中的 Artifacts 頁面現在應如下所示:

~/scripts/script.js
~/scripts/script.min.js
~/scripts/script.min.js.map

或者,您可以指定要上傳的文件。例如:

sentry-cli releases files VERSION upload-sourcemaps script.min.js script.min.js.map --url-prefix '~/scripts'

您也可以使用絕對 URL 上傳它。例如:

sentry-cli releases files VERSION upload-sourcemaps . --url-prefix 'http://localhost:8000/scripts'

Using the API

您也可以使用我們的API 來上傳工件,遵循這裡解釋的相同命名約定。

curl -X POST \
  https://sentry.io/api/0/organizations/ORG_SLUG/releases/VERSION/files/ \
  -H 'Authorization: Bearer AUTH_TOKEN' \
  -H 'content-type: multipart/form-data' \
  -F [email protected] \
  -F 'name=~/scripts/script.min.js.map'

Using the ~

~ 在 Sentry 中用於替換 scheme 和 domain。這不是一個問題!

http://example.com/dist/js/script.js 將匹配 ~/dist/js/script.jshttp://example.com/dist/js/script.js

但是將不匹配 ~/script.js

Verify artifacts are uploaded before errors occur

Sentry 希望在某個 release 中出現錯誤之前,將 source code 和 source maps 上傳到 Sentry。

如果您在 Sentry 捕獲錯誤之後上傳工件,Sentry 將不會返回並追溯地對這些錯誤應用任何源註釋。只有在工件上傳後觸發的新錯誤才會受到影響。

Verify your source maps are built correctly

我們維護了一個在線驗證工具,可以用來測試您的 source maps 與 hosted(託管) 源:https://sourcemaps.io

另外,如果你正在使用 Sentry CLI 上傳 source maps 到 Sentry,你可以使用 --validate 命令行選項來驗證你的 source maps 是否正確。

Verify your source maps work locally

如果發現 Sentry 沒有正確映射文件名,行或列映射,則應驗證 source maps 是否在本地運行。為此,您可以將 Node.js 與Mozilla 的 source-map library 一起使用。

首先,將 source-map 作為 npm 模塊全局安裝:

npm install -g source-map

然後,編寫一個腳本,該腳本讀取您的 source map 文件並測試映射。這是一個例子:

var fs = require("fs"),
  path = require("path"),
  sourceMap = require("source-map");
// file output by Webpack, Uglify, and so forth
var GENERATED_FILE = path.join(".", "app.min.js.map");
// line and column located in your generated file (for example, the source of your error
// from your minified file)
var GENERATED_LINE_AND_COLUMN = { line: 1, column: 1000 };
var rawSourceMap = fs.readFileSync(GENERATED_FILE).toString();
new sourceMap.SourceMapConsumer(rawSourceMap).then(function(smc) {
  var pos = smc.originalPositionFor(GENERATED_LINE_AND_COLUMN);
  // should see something like:
  // { source: 'original.js', line: 57, column: 9, name: 'myfunc' }
  console.log(pos);
});

如果您通過 Sentry 在本地獲得相同(不正確)的結果,請仔細檢查您的 source map 生成配置。

Verify your source files are not too large

對於單個 artifact,Sentry 接受的最大文件大小為 40 MB。

用戶通常會達到此限制,因為他們在臨時構建階段傳輸源文件。例如,在 Webpack/Browserify 合併所有源文件之後,但在壓縮之前。如果可能,請發送原始源文件。

Verify artifacts are not gzipped

Sentry API 當前僅適用於以純文本(UTF-8 編碼)上傳的 source maps 和 source files。如果文件以壓縮格式(例如 gzip)上傳,則將無法正確解釋它們。

這種情況有時會發生在生成預壓縮小文件的構建腳本和插件中。例如,Webpack 的壓縮插件。您需要禁用這些插件,並在將生成的 source maps/source files 上傳到 Sentry 後執行壓縮。

Verify workers are sharing the same volume as web (if running as docker on premise)

Sentry 在其 workers 中進行 source map 計算。這意味著 workers 需要訪問通過前端上傳的文件。仔細檢查 cron workers 和 web workers 是否可以從同一個磁盤讀/寫文件。

Uploading Source Maps

我們建議將上傳 source maps 作為構建過程的一部分,但您也可以將它們與源文件一起公開提供。

建議的上傳 source maps 的方法是使用 sentry-cli。如果您使用 Sentry Wizard 來設置項目,則它已經創建了所有必要的配置以上傳 source maps。否則,請遵循 CLI 配置文檔來設置您的項目。

您需要設置構建系統以創建 release 並附加各種源文件。為了使 Sentry 縮小堆棧跟蹤的大小,必須同時提供縮小的文件(例如app.min.js)和相應的源映射。如果源映射文件不包含原始源代碼(sourcesContent),則還必須提供原始源文件。另外,sentry-cli 將自動將源(如果缺少)嵌入到 source maps 中。

Sentry 使用 Releases 將正確的 source maps 與您的事件進行匹配。要創建新 release,請運行以下命令(例如,在發佈期間):

sentry-cli releases new <release_name>

release 名稱必須是在您的組織內唯一的,並且與 SDK 初始化代碼中的 release 選項匹配。然後,使用 upload-sourcemaps 命令掃描文件夾中的 source maps,進行處理並將其上傳到 Sentry。

sentry-cli releases files <release_name> upload-sourcemaps /path/to/files

您可以通過導航找到上傳到 Sentry 的工件:[Project] » Project Settings » Source Maps。

此命令會將所有以 .js 和 .map 結尾的文件上傳到指定的 release。如果您想更改這些擴展名(例如,上傳 typescript 源),請使用 --ext 選項:

sentry-cli releases files <release_name> upload-sourcemaps --ext ts --ext map /path/to/files

到目前為止,版本處於草稿狀態((“unreleased”)。一旦所有 source maps 都已上傳,並且您的應用已成功發佈,請使用以下命令完成 release:

sentry-cli releases finalize <release_name>

為了方便起見,您也可以將 --finalize flag 傳遞給 new 命令,該命令將立即完成 release。

你不必一定上傳源文件(由 source maps 引用),但是沒有它們,分組算法就不會那麼強大,UI 也不會顯示任何上下文相關的源文件。

有關更多信息,請參閱我們 Releases API documentation

web 應用程序可以從多個來源訪問並不少見。請參閱我們關於如何處理此問題的多個來源的文檔。

Validating Files

要確保 source maps 本身是有效的,並且正確上傳,這可能是一個相當具有挑戰性的問題。為了幫助實現這一點,我們維護了一個在線驗證工具,可用於根據託管源測試源映射:https://sourcemaps.io

此外,當使用 sentry-cli 上傳源映射時,可以在中使用 --validate 標誌,這將嘗試本地解析源映射並查找引用。請注意,在某些已知情況下,當設置正確時,validate 標誌將指示失敗(如果您有對外部源映射的引用,則驗證工具將指示失敗)。

除了驗證步驟之外,您還可以檢查以下內容:

  • 確保您的文件的 URL 前綴正確。這很容易出錯。
  • 為 minimized 的文件上傳匹配的源映射。
  • 確保服務器上的 minified 文件確實引用了您的文件。

Leave a Reply

Your email address will not be published. Required fields are marked *