Sentry 監控 - 私有 Docker Compose 部署與故障排除詳解

為少發表於2021-12-14

內容整理自官方開發文件

系列

自託管 Sentry

除了公開提供其原始碼外,Sentry 還提供並維護了一個最小的設定,可以為簡單的用例開箱即用。
該儲存庫還可以作為各種 Sentry 服務如何連線以進行完整設定的藍圖,這對於願意維護更大安裝的人很有用。
為簡單起見,我們為此選擇使用 DockerDocker Compose
以及基於 bash 的安裝和升級指令碼。

入門

我們的建議是下載自託管儲存庫的最新版本
然後在此目錄中執行 ./install.sh
這個指令碼會處理你開始需要的所有事情,包括一個 base-line 配置,
然後會告訴你執行 docker-compose up -d 來啟動 Sentry
Sentry 預設繫結到埠 9000
您應該能夠訪問 http://127.0.0.1:9000 上的登入頁面。

配置

您很可能希望調整 Sentry 的預設配置。這些設施可用於此目的:

  1. sentry/config.yml — 包含大多數(如果不是全部)要調整的配置選項。這個檔案是在安裝時從 sentry/config.example.yml 生成的。該檔案本身將最常見的配置選項記錄為程式碼註釋。此檔案中的一些常用設定包括:

    • system.url-prefix(我們會在安裝後立即提示您在歡迎螢幕上進行設定)
    • mail.*(雖然我們提供了一個基本的 SMTP 伺服器)
    • GitHubSlack 等的整合。
  2. sentry/sentry.conf.py—包含更高階的配置。這個檔案是在安裝過程中從 sentry/sentry.conf.example.py 生成的。

  3. 環境變數—可用的 key.env 中定義。如果您需要覆蓋任何環境變數,請使用一些與系統相關的方法來設定環境變數。為避免 Git 更改,只需建立一個名為 .env.custom 的檔案並在其中插入與系統相關的環境變數。為了使用它,請使用 docker-compose --env-file /path/to/.env.custom up -d

  4. Geolocation 使用自定義配置檔案來符合底層技術。

注意:更改配置後,您需要通過執行 docker-compose restart web worker cron sentry-cleanup(或僅 docker-compose restart 重新啟動所有內容)來重新啟動所有 Sentry 服務。

配置特定主題

以下是與自託管相關的特定配置主題的更多資訊:

  • 自定義 CA 根
  • Email
  • 地理位置
  • 單點登入 (SSO)

產品化

我們強烈建議在繫結到專用域或子域的 Sentry 設定前使用專用負載均衡器。
一個執行 SSL/TLS 終止的專用負載平衡器也將客戶端 IP 地址轉發為 Docker Compose 內部網路
(因為這幾乎不可能以其他方式獲得)將為您提供最佳的 Sentry 體驗。
作為此設定的一部分,我們建議使用 HTTP 協議針對 /_health/ 端點配置負載均衡器執行狀況檢查。
如果 Sentry 啟動,這將返回 200 或帶有問題列表的 500

請記住,所有這些設定都對所有服務使用單節點,包括 Kafka
對於更大的負載,您需要一臺具有大量 RAM 和磁碟儲存空間的強大機器。
為了進一步擴充套件,您很可能會使用帶有更復雜工具(例如 Kubernetes)的叢集。
由於自託管安裝的自定義性質,我們不提供任何有關擴充套件的建議或指導。

自託管釋出和升級

Sentry 減少了自託管的定期釋出,以使其儘可能接近 sentry.io
我們決定遵循使用 CalVer 版本控制方案的月度釋出計劃。
每個月的 15 號釋出一個新版本,並在必要時進行後續釋出。
您可以在我們自託管儲存庫的釋出部分
找到最新版本

為什麼選擇 CalVer

升級

我們鼓勵每個人定期更新他們的 Sentry 安裝以獲得最佳和最新的 Sentry 體驗。

要升級,您需要做的就是下載或檢查您想要的自託管儲存庫的版本,用該版本替換現有資料夾的內容,然後執行 ./install.sh

配置更新

我們可能有一些更新的配置,特別是對於新功能,因此請始終檢查 sentry 目錄下的示例配置檔案,看看是否需要更新現有配置。我們盡最大努力自動化關鍵配置更新,但您應該始終在升級期間檢查您的配置。

在開始升級之前,我們關閉了所有服務,然後執行了一些資料遷移,因此預計會有一些停機時間。
有一個實驗性--minimize-downtime 選項可以減少升級期間的停機時間。
使用它的風險由您自己承擔,並檢視它在其中實施的PR以獲取更多資訊。

從早期版本升級時,您需要經歷一些困難。請閱讀下面的 難點 部分以獲取列表。

難點

我們有三個難點,您需要通過這些步驟才能獲取重大的資料庫更改:

  1. 如果您來自 9.1.2 之前的版本,則首先需要升級到 9.1.2 並按照以下步驟操作:
    <your.sentry.version> -> 9.1.2 -> 21.5.0 -> 21.6.3 -> latest
    
  2. 如果您來自 9.1.2,首先需要升級到 21.5.0 並按照以下步驟操作:
    <your.sentry.version> -> 21.5.0 -> 21.6.3 -> latest
    
  3. 如果您來自 21.6.3 之前的版本,則首先需要升級到 21.6.3
    <your.sentry.version> -> 21.6.3 -> latest
    

任何其他情況(21.6.3+),你應該可以直接升級到最新版本。

每晚構建

我們為 Sentry 的每個新提交以及所有支援專案提供自託管儲存庫的 master 分支的每晚構建:

注意:這些構建通常是穩定的,但您可能偶爾會遇到損壞的版本,因為這些版本不能保證首先部署到 sentry.io。也不能保證您能夠乾淨地升級到更高版本而不會丟失任何資料。使用每晚構建的風險自負

自託管備份和恢復

快速備份

如果您需要一種快速備份和恢復 Sentry 例項的方法,並且不需要歷史事件資料,
則可以使用內建的 exportimport 命令。
這些命令將儲存和載入所有專案和使用者資料,但不包含任何事件資料。

備份

docker-compose run --rm -T -e SENTRY_LOG_LEVEL=CRITICAL web export > sentry/backup.json

注意:如果您省略了 -T-e SENTRY_LOG_LEVEL=CRITICAL 部分,您的備份檔案將混入日誌行,您必須以某種方式將其刪除。

恢復

使用 export 命令備份後,恢復它的最簡單方法是將其放在主 self-hosted 儲存庫中的 sentry 目錄下,在配置檔案旁邊。這個目錄會自動掛載到 /etc/sentry,所以你可以執行以下命令來恢復你的備份:

docker-compose run --rm -T web import /etc/sentry/backup.json

如果您沒有看到任何錯誤並且程式以程式碼 0 退出,那麼恭喜您,您剛剛恢復了備份。

注意:我們強烈建議您在全新安裝(空資料庫但執行遷移)時在 相同版本的 Sentry 上恢復備份。否則,您很可能會遇到錯誤並可能損壞您的資料庫。

完整備份

備份和恢復 Sentry 的理想方法是備份恢復它使用的所有 Docker 卷。所有儲存關鍵長期資料的卷在安裝時都已定義為全域性卷,並以 sentry- 為字首:

  • sentry-data
  • sentry-postgres
  • sentry-redis
  • sentry-zookeeper
  • sentry-kafka
  • sentry-clickhouse
  • sentry-symbolicator

注意:只有備份和恢復這些卷才能恢復所有持久化資料。如果您還需要備份執行中的資料,我們建議備份 docker-compose 自動建立的任何特定於專案的卷,通常使用 sentry_self_hosted_sentry- 字首。

Docker 在他們的文件中記錄了如何備份和恢復卷
只要可以毫無問題地讀回捲,您就可以使用不同的方法。

自託管的自定義 CA 根

從 Sentry 21.8.0 開始,如果您需要沒有來自公共信任 CA 根的 TLS 證照的 Sentry 訪問服務,現在可以輕鬆地將它們新增到容器中。
只需將證照新增到 Sentry 安裝根目錄內的 certificates 資料夾中,然後重新啟動容器。除了公共信任的 CA 根之外,還將使用您的自定義 CA 根。

注意:雖然您可以在每個容器中執行 update-ca-certificates,但這將更新磁碟上系統的根包,但不會對記憶體中的任何副本執行任何操作。重新啟動容器將更新包並確保它被使用。

如果給定的證照有問題,容器的日誌將在開始時具有 update-ca-certificates 的輸出。

具有捆綁根的依賴項

一些依賴項選擇捆綁自己的 CA 根並忽略系統 CA 根。
在已知的情況下,它們已被配置為使用系統根
如果某些東西似乎忽略了系統根,請建立一個 issue
以便對其進行跟蹤和修復。

覆蓋的捆綁根

  • Python
    • requests
    • botocore
    • grpc

自託管 Email

注意:請記住,一旦更改設定,您就需要重新啟動所有 Sentry 服務。有關更多資訊,請參閱配置部分。

出站 Email

自託管 Sentry 附帶一個由 exim4 提供支援的內建外發 SMTP server
預設配置設定為使用此伺服器。您需要做的就是為 config.yml 中的 mail.from 設定設定一個有效地址,
併為 .env 中的 SENTRY_MAIL_HOST 設定 Sentry 例項的 FQDN
請記住,如果您開始向公共地址傳送過多電子郵件,您的新伺服器可能會被標記為垃圾郵件傳送者並被禁止。

如果您想使用外部 SMTP server,您可以在 config.yml 檔案中設定相關的 mail.* 設定並忽略內建的 SMTP server
有關每個設定的含義和作用的所有詳細資訊,請參閱我們的電子郵件服務文件

由於配置的分層方式,如果您通過 Web 介面更新 mail 設定,您還需要註釋掉 config.yml 中的 mail.host: 'smtp' 預設值,以便選擇所需的設定。

入站 Email

Sentry 通過 Mailgun 提供的入站 mail 支援非常有限。
您可以在我們的入站 email 服務文件中找到有關如何進行設定的所有資訊。

自託管地理定位

Sentry 可以使用 MaxMind 的免費 GeoLite2-City 資料庫來對 IP 地址進行地理定位,
為已知終端使用者 IP 地址的錯誤事件以及登入 Sentry 安裝的使用者的會話歷史記錄提供額外的上下文。
為此,我們捆綁了 MaxMindgeoipupdate 工具。

為了利用伺服器端 IP 地址地理定位,您必須首先將 IP 地址傳送到 Sentry。
預設情況下,較新的 SDK 不會執行此操作

要啟用伺服器端 IP 地址地理定位,請註冊一個免費的 MaxMind 帳戶
然後通過將您的 MaxMind 配置檔案放在 geoip/GeoIP.conf 來告訴 Sentry 您的憑據。

AccountID 012345
LicenseKey foobarbazbuz
EditionIDs GeoLite2-City

有了這個配置檔案,Sentryinstall.sh 的後續執行將重新整理 IP 地址地理定位資料庫。
下次您重新啟動自託管的 Sentry 例項(特別是 relayweb 服務)時,您應該會看到最新的資料。
以下是確認它是否正常工作的方法:

  1. 對於 relay 服務:Dashboards > Errors by Country 上應該有一些紫色。

  2. 對於 web 服務:User Settings > Security > Session History 應在表中的 IP 地址下方顯示國家程式碼和地區(例如,"US (CA)")。

啟動後不久看到 sentry_self_hosted_geoipupdate_1 容器退出是正常的,因為更新地理定位資料庫是一次性的批處理過程,而不是長時間執行的 job

升級

使用 GeoLite2-City.mmdb 檔案的服務需要知道在哪裡可以找到它。新安裝將自動設定此設定,但如果您要升級,則需要在重新啟動 Sentry 之前手動設定以下內容。

relay/config.yml 中(示例):

processing:
  geoip_path: "/geoip/GeoLite2-City.mmdb"

sentry/sentry.conf.py 中(示例):

GEOIP_PATH_MMDB = '/geoip/GeoLite2-City.mmdb'

自託管單點登入 (SSO)

Sentry 中的 SSO 以兩種方式之一處理:

  • 通過處理上游代理的中介軟體來指示經過身份驗證的使用者
  • 通過實現身份驗證管道的第三方服務

使用中介軟體代理 (SAML2)

Sentry 20.6.0 開始,自託管 Sentry 內建了對 SAML2 和某些身份驗證提供程式的支援。
對於舊版本,您需要在執行 ./install.sh 之前將以下行新增到 sentry/requirements.txt

sentry-auth-saml2@https://github.com/getsentry/sentry-auth-saml2/archive/master.zip#egg=sentry-auth-saml2

您可以設定它的方式與 sentry.io 相同,除了您需要為文件中提到的 URL 使用自己例項的 url-prefix

有關所有詳細資訊,請參閱我們的主要 SAML 文件

使用 OAuth 的單點登入

注意:啟用 SSO 後,這將是登入到自託管例項的唯一方法。如果您需要與 SSO 一起免費註冊,您可以在 GitHub PR 上對此發表評論。

Google Auth

Sentry 9.1 開始,自託管的 Sentry 帶有內建的 Google Auth 支援。
要啟用,您需要為您的 Google App 建立一個 client ID 和 secret
然後將這些值分別輸入到您的 sentry/config.yaml 檔案中:

auth-google.client-id: '<client id>'
auth-google.client-secret: '<client secret>'

注意:請記住,一旦更改設定,您就需要重新啟動所有 Sentry 服務。有關更多資訊,請參閱配置部分。

GitHub Auth

Sentry 10 開始,
自託管 Sentry 帶有內建的 GitHub Auth 支援。要啟用,您需要在您的組織下建立一個新的 GitHub App 並安裝它。

為 SSO & integration 建立 GitHub App

GitHub App 名稱不得包含任何空格。

如果上面的表單對您不起作用,您需要為您的 GitHub 應用程式進行以下設定:

Setting Value
Homepage URL ${urlPrefix}
User authorization callback URL ${urlPrefix}/auth/sso/
Setup URL (optional) ${urlPrefix}/extensions/github/setup/
Webhook URL ${urlPrefix}/extensions/github/webhook/

不要忘記將所有出現的 {'${urlPrefix}'} 替換為您自己的 url 字首。

當提示輸入許可權時,請選擇以下選項:

Permission Setting
Organization permissions / members Read-only
User permissions / Email addresses Read-only
Repository administration Read-only
Repository contents Read-only
Issues Read & write
Pull requests Read & write
Repository webhooks Read & write
使用您的 GitHub App 資訊更新您的配置

然後,您需要設定以下配置值:

sentry/sentry.conf.py

GITHUB_APP_ID="<App ID>"
GITHUB_API_SECRET="<Client secret>"
GITHUB_REQUIRE_VERIFIED_EMAIL = True  # Optional but recommended

# Only if you are using GitHub Enterprise
#GITHUB_BASE_DOMAIN = "git.example.com"
#GITHUB_API_DOMAIN = "api.git.example.com"

sentry/config.yaml

# github-app.id: <App ID>
# github-app.name: '<GitHub App name>'
# github-app.webhook-secret: '<Webhook secret>' # Use only if configured in GitHub
# github-app.client-id: '<Client ID>'
# github-app.client-secret: '<Client secret>'
# github-app.private-key: |
#   -----BEGIN RSA PRIVATE KEY-----
#   privatekeyprivatekeyprivatekeyprivatekey
#   privatekeyprivatekeyprivatekeyprivatekey
#   privatekeyprivatekeyprivatekeyprivatekey
#   privatekeyprivatekeyprivatekeyprivatekey
#   privatekeyprivatekeyprivatekeyprivatekey
#   -----END RSA PRIVATE KEY-----

這還將為您的例項啟用 GitHub Integration

注意:請記住,一旦更改設定,您就需要重新啟動所有 Sentry 服務。有關更多資訊,請參閱配置部分。

自定義 Provider

目前,API 被認為是不穩定的,可能會發生變化。事情可能不會有太大變化,但有一些地方需要清理。

考慮到這一點,如果您想構建自己的,請檢視上面的參考實現之一。

自託管故障排除

請記住,自託管儲存庫面向中低負載,並考慮到了簡單性。
需要更大設定或有事件高峰的人們可以根據他們的特定需求和環境從這裡擴充套件。

常見

您可以通過執行 docker-compose logs <service_name> 來檢視每個服務的日誌。
您可以使用 -f 標誌來 "follow" 進入的日誌,並使用 -t 標誌作為時間戳。
如果您不傳遞任何服務名稱,您將獲得所有正在執行的服務的日誌。
有關詳細資訊,請參閱 logs 命令的參考

Kafka

最有可能導致問題的事情之一是 Kafka。最常報告的錯誤是

Exception: KafkaError{code=OFFSET_OUT_OF_RANGE,val=1,str="Broker: Offset out of range"}

這發生在 Kafkaconsumer 不同步的地方。可能的原因有:

  1. 磁碟空間或記憶體不足
  2. 持續的事件峰值會導致很長的處理時間,導致 Kafka 在超過保留時間時丟棄訊息
  3. 由於重新啟動或 suspend/resume(暫停/恢復) 迴圈導致的 Date/time(日期/時間) 不同步問題

恢復

正確的解決方案

正確 的解決方案如下 (reported by @rmisyurev):

  1. 接收消費者列表:
    docker-compose run --rm kafka kafka-consumer-groups --bootstrap-server kafka:9092 --list
    
  2. 獲取群組資訊:
    docker-compose run --rm kafka kafka-consumer-groups --bootstrap-server kafka:9092 --group snuba-consumers -describe
    
  3. 使用試執行(可選)觀察 offset 會發生什麼:
    docker-compose run --rm kafka kafka-consumer-groups --bootstrap-server kafka:9092 --group snuba-consumers --topic events --reset-offsets --to-latest --dry-run
    
  4. offset 設定為最新並執行:
    docker-compose run --rm kafka kafka-consumer-groups --bootstrap-server kafka:9092 --group snuba-consumers --topic events --reset-offsets --to-latest --execute
    

您可以在需要時將 snuba-consumers 替換為其他 consumer groups 或其他 topics 的 events

硬核選項

硬核選項 是刪除所有與 Kafka 相關的卷並重新建立它們,這將導致資料丟失。刪除這些卷後,任何掛起的資料都_將_消失。

  1. 停止例項:

    docker-compose down --volumes
    
  2. 刪除 Kafka & Zookeeper 相關卷:

    docker volume rm sentry-kafka
    docker volume rm sentry-zookeeper
    
  3. 再次執行安裝指令碼:

    ./install.sh
    
  4. 啟動例項:

    docker-compose up -d
    

減少磁碟使用

如果你想減少 Kafka 使用的磁碟空間,你需要仔細計算你攝取的資料量,你可以容忍的資料丟失量,
然後按照這個很棒的 StackOverflow 帖子
我們社群論壇上的帖子中的建議進行操作。

Redis

在自託管設定中,Redis 既用作事務資料儲存又用作 Celery 的工作佇列。
出於這個原因,它可能會在事件高峰期間不堪重負。
從版本 20.10.1 開始,我們對此進行了一些重大改進。
如果您仍然遇到問題,您可以考慮擴充套件 Redis 本身或切換到不同的 Celery broker,例如 RabbitMQ

Workers

如果您看到錯誤,例如

Background workers haven’t checked in recently. It seems that you have a backlog of 200 tasks. Either your workers aren’t running or you need more capacity.

您可能會從使用額外的專職工作人員中受益。
這是通過在 docker-compose.override.yml 中建立新的 worker 服務並使用 -Q queue_name 引數將它們繫結到特定佇列來實現的。 一個例子是:

worker1:
    << : *sentry_defaults
    command: run worker -Q events.process_event

要檢視更完整的示例,請參閱我們社群論壇上的示例解決方案

Postgres

Postgres 用於主資料儲存,以及用於儲存 key/value 資料的 nodestore
node_nodestore 表可以快速增長,尤其是在大量使用效能監控功能時,因為跟蹤資料儲存在該表中。

node_nodestore 表作為 cleanup 任務的一部分被清理,
但是 Postgres 可能沒有機會清理表(尤其是在過載情況下),所以即使行可能被刪除,它們仍然會佔用磁碟空間。

您可以使用 pg-repack,它通過建立一個新表並在刪除舊錶之前複製資料來重新打包一個表。
您需要在清理指令碼之後執行它,並注意它在建立表時,磁碟使用量會在回落之前激增

下面是一個指令碼示例:

# Only keep the last 7 days of nodestore data. We heavily use performance monitoring.
docker-compose run -T web cleanup --days 7 -m nodestore -l debug
# This ensures pg-repack exists before running as the container gets recreated on upgrades
docker-compose run -T postgres bash -c "apt update && apt install -y --no-install-recommends postgresql-9.6-repack && su postgres -c 'pg_repack -E info -t nodestore_node'"

其他

如果您仍然遇到問題,您可以隨時訪問我們的社群論壇以搜尋現有主題或建立新主題並尋求幫助。
請記住,我們希望社群能夠幫助自己,並且 Sentry 員工也會在有時間時嘗試監控和回答論壇問題。

報告問題或在論壇上提問時共享您的安裝日誌、服務日誌和 Sentry 版本將為您和試圖幫助您的人節省時間和精力。

相關文章