Linux中國

通過 Slack 監視慢 SQL 查詢

我的 Slack 機器人提示我一個運行了很長時間 SQL 查詢。我應該儘快解決它。

我們不能管理我們無法去測量的東西。每個後台應用程序都需要我們去監視它在資料庫上的性能。如果一個特定的查詢隨著數據量增長變慢,你必須在它變得太慢之前去優化它。

由於 Slack 已經成為我們工作的中心,它也在改變我們監視系統的方式。 雖然我們已經有非常不錯的監視工具,如果在系統中任何東西有正在惡化的趨勢,讓 Slack 機器人告訴我們,也是非常棒的主意。比如,一個太長時間才完成的 SQL 查詢,或者,在一個特定的 Go 包中發生一個致命的錯誤。

在這篇博客文章中,我們將告訴你,通過使用已經支持這些特性的一個簡單的日誌系統一個已存在的資料庫庫(database library) 怎麼去設置來達到這個目的。

使用記錄器

logger 是一個為 Go 庫和應用程序使用設計的小型庫。在這個例子中我們使用了它的三個重要的特性:

  • 它為測量性能提供了一個簡單的定時器。
  • 支持複雜的輸出過濾器,因此,你可以從指定的包中選擇日誌。例如,你可以告訴記錄器僅從資料庫包中輸出,並且僅輸出超過 500 ms 的定時器日誌。
  • 它有一個 Slack 鉤子,因此,你可以過濾並將日誌輸入到 Slack。

讓我們看一下在這個例子中,怎麼去使用定時器,稍後我們也將去使用過濾器:

package main

import (
    "github.com/azer/logger"
    "time"
)

var (
  users = logger.New("users")
  database = logger.New("database")
)

func main () {
  users.Info("Hi!")

  timer := database.Timer()
  time.Sleep(time.Millisecond * 250) // sleep 250ms
  timer.End("Connected to database")

  users.Error("Failed to create a new user.", logger.Attrs{
    "e-mail": "foo@bar.com",
  })

  database.Info("Just a random log.")

  fmt.Println("Bye.")
}

運行這個程序沒有輸出:

$ go run example-01.go
Bye

記錄器是預設靜默的,因此,它可以在庫的內部使用。我們簡單地通過一個環境變數去查看日誌:

例如:

$ LOG=database@timer go run example-01.go
01:08:54.997 database(250.095587ms): Connected to database.
Bye

上面的示例我們使用了 database@timer 過濾器去查看 database 包中輸出的定時器日誌。你也可以試一下其它的過濾器,比如:

  • LOG=*: 所有日誌
  • LOG=users@error,database: 所有來自 users 的錯誤日誌,所有來自 database 的所有日誌
  • LOG=*@timer,database@info: 來自所有包的定時器日誌和錯誤日誌,以及來自 database 的所有日誌
  • LOG=*,users@mute: 除了 users 之外的所有日誌

發送日誌到 Slack

控制台日誌是用於開發環境的,但是我們需要產品提供一個友好的界面。感謝 slack-hook, 我們可以很容易地在上面的示例中,使用 Slack 去整合它:

import (
  "github.com/azer/logger"
  "github.com/azer/logger-slack-hook"
)

func init () {
  logger.Hook(&slackhook.Writer{
    WebHookURL: "https://hooks.slack.com/services/...",
    Channel: "slow-queries",
    Username: "Query Person",
    Filter: func (log *logger.Log) bool {
      return log.Package == "database" && log.Level == "TIMER" && log.Elapsed >= 200
    }
  })
}

我們來解釋一下,在上面的示例中我們做了什麼:

  • 行 #5: 設置入站 webhook url。這個 URL 鏈接在這裡
  • 行 #6: 選擇流日誌的入口通道。
  • 行 #7: 顯示的發送者的用戶名。
  • 行 #11: 使用流過濾器,僅輸出時間超過 200 ms 的定時器日誌。

希望這個示例能給你提供一個大概的思路。如果你有更多的問題,去看這個 記錄器的文檔。

一個真實的示例: CRUD

crud 是一個用於 Go 的資料庫的 ORM 式的類庫,它有一個隱藏特性是內部日誌系統使用 logger 。這可以讓我們很容易地去監視正在運行的 SQL 查詢。

查詢

這有一個通過給定的 e-mail 去返回用戶名的簡單查詢:

func GetUserNameByEmail (email string) (string, error) {
  var name string
  if err := DB.Read(&name, "SELECT name FROM user WHERE email=?", email); err != nil {
    return "", err
  }

  return name, nil
}

好吧,這個太短了, 感覺好像缺少了什麼,讓我們增加全部的上下文:

import (
  "github.com/azer/crud"
  _ "github.com/go-sql-driver/mysql"
  "os"
)

var db *crud.DB

func main () {
  var err error

  DB, err = crud.Connect("mysql", os.Getenv("DATABASE_URL"))
  if err != nil {
    panic(err)
  }

  username, err := GetUserNameByEmail("foo@bar.com")
  if err != nil {
    panic(err)
  }

  fmt.Println("Your username is: ", username)
}

因此,我們有一個通過環境變數 DATABASE_URL 連接到 MySQL 資料庫的 crud 實例。如果我們運行這個程序,將看到有一行輸出:

$ DATABASE_URL=root:123456@/testdb go run example.go
Your username is: azer

正如我前面提到的,日誌是 預設靜默的。讓我們看一下 crud 的內部日誌:

$ LOG=crud go run example.go
22:56:29.691 crud(0): SQL Query Executed: SELECT username FROM user WHERE email='foo@bar.com'
Your username is: azer

這很簡單,並且足夠我們去查看在我們的開發環境中查詢是怎麼執行的。

CRUD 和 Slack 整合

記錄器是為配置管理應用程序級的「內部日誌系統」而設計的。這意味著,你可以通過在你的應用程序級配置記錄器,讓 crud 的日誌流入 Slack :

import (
  "github.com/azer/logger"
  "github.com/azer/logger-slack-hook"
)

func init () {
  logger.Hook(&slackhook.Writer{
    WebHookURL: "https://hooks.slack.com/services/...",
    Channel: "slow-queries",
    Username: "Query Person",
    Filter: func (log *logger.Log) bool {
      return log.Package == "mysql" && log.Level == "TIMER" && log.Elapsed >= 250
    }
  })
}

在上面的代碼中:

  • 我們導入了 loggerlogger-slack-hook 庫。
  • 我們配置記錄器日誌流入 Slack。這個配置覆蓋了代碼庫中 記錄器 所有的用法, 包括第三方依賴。
  • 我們使用了流過濾器,僅輸出 MySQL 包中超過 250 ms 的定時器日誌。

這種使用方法可以被擴展,而不僅是慢查詢報告。我個人使用它去跟蹤指定包中的重要錯誤, 也用於統計一些類似新用戶登入或生成支付的日誌。

在這篇文章中提到的包

告訴我們 如果你有任何的問題或建議。

via: http://azer.bike/journal/monitoring-slow-sql-queries-via-slack/

作者:Azer Koçulu 譯者:qhwdw 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國