Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deploy gitter bot to write annotations to Grafana #425

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion chartpress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ charts:
imagePrefix: gcr.io/binder-prod/mybinder-tool-
images:
events-archiver:
valuesPath: eventsArchiver.image
valuesPath: eventsArchiver.image
gitter-grafana-logger:
valuesPath: gitterGrafanaLogger.image
5 changes: 5 additions & 0 deletions config/staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,8 @@ matomo:
eventsArchiver:
sourceBucket: mybinder-staging-events-raw-export
destinationBucket: mybinder-staging-events-archive


gitterGrafanaLogger:
# Only run one copy of logger bot
enabled: false
5 changes: 5 additions & 0 deletions images/gitter-grafana-logger/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM python:3.7-stretch

ADD . /srv

CMD ["python3", "/srv/event-archiver.py"]
82 changes: 82 additions & 0 deletions images/gitter-grafana-logger/bot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/env python3
import argparse
import json
import os
import time
import aiohttp
import asyncio


async def create_annotation(session, grafana_url, grafana_api_key, text):
"""
Create annotation in a grafana instance.
"""
tags = ['ops-log']
async with session.post(
grafana_url + "/api/annotations",
json={
'tags': tags,
'text': text,
'time': int(time.time() * 1000),
'isRegion': False
},
headers={
'Authorization': f'Bearer {grafana_api_key}'
}
) as resp:
return await resp.text()


async def stream_chat(session, gitter_room_id, grafana_url, GITTER_KEY, GRAFANA_KEY):
gitter_stream_url = f'https://stream.gitter.im/v1/rooms/{gitter_room_id}/chatMessages'

print(f'Started connection to Gitter Room {gitter_room_id}')
async with session.get(
gitter_stream_url,
headers={'Authorization': f'Bearer {GITTER_KEY}'}
) as response:
async for line in response.content:
# filter out empty lines
if line:
decoded_line = line.decode('utf-8')

try:
msg = json.loads(decoded_line)
except json.decoder.JSONDecodeError:
continue

text = msg['text'].strip()
if text.startswith("!log"):
name = msg['fromUser']['username']
print(f"Received {name}: {text}")
await create_annotation(session, grafana_url, GRAFANA_KEY, f"{name}: {text}")
print(f"Annotation created for {name}: {text}")


async def main():
argparser = argparse.ArgumentParser()
argparser.add_argument(
'--grafana-url',
help='URL of the grafana instance to use',
default='https://grafana.mybinder.org'
)
argparser.add_argument(
'--gitter-room-id',
help='IDs of rooms to watch',
action='append'
)
args = argparser.parse_args()

GRAFANA_KEY = os.environ['GRAFANA_API_KEY']
GITTER_KEY = os.environ['GITTER_API_KEY']

async with aiohttp.ClientSession() as session:
await asyncio.gather(*[
asyncio.ensure_future(stream_chat(session, room_id, args.grafana_url, GITTER_KEY, GRAFANA_KEY))
for room_id in args.gitter_room_id
])


if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
1 change: 1 addition & 0 deletions images/gitter-grafana-logger/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
aiohttp==3.4.4
40 changes: 40 additions & 0 deletions mybinder/templates/gitter-grafana-logger/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{{ if .Values.gitterGrafanaLogger.enabled }}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: gitter-grafana-logger
labels:
app: gitter-grafana-logger
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: gitter-grafana-logger
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
template:
metadata:
labels:
app: gitter-grafana-logger
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
volumes:
- name: gitter-grafana-logger
image: {{ .Values.gitterGrafanaLogger.image.name}}:{{ .Values.gitterGrafanaLogger.image.tag }}
env:
- name: PROJECT_NAME
value: {{ .Values.projectName }}
- name: SOURCE_BUCKET
value: {{ .Values.eventsArchiver.sourceBucket | quote }}
- name: DESTINATION_BUCKET
value: {{ .Values.eventsArchiver.destinationBucket | quote }}
volumeMounts:
- name: secrets
mountPath: /secrets
readOnly: true
{{ endif }}
11 changes: 11 additions & 0 deletions mybinder/templates/gitter-grafana-logger/secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: events-archiver-secrets
labels:
app: events-archiver
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
type: Opaque
data:
service-account.json: {{ .Values.eventsArchiver.serviceAccountKey | b64enc | quote }}
6 changes: 6 additions & 0 deletions mybinder/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -292,3 +292,9 @@ eventsArchiver:
image:
name: jupyterhub/mybinder-extraevents-archiver
tag: set-by-chartpress

gitterGrafanaLogger:
enabled: true
image:
name: set-by-chartpress
tag: set-by-chartpress
Binary file added secrets/bot-accounts.yaml
Binary file not shown.
Binary file modified secrets/config/prod.yaml
Binary file not shown.
Binary file modified secrets/config/staging.yaml
Binary file not shown.