📘

GolangからPagerdutyのインシデントを発砲する

2024/12/11に公開

目的

Golangで作成したアプリケーションからPagerdutyの任意のインシデントを発砲する

Event API v2

Event Types

Alert

  • 監視システムの問題。 既存のアラートを確認または解決するためにイベントを送信することができる
  • ex
    • High error rate
    • CPU usage exceeded limit
    • Deployment failed

Change

  • 問題ではないシステムの変更
  • ex
    • Pull request merged
    • Secret successfully rotated
    • Configuration update applied

インシデントの作成

  • Alert Eventを送信するとインシデントが作成され、オンコール対応者に割り当てられます。これにより、通知(電話、SMS、電子メール、またはオンコール対応者の設定に応じたモバイルプッシュ通知)が生成されます。

Alert Eventの送信

  • POST Request
  • endpoint
  • 必須のparameters
    • routing_key
      • Integration Key
    • event_action
      • trigger
        • 問題の発生
      • acknowledge
        • 問題の確認
      • resolve
        • 問題が修正された
    • payload.summary
      • 概要
    • payload.source
      • 影響を受けるシステムの固有の場所。ホスト名やFQDN
    • payload.severity(critical, error, warning or info)
      • 重要度
  • オプションのparameters
    • dedup_key
      • 重複排除キー
    • client
      • イベントをトリガーしているモニタリングクライアントの名前
    • client_url
      • イベントをトリガーしているモニタリングクライアントのURL
    • payload.timestamp
    • payload.component
      • イベントの原因となっているソースマシンのコンポーネント(mysqlやeth0)
    • payload.group
      • コンポーネントを論理的にグループ化したもの(app-slack)
    • payload.class
      • 任意の種類
    • payload.custom_details
      • 任意のデータ
      • JSON形式にするとテーブル構造で表示される
    • images
    • links
$ curl --request POST \
  --url https://events.pagerduty.com/v2/enqueue \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{
  "payload": {
    "summary": "DISK at 99% on machine prod-datapipe03.example.com",
    "timestamp": "2015-07-17T08:42:58.315+0000",
    "severity": "critical",
    "source": "prod-datapipe03.example.com",
    "component": "mysql",
    "group": "prod-datapipe",
    "class": "disk",
    "custom_details": {
      "free space": "1%",
      "ping time": "1500ms",
      "load avg": 0.75
    }
  },
  "routing_key": "e93facc04764012d7bfb002500d5d1a6",
  "dedup_key": "srv01/mysql",
  "event_action": "trigger",
  "client": "Sample Monitoring Service",
  "client_url": "https://monitoring.service.com",
  "links": [
    {
      "href": "http://pagerduty.example.com",
      "text": "An example link."
    }
  ],
  "images": [
    {
      "src": "https://chart.googleapis.com/chart?chs=600x400&chd=t:6,2,9,5,2,5,7,4,8,2,1&cht=lc&chds=a&chxt=y&chm=D,0033FF,0,0,5,1",
      "href": "https://google.com",
      "alt": "An example link with an image"
    }
  ]
}'
{
  "status": "success",
  "message": "Event processed",
  "dedup_key": "srv01/HTTP"
}

やり方

Integration Key(routing_key)を取得する

  1. Service DirectoryからServiceを作成する
  2. ServiceのIntegrationsから"Event API v2"を追加する

go-pagerdutyの利用

package main

import (
	"context"
	"errors"
	"log"
	"strings"
	"time"

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

func send(ctx context.Context, integrationKey, summary, source, severity, details string) error {
	event := pagerduty.V2Event{
		RoutingKey: integrationKey, // 前項で取得したkey
		Action:     "trigger", // インシデントの作成
		Payload: &pagerduty.V2Payload{ // 必須のparameter
			Summary:   summary,
			Source:    source,
			Severity:  severity,
			Timestamp: time.Now().Format(time.DateTime),
			Details:   details,
		},
	}

	res, err := pagerduty.ManageEventWithContext(ctx, event)
	if err != nil {
		return err
	}
	if res.Status != "success" {
		return errors.New(strings.Join(res.Errors, "\n"))
	}

	return nil
}

参考

https://developer.pagerduty.com/docs/3d063fd4814a6-events-api-v2-overview
https://developer.pagerduty.com/docs/ZG9jOjExMDI5NTgx-send-an-alert-event
https://developer.pagerduty.com/api-reference/368ae3d938c9e-send-an-event-to-pager-duty

Discussion