This repository has been archived by the owner on Jun 14, 2019. It is now read-only.
forked from felixhummel/gitlab-prometheus-exporter
-
Notifications
You must be signed in to change notification settings - Fork 1
/
gitlab_exporter.py
executable file
·117 lines (96 loc) · 3.96 KB
/
gitlab_exporter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env python
# encoding: utf-8
import logging
import os
from datetime import datetime
import time
import gitlab
from prometheus_client import start_http_server, Summary, Gauge
try:
loglevel = getattr(logging, os.environ.get('LOGLEVEL', 'WARN').upper())
except AttributeError:
pass
logging.basicConfig()
log = logging.getLogger(__name__)
log.setLevel(level=loglevel)
# time to sleep between calls to gitlab
INTERVAL = int(os.environ.get('INTERVAL', 300))
# port to listen on
PORT = int(os.environ.get('PORT', 3001))
# URL of the GitLab instance, defaults to hosted GitLab
URL = str(os.environ.get('URL', 'https://gitlab.com'))
# Secret token for the app to authenticate itself
TOKEN = str(os.environ.get('TOKEN'))
# Login to GitLab
gl = gitlab.Gitlab(URL, TOKEN)
gl.auth()
# Initialize Prometheus instrumentation
projects_total = Gauge('gitlab_projects_total', 'Number of projects')
builds_total = Gauge('gitlab_builds_total', 'Number of builds', ['project_id', 'project_name'])
build_duration_seconds = Summary('gitlab_build_duration_seconds', 'Seconds the build took to run', ['project_id', 'project_name', 'stage', 'status', 'ref'])
open_issues_total = Gauge('gitlab_open_issues_total', 'Number of open issues', ['project_id', 'project_name'])
pipeline_duration_seconds = Summary('gitlab_pipeline_duration_seconds', 'Seconds the pipeline took to run', ['project_id', 'project_name', 'status', 'ref'])
def get_projects():
try:
projects = gl.projects.list(all=True)
log.debug("Projects: {}".format(projects))
return projects
except gitlab.exceptions.GitlabListError:
log.warn("Projects could not be retrieved")
return []
def get_builds(project):
try:
builds = project.builds.list(all=True)
log.debug("Builds: {}".format(builds))
return builds
except gitlab.exceptions.GitlabListError:
log.warn("Builds could not be retrieved")
return []
def get_duration(process):
try:
start = datetime.strptime(process.started_at, "%Y-%m-%dT%H:%M:%S.%fZ")
end = datetime.strptime(process.finished_at, "%Y-%m-%dT%H:%M:%S.%fZ")
duration = end - start
return duration
except TypeError:
return 0
def get_pipelines(project):
try:
pipelines = project.pipelines.list(all=True)
log.debug("Pipelines: {}".format(pipelines))
return pipelines
except gitlab.exceptions.GitlabListError:
log.warn("Pipelines could not be retrieved")
return []
def get_stats():
projects = get_projects()
projects_total.set(len(projects))
for project in projects:
project = gl.projects.get(project.id)
log.debug("Project: {}".format(project))
builds_total.labels(project_id=project.id, project_name=project.name).set(len(project.builds.list()))
open_issues_total.labels(project_id=project.id, project_name=project.name).set(project.open_issues_count)
for pipeline in get_pipelines(project):
try:
duration = get_duration(pipeline)
summary = pipeline_duration_seconds.labels(project_id=project.id, project_name=project.name, status=pipeline.status, ref=pipeline.ref)
summary.observe(duration.total_seconds())
except AttributeError:
pass
for build in get_builds(project):
try:
duration = get_duration(build)
summary = build_duration_seconds.labels(project_id=project.id, project_name=project.name, stage=build.stage, status=build.status, ref=pipeline.ref)
summary.observe(duration.total_seconds())
except AttributeError:
pass
if __name__ == '__main__':
start_http_server(PORT)
log.info('listening on port {0}'.format(PORT))
while True:
try:
get_stats()
log.info('sleeping for {0} seconds'.format(INTERVAL))
time.sleep(INTERVAL)
except KeyboardInterrupt:
break