インシデントと JIRA の双方向連携のベストプラクティス¶
著者:蘇桐桐、劉鋭
インシデント は、Guanceが提供する、社内のインシデントを効果的に調整・管理するためのコミュニケーションツールです。
JIRA は、社内のプロジェクト管理ツールです。
Info
アプリケーションやシステムに異常が発生した場合、通常は迅速に対応してシステムの正常な動作を確保する必要があります。インシデントと JIRA の双方向連携により、社内の関係者が問題や障害の原因を迅速に理解・分析し、障害の処理プロセスを追跡・記録できるため、担当者間のコミュニケーション効率が効果的に向上し、障害処理コストが大幅に削減されます。
準備¶
- Jira プラットフォーム(管理者権限が必要)
- Guance ワークスペースアカウント
- Dataflux Func Guance特別版
Jira¶
Jira プラットフォームの該当プロジェクトの project、プロジェクトURL、api_token、username を取得します。これらは後続のGuanceスクリプトで使用します。
上記の操作は管理者のみが実行できます。
Guance¶
API Key の作成¶
API Key の作成方法については、ドキュメント API Key を参照してください。
key name は Jira システム と設定します。これにより、コメント情報がGuanceからのものか Jira からのものかを区別しやすくなり、key name はGuanceの issue 内で user として表示されます。
Func スクリプトの作成¶
- Func にログインする
デプロイ済みの Dataflux Func Guance特別版 にログインします。
-
Python 依存関係を追加する
-
管理 メニューをクリックします。
- 実験的機能 をクリックし、PIP ツールを有効にする スイッチをオンにします。既に有効な場合は、この手順をスキップしてください。
-
PIP ツール をクリックし、Python パッケージ のインストール画面で
jiraと入力し、デフォルトのデータソースを選択します。デフォルトのデータソースに依存関係がない場合は、他のデータソースに切り替えて、インストール ボタンをクリックし、依存関係のインストールを完了します。 -
スクリプトを作成する
-
開発 メニューをクリックします。
- スクリプトセットを作成 ボタンをクリックし、スクリプトセットの ID を入力します(任意の名前)。ここでは
Issue_to_jiraと入力し、保存 ボタンをクリックします。 Issue_to_jiraを選択し、新規スクリプト をクリックします。この ID も任意で構いません。- 以下のスクリプト内容を貼り付け、設定情報を調整します。
import requests
import json
import time
from datetime import datetime, timedelta
from jira import JIRA
# Guanceの設定。df_api_key を忘れずに変更してください。
base_url = 'https://openapi.guance.com'
channel_list_url = base_url + '/api/v1/channel/quick_list'
issue_list_url = base_url + '/api/v1/issue/list'
create_issue_reply_url = base_url + '/api/v1/issue/reply/create'
df_api_key = 'vy2EV......fuTtn'
# JIRAの設定。以下は必須項目です。ご自身の環境に合わせて変更してください。
username = 'sutt'
api_token = 'ATATT3xFfGF0eVvhZUkO0tTas8JnNYEsxGIJqWGinVyQL0ME......B6E'
jira_server_url = 'https://***.net/'
project_key = 'projectName'
#JIRAに接続
def connect_to_jira(username, api_token, jira_server_url):
try:
jira_connection = JIRA(basic_auth=(username, api_token), server=jira_server_url)
print("JIRAへの接続に成功しました!")
return jira_connection
except Exception as e:
print(f"JIRAへの接続中にエラーが発生しました: {e}")
return None
jira_instance = connect_to_jira(username, api_token, jira_server_url)
def sync_issues_from_guance_to_jira():
headers = {
'DF-API-KEY': df_api_key,
'Content-Type': 'application/json;charset=UTF-8'
}
one_minute_ago = datetime.now() - timedelta(minutes=1)
one_minute_ago_time = int(one_minute_ago.timestamp())
current_time = int(time.time())
response = requests.get(channel_list_url, headers=headers)
if response.status_code == 200:
channel_list = response.json()["content"]
for channel in channel_list:
if channel["name"] == "default":
body = {
'channelUUID': channel["uuid"],
'startTime': one_minute_ago_time,
'endTime': current_time
}
issue_response = requests.post(issue_list_url, headers=headers, data=json.dumps(body))
print(issue_response.text) # レスポンス内容を出力してデバッグに役立てる
if issue_response.status_code == 200:
issue_lists = issue_response.json()['content']
for issue in issue_lists:
issue_uuid = issue["uuid"]
print(f"Guance からの UUID: {issue_uuid}") # UUID を出力してデバッグ
issue_data = {
'project': {'key': project_key},
'summary': issue["name"],
'description': issue["description"],
'issuetype': {'name': 'バグ'},
'priority': {'name': 'Medium'},
'labels': [issue_uuid] # ラベルを使用して issue_id を保存
}
created_issue = jira_instance.create_issue(fields=issue_data)
print(f"JIRA の課題を作成しました: {created_issue.key}")
def create_issue_reply(issue_uuid, content):
headers = {
'DF-API-KEY': df_api_key,
'Content-Type': 'application/json;charset=UTF-8'
}
body = {
'issueUUID': issue_uuid,
'content': content,
'extend': {}
}
response = requests.post(create_issue_reply_url, headers=headers, data=json.dumps(body))
if response.status_code == 200:
print(f"issueUUID: {issue_uuid} の返信を作成しました。")
else:
print(f"issueUUID: {issue_uuid} の返信作成に失敗しました。ステータスコード: {response.status_code}")
def sync_comments_from_jira_to_guance():
end_time = datetime.now()
start_time = end_time - timedelta(minutes=1)
start_time_str = start_time.strftime('%Y-%m-%d %H:%M')
end_time_str = end_time.strftime('%Y-%m-%d %H:%M')
jql_str = f'project = {project_key} AND updated >= "{start_time_str}" AND updated <= "{end_time_str}"'
recently_updated_issues = jira_instance.search_issues(jql_str)
has_updates = False
for issue in recently_updated_issues:
comments = jira_instance.comments(issue)
new_comments = [comment for comment in comments if start_time_str <= comment.created.split('.')[0].replace("T", " ") <= end_time_str]
issue_labels = issue.fields.labels
guance_issue_id = None
for label in issue_labels:
if label.startswith("issue"):
guance_issue_id = label
break
if guance_issue_id and new_comments:
has_updates = True
for comment in new_comments:
create_issue_reply(guance_issue_id, comment.body)
if not has_updates:
print("過去1分間に更新された課題や新しいコメントはありません。")
@DFF.API('Create_JIRA_Issue_Reply2')
def guance():
print("開始します")
sync_issues_from_guance_to_jira()
sync_comments_from_jira_to_guance()
- スクリプトを公開する
公開 ボタンをクリックして公開を完了します。公開が完了すると、API が公開され、外部からサービスを利用できるようになります。
- 自動トリガー設定
自動トリガー設定 により、API を定期的に実行できます。
- 管理 メニューから 自動トリガー設定 ボタンをクリックします。
- 右上の 新規作成 ボタンをクリックして新規作成します。
- 実行するスクリプトを選択します。パラメータは指定しなくても構いません。実行頻度を選択し、ここでは 毎分繰り返す にチェックを入れ、保存 します。
issue の作成¶
Guance では、2 通りの方法で issue を作成できます。
- 直接作成
- モニターから作成
直接作成¶
- Guance コンソールにログインします。
- インシデント メニューをクリックし、右上の Issue を作成 ボタンをクリックして、issue 情報を入力し、保存します。
モニターから作成¶
モニターから作成 は、モニターが生成したイベント情報を基に issue を作成する方法です。
- Guance コンソールにログインします。
- 左側の モニター メニューをクリックします。
- 新しいモニターを作成するか、既存のモニターを編集します。該当のモニターを編集し、Issue を同時に作成 スイッチをオンにして、保存します。
動作イメージ¶
Jira での表示:¶
Jira の issue が自動生成され、コメントを入力すると、Guance 上で issue の処理過程が表示されます。
Guance での表示¶
Guance 上でも Jira の issue 処理過程が同期されます。



