地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

SlackBotでPagerDutyを操作する

この記事は「PagerDuty Advent Calendar 2023」の24日目の記事です!前日は @manji0さんの PagerDutyのAPIの使い方でした。PagerDutyのAPIの使い方が紹介されており今回自分が書く記事にも近い部分があって学びがあってよかったです!

PagerDuty APIの使い方

前述したように使い方的な話はqiita.com がこちらが詳しいので是非ご参照ください。

また13日目のリナルディさんの記事の 【入門】PagerDuty Event API || REST API も今回は使っていないEvent APIが取り上げられていて大変参考になります!

SlackBotの実装

PagerDutyの操作は公式のライブラリが提供されているのでそちらを使います。公式ドキュメントも充実しており私がやりたかったことは全てそちらに書いてありとても助かりました。

github.com

今回書いている記事で使っているSlackBotは結構サービス固有の設定やコメントを書いてしまっており現時点では公開していませんが雰囲気としては以下のように作っています。SlackBotの呼び出しコマンドごとにgo-pagerdutyの機能を呼び出すことで実現しています。

package main

import (
    "context"
    "fmt"
    "os"

    "github.com/PagerDuty/go-pagerduty"
)

type Client struct {
    client *pagerduty.Client
    ctx    context.Context
}

func New(authToken string, ctx context.Context) *Client {
    return &Client{
        client: pagerduty.NewClient(authToken),
        ctx:    ctx,
    }
}

func (p *Client) ListSchedule() (string, error) {
    var lo pagerduty.ListSchedulesOptions
    schedules, err := p.client.ListSchedulesWithContext(p.ctx, lo)
    if err != nil {
        return "", err
    }

    var msg string
    for _, sched := range schedules.Schedules {
        msg += fmt.Sprintf("name: %s, ID: %s\n", sched.Name, sched.ID)
    }

    return msg, nil
}

Botでは何ができるの?

@pd-bot-kaiというbotをSlackに常駐させておきコマンドを実行することでPagerDutyAPIを叩きにいくといった仕組みで動いています。名前にkaiって入っているのはpd-botという前身がいたからなのですがGoで再実装した際にそういう名前になりました。以下が実行時の例になります。

# ユーザー一覧を出す
@pd-bot-kai list user

# ユーザー詳細を出す
@pd-bot-kai user ${ユーザー名}

オンコールスケジュールの確認

@pd-bot-kai sched ${サービス名} と呼び出すことでそのサービスをオンコールのスケジュールを確認する機能です。スケジュールの一覧を出力するための@pd-bot-kai list schedという機能も実装しています。

オンコールシフトのオーバーライド

@pd-bot-kai ${サービス名} day|night ${ユーザー名}と呼び出すことでそのサービスのオンコールシフトをオーバーライドします。例えば一時的にオンコールを取ることができないタイミング(離席やMTGなど)のタイミングで電話が鳴るとすぐにエスカレーションをして次のメンバーに渡すみたいな場面がありましう。一時的なスケジュールの変更であればPagerDutyにはオーバーライドという機能があります。その機能を使うことで実現できるのですがSlackから呼び出して使うための機能になります。指定した時間だけ設定されたユーザーがオンコールを取るようになります。

夜間のアラートの確認

@pd-bot-kai ${サービス名} list oncallとすることで夜間なったアラートの一覧を取得することができます。PagerDutyではアラートがなってからの通知方法を自分でカスタマイズする機能があります。例えばDBのプロセスが一時的にいなくなったというアラートが出たらすぐに電話で通知するではなく1分後にメールの送信、Slackへの通知をした後に電話を鳴らすといった機能です。これはあまりチューニングされていない外形監視が落ちた際に毎回電話を鳴らすというように睡眠妨害になってしまったりして電話での呼び出しまでに猶予を持つことができるという使い方ができます。(もちろんそんなアラート自体消してしまうや閾値を変えるという方法が好ましいですが現実的には全てをそういうふうに変えることは難しいためそうなっていたりします)。そうなったときに夜間に復旧とアラートを繰り返すような場合に気付けなかったりするのでアラートのリストを表示するといった使い方をしています。

サービス単位のサイレント

例えばサービスの主要なコンポーネントに障害があったとします。例えば共通で使っているロードバランサーはデータベースが仮に障害で落ちてしまった時にアラートは大量に発生することが予想されます。例えば同じ経路を通る外形監視であればそれぞれ設定されている監視分のアラートが飛びます。100個の外形監視があったら100回アラートがなってPagerDutyから通知が来てしまいます。AI Opsなどをうまく使いこなせばある程度は通知をまとめられるのかもしれませんがDB障害になると外形監視以外にも関連性があるか不明なアラートが大量になってしまうことが考えられます。その際に便利なのがこの機能です。@pd-bot-kai silence ${サービス名} ${サイレンスする時間}と実行することでPagerDutyをメンテナンスモードにしアラートの通知が来なくなるようにする仕組みです。MackerelやGrafanaが出すアラート自体はSlackに通知し続けるのでPagerDutyからの通知を止めるためだけに使用しています。

その他

他にもAPIを叩くような実装を色々入れています。

  • ユーザーリスト/詳細の出力
  • チームのリスト/詳細の出力
  • オンコールスケジュールの確認

終わりに

オンコール × 睡眠は個人的にはずっとホットなトピックでこれからも全てのエンジニアの睡眠が守られるような取り組みを行っていきたいなと思いました。

atmarkit.itmedia.co.jp

PagerDutyの機能は日々進化しているのはメールやフィードからは気づいているのですがあまりキャッチアップできてるとは言えないので今後も情報を追って便利な機能はガンガン導入するということをやっていきたいなと思います。

参考

www.pagerduty.co.jp

ueokande.github.io

www.pagerduty.co.jp