高效利用Sentry追蹤日誌發現問題

面臨的問題

程序運行的日誌是一個必不可少的東西,可能是一些系統信息,比如 gc 的情況;可能是一些正常的模塊處理信息,比如最近更新的配置;還可能是一些在程序運行中,我們不希望出現的錯誤所帶來的信息。通過日誌,可以知道我們的程序是不是在正常地運行,看到錯誤日誌,我們還需要利用日誌排查錯誤。

我們知道日誌如此重要,並樂於記錄日誌,然而在發現並解決問題的過程中,日誌並沒有想像中的高效率。

作者Daisy 豈安科技框架研發負責人

主導底層框架系統和 Warden java 服務端的研發工作。擅長 Java 研發、分散式系統、監控系統以及各類開源項目的引入和改造。更多乾貨關注微信公眾:bigsec

01文件過於分散

一般會將不同模塊的日誌以文件的形式分開保存。即使是將日誌寫在統一的目錄下,不管是系統正常運行還是出現問題的時候都可能需要檢查多個日誌。

02內容過於繁雜

不太同於代碼崇尚簡潔,特別是遇到問題的時候,日誌更是越詳細越好,巴不得日誌能記錄下所有上下文信息和關聯的代碼。但是在查看日誌的時候卻往往不得不反覆前後翻看錯誤的關聯日誌信息,同時還要略過大量無關信息,還沒開始解決問題腦細胞就死了好多。

03解決問題的被動性

很可能在程序剛開始運行起來的時候,我們會檢查一下情況,看看日誌是否正常。但是更多的時候我們根本不會想去看那些冗長的日誌。過了一段時間,突然有人告訴我們問題出現了,便又懷著沉重的心情慌張地檢查日誌開始排查錯誤。

如何解決

考慮傳統的解決方案,規定好統一的日誌格式,將所有模塊的日誌進行適配之後統一管理起來,並建立相應的日誌分類與報表,在檢查到問題的時候通過郵件的形式通知運維。這樣的解決方案對於小公司來說,需要的時間和技術成本還是很大的,真正能提高日誌利用的效率,還需要很長的規劃與不斷的總結。

而我們這樣的小公司就中意這樣的簡單粗暴的方案:

1 個小時搭建整個平台!日誌彙集、聚合、主動報警、漂亮的界面,都有了—— Sentry

那麼 Sentry 到底如何幫助我們有效利用日誌發現並解決程序問題的呢?

Sentry 初試

Server 的安裝教程官網已經非常詳細了,如果不要求 HA ,只需要額外確定依賴的 redis 和 postgresql 安裝好了就行。

支持多種語言與框架的客戶端

Sentry 不但有多種語言的客戶端,還直接支持大量的日誌框架,比如 java 的 log4j ,logback 。這就意味著我們之前的代碼幾乎可以不用做任何修改,而僅僅加一點配置即可。

官方 saas

如果想要快速欣賞一下 Sentry 的芳容,可以現在就嘗試一下官方的 saas (當然它是免費的):

Sentry 團隊很貼心地讓你可以快速建立一個自己的 demo 嘗試它的運用。

簡單的使用示例bigsec

拿官方的 saas 快速認識 Sentry :

註冊好你的賬戶後,會有提示幫助你建立好自己的項目,並選擇想要使用的客戶端平台或框架(這裡以 logback 為例):

到這裡為止,我們就差一步就可以看到效果了:添加一個依賴和一個 logback 的 appender 到你的項目配置里,其他的代碼可以一點不變,記日誌還是熟悉的配方。

配置好依賴和 appender ,運行一些寫入日誌的代碼後,你就會收到兩方面的反饋:

01面板上出現待解決的 issues :

02收到新 issues 的郵件:

怎麼樣,對 Sentry 已經有了一個直觀的感受了吧。

Sentry 如何解決問題

我們使用 Sentry 就是為了解決日誌利用的低效率問題,那麼 Sentry 是怎麼幫助我們解決的呢。答案就在幾個重要的概念中,當然 Sentry 有詳盡的官方使用說明和文檔。

  • dsn(data source name):

示例中是加在 appender 中的標籤。這個就是 Sentry 的實際連接地址, Sentry 通過這個來知道到底將日誌發送到哪裡。

  • issues & events:

從上面的圖可以發現有 3 個 error 標記的 issue 標籤,實際上代碼裡面發送了 5 條 error 的日誌。這是 Sentry 很重要的一點:

我們需要看的不是單單一條日誌,而是一類日誌。

一些聚集的日誌才能儘可能地反映整個錯誤的情況,即一個 issue ,而這些有關聯的日誌在 Sentry 這邊就轉化為這個 issue 的關聯的 events 。

回想一下我們通過日誌文件來排查錯誤的時候,是不是就是自己耐心地運用肉眼過濾掉一系列無關的日誌,然後大腦中聚合好這些有關聯的日誌,儘可能全面地了解一個錯誤呢。

除了幫我們省掉這些事情,Sentry 提供了更豐富的數據來充實這些 events ,點擊一個 issue ,便會進入這個 issue 的詳細信息:

不僅可以看到我們主動加上的 message , stacktrace , Sentry 還幫我們加上了一些額外的 tags (我們也需要自己去定義一些有用的 tags ),儘可能多的展現一個 issue 發生前的狀況。另外一個亮點在右邊,展示了這個 issue 的一些統計信息。

  • Sampling

Sentry 不是為了日誌存儲,也不會將所有日誌都記錄下來(畢竟使用關係型資料庫作為持久化存儲)。每個發送到 Sentry 的日誌都是一個提供 issue 信息的事件(event),而每個項目發送到 Sentry 的事件都有一個數量上限,一旦超過這個上限 Sentry 就會忽略掉重複的內容。

Sentry 是我們所有日誌的一個關於錯誤,問題的分析子集。體現在界面上的 events 信息,也是 Sentry 聚合之後的樣本。

  • 聚合策略

Sentry 按照策略將日誌事件進行聚合,從而提供一個 issue的events 。這麼做就是為了智能地幫助我們組合關聯的日誌信息,減少人工的日誌信息的提取工作量,關注一個 issue 首先關注這些聚合的事件。但是這個策略分組並不會那麼智能,Sentry 主要按照以下幾個方面,優先順序從高到低進行日誌事件的聚合:

  • Stacktrace
  • Exception
  • Template
  • Messages

要注意的是,如果日誌記錄比較隨意,聚合的效果可能不盡如人意。例如:兩個無關的事件但是 stacktrace 相同,那麼 Sentry 會將它們分到同一個 issue 下。

  • alerts digest & limit

默認 Sentry 的 alerts 會發送郵件(你也可以推送 slack!)。當一個 issue 產生或者一組 issue 產生時,項目相關的成員都會受到郵件。但是並不是每次 issue 有更新就會產生 alert 。

考慮到用戶也不希望被一籮筐的報警郵件給轟炸,因為過多相當於沒有, Sentry 除了對重複的報警進行抑制,還會追加一段時間內更新 issue 的摘要(digest)到下一個報警,這樣,用戶郵件上接收到的信息會充分壓縮,不用苦惱於過多的郵件。另外,每個用戶可以根據自己的喜好自行配置報警的時間間隔。

總結

Sentry 還有有很多亮點,比如敏感信息過濾, release 版本跟蹤,關鍵字查找,受影響用戶統計,許可權管理等(部分可能需要我們通過代碼提供內容)可以通過 Sentry 進行問題分配與跟蹤。Sentry 的 plugin 模塊還可以集成大量的第三方工具如: slack , jira 。

對我們來說最大的便利就是利用日誌進行錯誤發現和排查的效率變高了。

01及時提醒

報警的及時性:不需要自己再去額外集成報警系統,一旦產生了 issue 便以郵件通知到項目組的每個成員。

02問題關聯信息的聚合

每個問題不僅有一個整體直觀的描繪,聚合的日誌信息省略了人工從海量日誌中尋找線索,免除大量無關信息的干擾。

03豐富的上下文

Sentry 不僅豐富還規範了上下文的內容,也讓我們意識到更多的有效內容,提高日誌的質量。

最後,完全依賴Sentry?

雖然 Sentry 讓我們在使用日誌上的效率提高了,但是有幾點還是需要注意。

01不是日誌的替代

Sentry 的目的是為了讓我們專註於系統與程序的異常信息,目的是提高排查問題的效率,日誌事件的量到達一個限制時甚至丟棄一些內容。官方也提倡正確設置 Sentry 接收的日誌 level 的同時,用戶也能繼續舊的日誌備份(用 logback 的同學僅僅是保留自己以前的 appender 就好)。

02不是排查錯誤的萬能工具

Sentry 是帶有一定策略的問題分析工具,以樣本的形式展示部分原始日誌的信息。信息不全面的同時,使用過程中也可能出現 Sentry 聚合所帶來的負面影響,特別是日誌記錄質量不夠的情況下。

03不是傳統監控的替代品

與傳統的監控系統相比,Sentry 更依賴於發出的日誌報告,而另外一些隱藏的邏輯問題或者業務問題很可能是不會得到反饋的。

推薦閱讀:

TAG:日志分析 | 标签Tag | 聚合 |