Sentry 開發者貢獻指南 – 後端服務(Python/Go/Rust/NodeJS)

  • 2021 年 12 月 17 日
  • 筆記

內容整理自官方開發文檔

系列

目錄

  • 服務管理 (devservices)
    • 查看服務的日誌
    • redispostgresclickhouse 運行 CLI 客戶端
    • 移除容器狀態
  • 端口分配
    • 找出您的機器上正在運行的內容
  • 異步 Worker
    • 註冊任務
    • 運行 Worker
    • 啟動 Cron 進程
    • 配置 Broker
      • Redis
      • RabbitMQ
  • Email
    • 出站 Email
    • 入站 Email
      • Mailgun
  • 節點存儲
    • Django 後端
    • 自定義後端
  • 文件存儲
    • 文件系統後端
    • Google Cloud 存儲後端
    • Amazon S3 後端
    • MinIO S3 後端
  • 時間序列存儲
    • RedisSnuba 後端(推薦)
    • Dummy 後端
    • Redis 後端
  • Buffer
    • 配置
      • Redis
  • 指標
    • Statsd 後端
    • Datadog 後端
    • DogStatsD 後端
    • Logging 後端
  • 配額
    • 事件配額
      • 配置
      • 全系統速率限制
      • 基於用戶的速率限制
      • 基於項目的速率限制
    • Notification 速率限制
      • 配置
  • Notification 摘要
    • 配置
    • 後端
      • Dummy 後端
      • Redis 後端
      • 示例配置
  • Relay
  • Snuba
  • 後端 Chart 渲染
    • Sentry 的後端使用 Chartcuterie
    • 配置 chart 以進行渲染
      • 服務初始化
      • 添加/刪除 chart 類型
    • 在開發中運行 Chartcuterie
      • 在本地更新 chart type
  • 工作原理
    • Chartcuterie 啟動
    • 來自 SentryRender 調用

服務管理 (devservices)

SentryDocker 提供了一個抽象,以在開發中運行所需的服務,稱為 devservices

Usage: sentry devservices [OPTIONS] COMMAND [ARGS]...

  Manage dependent development services required for Sentry.

  Do not use in production!

Options:
  --help  Show this message and exit.

Commands:
  attach  Run a single devservice in foreground, as...
  down    Shut down all services.
  rm      Delete all services and associated data.
  up      Run/update dependent services.

查看服務的日誌

# Follow snuba logs
docker logs -f sentry_snuba

為 redis、postgres 和 clickhouse 運行 CLI 客戶端

# redis
docker exec -it sentry_redis redis-cli

# clickhouse
docker exec -it sentry_clickhouse clickhouse-client

# psql
docker exec -it sentry_postgres psql -U postgres

移除容器狀態

如果你真的搞砸了你的容器或卷,你可以使用 devservices rm 重新開始。

# 刪除與所有服務關聯的所有數據(容器、卷和網絡)
sentry devservices rm

例如,假設我們在進行遷移時設法損壞了 postgres 數據庫,並且您想重置 postgres 數據,您可以執行以下操作:

# 刪除與單個服務關聯的所有數據(容器、卷和網絡)
sentry devservices rm postgres

端口分配

以下是 Sentry 服務使用的端口或開發設置中 Sentry 服務的任何依賴項的簡單列表。它有兩個目的:

  • 找出為什麼在您的工作機器上使用端口以及殺死哪個進程以使其空閑。
  • 找出哪些端口可以安全地分配給新服務。
Port Service Description
9000 Clickhouse Devservice clickhouse. Snuba 的數據庫。
8123 Clickhouse
9009 Clickhouse
3021 Symbolicator Devservice symbolicator. 用於處理堆棧跟蹤。
1218 Snuba Devservice snuba. 用於搜索事件。
9092 Kafka Devservice kafka. 用於 relay-sentry 通信和可選的用於 sentry-snuba 通信
6379 Redis Devservice redis (或者可能通過 rustier 設置中的 Homebrew 安裝),負責緩存、relay 項目配置和 Celery 隊列
5432 Postgres Devservice postgres(或者可能通過 rustier 設置中的 Homebrew 安裝)
7899 Relay Devservice relay. 為 SDK 提供將事件發送到的 API(也稱為事件攝取event ingestion)。Webpack8000 端口反向代理到此服務器。使用 sentry devserver 啟動/停止。
8000 Sentry Dev Sentry API +前端。Webpack 監聽此端口並代理 API 請求 Django app
8001 uWSGI 使用 sentry devserver 啟動/停止。為 Django app/API 提供服務。Webpack8000 端口反向代理到此服務器。
7999 Sentry frontend prod proxy 用於測試針對 prod API 的本地 UI 更改
8000 Develop docs 圍繞本文檔的網站。 Sentry Dev 的衝突
3000 User docs 面向用戶的文檔。如果 Relaydevservice 之外運行,則可能與 Relay 衝突。
9001 Sentry Dev Styleguide server 運行 sentry devserver --styleguide 時綁定
9000 sentry run web sentry run web 的傳統默認端口,更改為 9001 以避免與 Clickhouse 衝突。
9001 sentry run web 沒有 webpackRelay 的准系統前端。Sentry Dev 可能更好。與 Sentry Dev Styleguide server 衝突
8000 Relay mkdocs documentation 在某些時候,這將合併到我們現有的文檔存儲庫中。與 Sentry Dev 的衝突

找出您的機器上正在運行的內容

  • 使用 lsof -nP -i4 | grep LISTENmacOS 上查找被佔用的端口。
  • Docker for MacDashboard UI 顯示您正在運行的 docker 容器/開發服務以及分配的端口啟動/停止選項。

異步 Worker

Sentry 帶有一個內置隊列,以更異步的方式處理任務。
例如,當一個事件進入而不是立即將其寫入數據庫時,它會向隊列發送一個 job,以便可以立即返回請求,並且後台 worker 會實際處理保存該數據。

Sentry 依賴 Celery 庫來管理 worker

  • ttps://docs.celeryproject.org/

註冊任務

Sentry 使用特殊的裝飾器配置任務,使我們能夠更明確地控制可調用對象。

from sentry.tasks.base import instrumented_task

@instrumented_task(
    name="sentry.tasks.do_work",
    queue="important_queue",
    default_retry_delay=60 * 5,
    max_retries=None,
)
def do_work(kind_of_work, **kwargs):
    # ...

有幾個重要的點:

  • _必須_聲明 task 名稱。

    Task 名稱是 Celery 如何識別消息(請求)以及需要哪個函數和工作線程來處理這些消息。
    如果 task 沒有命名,celery 將從模塊函數名稱派生一個名稱,
    這使得名稱與代碼的位置相關聯,並且對於未來的代碼維護更加脆弱。

  • Task 必須接受 \*\*kwargs 來處理滾動兼容性。

    這確保 task 將接受恰好在隊列中的任何消息,而不是因未知參數而失敗。
    它有助於回滾更改,部署不是即時的,並且可能會使用多個版本的參數生成消息。

    雖然這允許在不完全任務失敗的情況下向前和向後滾動,
    但在更改參數時仍必須注意 worker 處理具有參數和參數的消息。
    這確實減少了這種遷移中所需更改的數量,並為 operator 提供了更多的靈活性,
    但是由於未知參數而導致的消息丟失仍然是不可接受的。

  • Task _應該_在失敗時自動重試。

  • Task 參數_應該_是原始類型並且很小。

    Task 參數被序列化到通過 broker 發送的消息中,worker 需要再次反序列化它們。
    對複雜類型執行此操作是脆弱的,應該避免。例如。更喜歡將 ID 傳遞給 task
    ID 可用於從緩存而不是數據本身加載數據。
    Task 參數被序列化到通過 broker 發送的消息中,worker 需要再次對它們進行反序列化。
    對複雜類型執行此操作是脆弱的,應該避免。
    例如,寧願向 task 傳遞 ID,該 ID 可用於從緩存加載數據,而不是數據本身。

    類似地,為了保持消息 brokerworker 有效運行,
    將大值序列化到消息中會導致大消息大隊列和更多(反)序列化開銷,因此應該避免

  • 必須將 task 的模塊添加到 CELERY_IMPORTS

    src/sentry/conf/server.py.
    Celery worker 必須按 name 查找 task
    只有當 worker 導入帶有裝飾任務函數的模塊時才能這樣做,
    因為這是按 name 註冊 task 的內容。因此,每個包含 task 的模塊都必須添加到 src/sentry/conf/server.py 中的 CELERY_IMPORTS 設置中。

運行 Worker

可以使用 Sentry CLI 運行 Worker

$ sentry run worker

啟動 Cron 進程

Sentry 通過 cron 進程安排 routine job

SENTRY_CONF=/etc/sentry sentry run cron

配置 Broker

Sentry 支持兩個主要 broker,可根據您的 workload 進行調整:RabbitMQRedis

Redis

默認 brokerRedis,可以在大多數情況下工作。使用 Redis 的主要限制是所有待處理的工作都必須放在內存中。

BROKER_URL = "redis://localhost:6379/0"

如果您的 Redis 連接需要密碼進行身份驗證,則需要使用以下格式:

BROKER_URL = "redis://:password@localhost:6379/0"

RabbitMQ

如果您在 高 workload 下運行,或者擔心將待處理的 workload 放入內存中,那麼 RabbitMQ 是支持 Sentry worker 的理想選擇。

BROKER_URL = "amqp://guest:guest@localhost:5672/sentry"

Email

Sentry 提供對出站傳入電子郵件的支持。

入站電子郵件的使用相當有限,目前僅支持處理對 errornote 通知的回復。

出站 Email

您需要為出站電子郵件配置 SMTP 提供商。

TODO: 撰寫 mail 預覽後端。

mail.backend

在 `config.yml` 中聲明。

用於發送電子郵件的後端。選項是 smtpconsoledummy

默認為 smtp。如果您想禁用電子郵件傳送,請使用 dummy

mail.from

在 `config.yml` 中聲明。

From header 中用於出站電子郵件的電子郵件地址。

默認為 root@localhost。強烈建議更改此值以確保可靠的電子郵件傳送。

mail.host

在 `config.yml` 中聲明。

用於 SMTP 連接的主機名。

默認為 localhost.

mail.port

在 `config.yml` 中聲明。

用於 SMTP 連接的連接端口。

默認為 25

mail.username

在 `config.yml` 中聲明。

使用 SMTP 服務器進行身份驗證時使用的用戶名。

默認為 (empty)

mail.password

在 `config.yml` 中聲明。

使用 SMTP 服務器進行身份驗證時使用的密碼。

默認為 (empty)

mail.use-ssl

在 `config.yml` 中聲明。

Sentry 在連接到 SMTP 服務器時是否應該使用 SSL?

默認為 false

mail.use-tls

在 `config.yml` 中聲明。

Sentry 在連接到 SMTP 服務器時應該使用 TLS 嗎?

默認為 false

mail.list-namespace

在 `config.yml` 中聲明。

此 Sentry 服務器發送的電子郵件的郵件列表命名空間。這應該是您擁有的域(通常與 mail.from 配置參數值的域部分相同)或 localhost

入站 Email

對於配置,您可以從不同的後端進行選擇。

Mailgun

首先選擇一個域來處理入站電子郵件。我們發現如果您維護一個與其他任何事物分開的域,這是最簡單的。
在我們的示例中,我們將選擇 inbound.sentry.example.com。您需要根據 Mailgun 文檔為給定域配置 DNS 記錄。

mailgun 中創建一個新路由:

Priority:
  0
Filter Expression:
  catch_all()
Actions:
  forward("//sentry.example.com/api/hooks/mailgun/inbound/")
Description:
  Sentry inbound handler

使用適當的設置配置 Sentry

# 您的 Mailgun API key(用於驗證傳入的 webhook)
mail.mailgun-api-key: ""

# 將 SMTP hostname 設置為您配置的入站域
mail.reply-hostname: "inbound.sentry.example.com"

# 通知 Sentry 發送適當的郵件頭以啟用
# 收到答覆
mail.enable-replies: true

就是這樣!您現在可以通過電子郵件客戶端響應有關錯誤的活動通知。

節點存儲

Sentry 提供了一個名為 『nodestore』 的抽象,用於存儲 key/value blob

默認後端只是將它們作為 gzipped blob 存儲在默認數據庫的 『nodestore_node』 表中。

Django 後端

Django 後端使用 gzipped json blob-as-text 模式將所有數據存儲在 『nodestore_node』 表中。

後端不提供任何選項,因此只需將其設置為空字典即可。

SENTRY_NODESTORE = 'sentry.nodestore.django.DjangoNodeStorage'
SENTRY_NODESTORE_OPTIONS = {}

自定義後端

如果你有一個最喜歡的數據存儲解決方案,它只需要在一些規則下運行,它就可以與 Sentryblob 存儲一起工作:

  • 設置 key/value
  • 獲取 key
  • 刪除 key

有關實現自己的後端的更多信息,請查看 sentry.nodestore.base.NodeStorage

文件存儲

Sentry 提供了一個名為 『filestore』 的抽象,用於存儲文件(例如發佈工件)。

默認後端將文件存儲在不適合生產使用的 /tmp/sentry-files 中。

文件系統後端

filestore.backend: "filesystem"
filestore.options:
  location: "/tmp/sentry-files"

Google Cloud 存儲後端

除了下面的配置之外,您還需要確保 shell 環境設置了變量 GOOGLE_APPLICATION_CREDENTIALS
有關詳細信息,請參閱 用於設置身份驗證的 Google Cloud 文檔

filestore.backend: "gcs"
filestore.options:
  bucket_name: "..."

Amazon S3 後端

S3 存儲後端支持使用 access keyIAM 實例角色進行身份驗證。
使用後者時,省略 access_keysecret_key
默認情況下,S3 對象是使用 public-read ACL 創建的,這意味着除了 PutObjectGetObjectDeleteObject 之外,
所使用的帳戶/角色還必須具有 PutObjectAcl 權限。
如果您不希望您上傳的文件可公開訪問,您可以將 default_acl 設置為 private

filestore.backend: "s3"
filestore.options:
  access_key: "..."
  secret_key: "..."
  bucket_name: "..."
  default_acl: "..."

MinIO S3 後端

filestore.backend: "s3"
filestore.options:
  access_key: "..."
  secret_key: "..."
  bucket_name: "..."
  endpoint_url: "//minio.example.org/"

時間序列存儲

Sentry 提供存儲時間序列數據的服務。這主要用於顯示事件和項目的匯總信息,以及(實時)計算事件發生率。

RedisSnuba 後端(推薦)

這是唯一一個 100% 正確工作的後端

SENTRY_TSDB = 'sentry.tsdb.redissnuba.RedisSnubaTSDB'

該後端與 Snuba 通信以獲取與事件攝取(event ingestion)相關的指標,並與 Redis 通信以獲取其他所有內容。
Snuba 需要運行自己的結果消費者(outcomes consumer),目前這不是 devservices 的一部分。

包裝的 Redis TSDB 可以這樣配置(有關 Redis 選項,請參閱下文):

SENTRY_TSDB_OPTIONS = {
    'redis': ... # RedisTSDB 的選項字典在這裡
}

Dummy 後端

顧名思義,所有 TSDB 數據將在寫入時刪除並在讀取時替換為零:

SENTRY_TSDB = 'sentry.tsdb.dummy.DummyTSDB'

Redis 後端

「裸」 Redis 後端讀取和寫入所有數據到 Redis。與事件攝取(Organization Stats)相關的各個列將顯示歸零數據,因為該數據僅在 Snuba 中可用。

SENTRY_TSDB = 'sentry.tsdb.redis.RedisTSDB'

默認情況下,這將使用名為 defaultRedis 集群。要使用不同的集群,請提供 cluster 選項,如下所示:

SENTRY_TSDB_OPTIONS = {
    'cluster': 'tsdb',
}

寫 Buffer

Sentry 通過在一段時間內 buffer 寫入和刷新對數據庫的批量更改來管理數據庫行爭用。 如果您具有高並發性,這將非常有用,尤其是當它們經常是同一個事件時。

例如,如果您碰巧每秒接收 100,000 個事件,並且其中 10% 向數據庫報告連接問題(它們將被組合在一起),
啟用 buffer 後端將改變事情,以便每個計數更新實際上是放入隊列中,所有更新都以隊列可以跟上的速度執行。

配置

要指定後端,只需修改配置中的 SENTRY_BUFFERSENTRY_BUFFER_OPTIONS 值:

SENTRY_BUFFER = 'sentry.buffer.base.Buffer'

Redis

配置 Redis 後端需要隊列,否則您將看不到任何收益(事實上,您只會對性能產生負面影響)。

配置是直截了當的:

SENTRY_BUFFER = 'sentry.buffer.redis.RedisBuffer'

默認情況下,這將使用名為 defaultRedis 集群。要使用不同的集群,請提供 cluster 選項,如下所示:

SENTRY_BUFFER_OPTIONS = {
    'cluster': 'buffer',
}

指標

Sentry 提供了一種稱為 『metrics』 的抽象,用於內部監控,通常是計時和各種計數器。

默認後端只是丟棄它們(儘管某些值仍保留在內部時間序列數據庫中)。

Statsd 後端

SENTRY_METRICS_BACKEND = 'sentry.metrics.statsd.StatsdMetricsBackend'
SENTRY_METRICS_OPTIONS = {
    'host': 'localhost',
    'port': 8125,
}

Datadog 後端

Datadog 將要求您將 datadog 包安裝到您的 Sentry 環境中:

$ pip install datadog

在你的 sentry.conf.py 中:

SENTRY_METRICS_BACKEND = 'sentry.metrics.datadog.DatadogMetricsBackend'
SENTRY_METRICS_OPTIONS = {
    'api_key': '...',
    'app_key': '...',
    'tags': {},
}

安裝後,Sentry 指標將通過 HTTPS 發送到 Datadog REST API

DogStatsD 後端

使用 DogStatsD 後端需要一個 Datadog AgentDogStatsD 後端一起運行(默認情況下在端口 8125)。

您還必須將 datadog Python 包安裝到您的 Sentry 環境中:

$ pip install datadog

在你的 sentry.conf.py 中:

SENTRY_METRICS_BACKEND = 'sentry.metrics.dogstatsd.DogStatsdMetricsBackend'
SENTRY_METRICS_OPTIONS = {
    'statsd_host': 'localhost',
    'statsd_port': 8125,
    'tags': {},
}

配置完成後,指標後端將發送到 DogStatsD 服務器,然後通過 HTTPS 定期刷新到 Datadog

Logging 後端

LoggingBackend 將所有操作報告給 sentry.metrics logger
除了指標名稱和值之外,日誌消息還包括額外的數據,例如可以使用自定義格式化程序顯示的 instancetags 值。

SENTRY_METRICS_BACKEND = 'sentry.metrics.logging.LoggingBackend'

LOGGING['loggers']['sentry.metrics'] = {
    'level': 'DEBUG',
    'handlers': ['console:metrics'],
    'propagate': False,
}

LOGGING['formatters']['metrics'] = {
    'format': '[%(levelname)s] %(message)s; instance=%(instance)r; tags=%(tags)r',
}

LOGGING['handlers']['console:metrics'] = {
    'level': 'DEBUG',
    'class': 'logging.StreamHandler',
    'formatter': 'metrics',
}

配額

使用 Sentry 的工作方式,您可能會發現自己處於這樣一種情況:您會看到太多的入站流量,而沒有一個好的方法來丟棄多餘的消息。對此有幾種解決方案,如果您遇到此問題,您可能希望全部使用它們。

事件配額

Sentry 中限制工作負載的主要機制之一涉及設置事件配額。這些可以在每個項目和系統範圍內進行配置,並允許您限制在 60 秒時間內接受的最大事件數。

配置

主要實現使用 Redis,只需要你配置連接信息:

SENTRY_QUOTAS = 'sentry.quotas.redis.RedisQuota'

默認情況下,這將使用名為 defaultRedis 集群。要使用不同的集群,請提供 cluster 選項,如下所示:

SENTRY_QUOTA_OPTIONS = {
    'cluster': 'quota',
}

如果您有其他需求,您可以像 Redis 實現一樣自由擴展基本 Quota 類。

全系統速率限制

您可以配置系統範圍的最大每分鐘速率限制:

system.rate-limit: 500

例如,在您項目的 sentry.conf.py 中,您可以執行以下操作:

from sentry.conf.server import SENTRY_OPTIONS


SENTRY_OPTIONS['system.rate-limit'] = 500

或者,如果您導航到 /manage/settings/,您將找到一個管理面板,其中包含一個用於設置 Rate Limit 的選項,該選項存儲在上述配額實施中。

基於用戶的速率限制

您可以配置基於用戶的每分鐘最大速率限制:

auth.user-rate-limit: 100
auth.ip-rate-limit: 100

基於項目的速率限制

要進行基於項目的速率限制,請單擊項目的 Settings
Client Keys (DSN) tab 下,找到你想要限速的 key,點擊對應的 Configure 按鈕。這應該會顯示 key/project-specific 的速率限制設置。

Notification 速率限制

在某些情況下,可能會擔心限制諸如出站電子郵件通知之類的內容。為了解決這個問題,Sentry 提供了一個支持任意速率限制的速率限制子系統。

配置

與事件配額一樣,主要實現使用 Redis

SENTRY_RATELIMITER = 'sentry.ratelimits.redis.RedisRateLimiter'

默認情況下,這將使用名為 default 的 Redis 集群。要使用不同的集群,請提供 cluster 選項,如下所示:

SENTRY_RATELIMITER_OPTIONS = {
    'cluster': 'ratelimiter',
}

Notification 摘要

Sentry 提供了一項服務,該服務將在通知發生時收集通知,並安排它們作為聚合 「digest」 通知進行傳送。

配置

儘管 digest 系統配置了一組合理的默認選項,但可以使用 SENTRY_DIGESTS_OPTIONS 設置來微調 digest 後端行為,以滿足您獨特安裝的需要。
所有後端共享下面定義的一組通用選項,而某些後端還可能定義特定於其各自實現的附加選項。

minimum_delay: minimum_delay 選項定義了默認的最小時間量(以秒為單位),以在初始調度後在調度 digest 之間等待交付。這可以在 Notification 設置中按項目覆蓋。

maximum_delay: maximum_delay 選項定義了在調度 digest 之間等待傳送的默認最長時間(以秒為單位)。這可以在 Notification 設置中按項目覆蓋。

increment_delay: increment_delay 選項定義了在最後一次處理 digest 之後的 maximum_delay 之前,事件的每個觀察應該延遲調度多長時間。

capacity: capacity 選項定義了時間線內應包含的最大 item 數。這是硬限制還是軟限制取決於後端 – 請參閱 truncation_chance 選項。

truncation_chance: truncation_chance 選項定義了 add 操作觸發時間線截斷以使其大小接近定義容量的概率。值為 1 將導致時間線在每次 add 操作時被截斷(有效地使其成為硬限制),而較低的概率會增加時間線超過其預期容量的機會,但通過避免截斷來執行操作會提高 add 的性能,截斷是一項潛在的昂貴操作,尤其是在大型數據集上。

後端

Dummy 後端

Dummy 後端禁用摘要調度,所有通知都會在發生時發送(受速率限制)。這是在版本 8 之前創建的安裝的默認 digest 後端。

可以通過 SENTRY_DIGESTS 設置指定 dummy 後端:

SENTRY_DIGESTS = 'sentry.digests.backends.dummy.DummyBackend'

Redis 後端

Redis 後端使用 Redis 來存儲 schedule 和待處理 notification 數據。這是自版本 8 以來創建的安裝的默認 digest 後端。

Redis 後端可以通過 SENTRY_DIGESTS 設置來指定:

SENTRY_DIGESTS = 'sentry.digests.backends.redis.RedisBackend'

Redis 後端接受基本集之外的幾個選項,通過 SENTRY_DIGESTS_OPTIONS 提供:

cluster : cluster 選項定義了應該用於存儲的 Redis 集群。如果未指定集群,則使用 default 集群。

在將數據寫入 digest 後端後更改 cluster 值或集群配置可能會導致意外影響 – 即,它會在集群大小更改期間造成數據丟失的可能性。應在運行系統上小心調整此選項。

ttl : ttl 選項定義 recordtimelinedigest 的生存時間(以秒為單位)。這可以(也應該)是一個相對較高的值,因為 timelinedigestrecord 在處理後都應該被刪除——這主要是為了確保在配置錯誤的情況下過時的數據不會停留太久 . 這應該大於最大調度延遲,以確保不會過早驅逐數據。

示例配置

SENTRY_DIGESTS = 'sentry.digests.backends.redis.RedisBackend'
SENTRY_DIGESTS_OPTIONS = {
    'capacity': 100,
    'cluster': 'digests',
}

Relay

Relay 是一種用於事件過濾、速率限制和處理的服務。 它可以作為:

Snuba

後端 Chart 渲染

Sentry 的前端為用戶提供了各種類型的詳細交互式圖表,高度符合 Sentry 產品的外觀和感覺。
從歷史上看,這些圖表只是我們在 Web 應用程序中才有的東西。

然而,在某些情況下,在應用程序的某些上下文中顯示圖表非常有價值。例如

  • Slack 展開 Discover 圖表、指標警報通知、問題詳細信息或 Sentry 中的任何其他鏈接,其中在 Slack 中查看圖表可能很有用。

  • 通知摘要電子郵件。將趨勢可視化為圖表。

幸運的是,Sentry 為內部 Chartcuterie NodeJS 服務提供了內置功能,它可以通過 HTTP API 以圖像格式生成圖形。
圖表是使用前端使用的相同 ECharts 庫生成的。
ChartcuterieSentry 的前端共享代碼,這意味着可以在前端和後端 Chartcuterie 生成的圖表之間輕鬆維護圖表的外觀。

在 Sentry 的後端使用 Chartcuterie

使用 Chartcuterie 生成圖表非常簡單。

導入 generate_chart 函數,提供 chart 類型和 data 對象,獲取公共圖片 URL

from sentry.charts import generate_chart, ChartType

# The shape of data is determined by the RenderDescriptor in the
# configuration module for the ChartType being rendered.
data = {}

chart_url = generate_chart(ChartType.MY_CHART_TYPE, data)

配置 chart 以進行渲染

Chartcuteriesentry.io 加載一個外部 JavaScirpt 模塊,該模塊決定了它如何呈現圖表。
該模塊直接配置 EChart 的 options 對象,
包括在 POST /render 調用時提供給 Chartcuterie 的系列數據的轉換。

該模塊作為 getsentry/sentry 的一部分存在,
可以在 static/app/chartcuterie/config.tsx 中找到。

服務初始化

可以配置一個可選的初始化函數 init 在服務啟動時運行。
這個函數可以訪問 Chartcuterie 的全局 echarts 對象,
並且可以使用它來註冊實用程序(例如 registerMaps)。

添加/刪除 chart 類型

Chart 渲染是基於 每個 “chart type” 配置的。
對於每種類型的 chart,您都需要在前端應用程序和後端 chart 模塊中聲明一個眾所周知的名稱。

  1. 在前端,在 static/app/charctuerie/types.tsx 中添加一個 ChartType

  2. static/app/chartcuterie/config.tsx中註冊 chartRenderDescriptor,它描述了外觀和系列轉換。您可以為此使用 register 函數。

  3. 在後端,在 sentry.charts.types 模塊中添加一個匹配的 ChartType

  4. Sentry 中部署您的更改。配置模塊將在 5 分鐘內自動傳播到 Chartcuterie

    您無需部署 Charcuterie

不要在配置模塊的同時部署使用新 chart type 的功能。由於存在傳播延遲,因此不能保證新 chart type 在部署後立即可用。

配置模塊包括部署的 sentry.io 提交 SHA,它允許 Chartcuterie 在每個輪詢 tick 時檢查它是否收到了新的配置模塊。

在開發中運行 Chartcuterie

要在本地開發人員環境中啟用 Chartcuterie,請首先在 config.yml 中啟用它:

# 啟用 charctuerie
chart-rendering.enabled: true

目前您需要在您的開發環境中手動構建配置模塊。

yarn build-chartcuterie-config

然後您可以啟動 Chartcuterie devservice。如果 devservice 沒有啟動,
請檢查 chart-render.enabled key 是否正確設置為 true(使用 sentry config get chart-rendering.enabled)。

sentry devservices up chartcuterie

您可以通過檢查日誌來驗證服務是否已成功啟動

docker logs -f sentry_chartcuterie

應該是這樣的

info: Using polling strategy to resolve configuration...
info: Polling every 5s for config...
info: Server listening for render requests on port 9090
info: Resolved new config via polling: n styles available. {"version":"xxx"}
info: Config polling switching to idle mode
info: Polling every 300s for config...

您的開發環境現在已準備好調用 Chartcuterie 的本地實例。

在本地更新 chart type

當前,您需要在每次更改時使用 yarn build-chartcuterie-config 重建配置模塊。 這在未來可能會得到改善。

工作原理

下面是 Chartcuterie service 的幾個 service 圖以及它如何與 Sentry 應用程序服務器交互。

Chartcuterie 啟動

來自 Sentry 的 Render 調用

公眾號:黑客下午茶