You've already forked gitea_exporter
mirror of
https://github.com/Lunik/gitea_prometheus_exporter.git
synced 2025-07-31 19:24:22 +03:00
init
This commit is contained in:
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
venv/
|
||||||
|
|
||||||
|
config.yml
|
||||||
|
|
||||||
|
__pycache__/
|
||||||
|
|
||||||
|
*.pyc
|
26
Dockerfile
Normal file
26
Dockerfile
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
FROM python:alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
|
||||||
|
RUN pip3 install -r requirements.txt
|
||||||
|
|
||||||
|
######### FIX #########
|
||||||
|
|
||||||
|
COPY patch/py-gitea_user-get-orgs.diff /tmp/py-gitea_user-get-orgs.diff
|
||||||
|
|
||||||
|
RUN apk add -u --no-cache --virtual build-utils patch \
|
||||||
|
&& unix2dos /tmp/py-gitea_user-get-orgs.diff \
|
||||||
|
&& patch --binary -u /usr/local/lib/python3.9/site-packages/gitea/gitea.py -i /tmp/py-gitea_user-get-orgs.diff \
|
||||||
|
&& apk del build-utils
|
||||||
|
|
||||||
|
######### FIX #########
|
||||||
|
|
||||||
|
COPY api api
|
||||||
|
COPY prometheus-exporter.py .
|
||||||
|
COPY config.yml.exemple config.yml
|
||||||
|
|
||||||
|
EXPOSE 9100
|
||||||
|
|
||||||
|
CMD ["python3", "prometheus-exporter.py"]
|
1
api/__init__.py
Normal file
1
api/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from api.app import App
|
34
api/app.py
Normal file
34
api/app.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import yaml
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import threading
|
||||||
|
|
||||||
|
from prometheus_client import start_http_server
|
||||||
|
|
||||||
|
from api.gitea import module as GiteaModule
|
||||||
|
|
||||||
|
|
||||||
|
class App:
|
||||||
|
def __init__(self, config_file=""):
|
||||||
|
self.cache = dict()
|
||||||
|
|
||||||
|
if config_file is not None and config_file != "":
|
||||||
|
self.config = self._parseConfig(config_file)
|
||||||
|
|
||||||
|
def _parseConfig(self, config_file):
|
||||||
|
with open(config_file, 'r') as file:
|
||||||
|
config = yaml.full_load(file)
|
||||||
|
|
||||||
|
if config is None:
|
||||||
|
raise Exception("Config file is empty: {}".format(config_file))
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
start_http_server(int(self.config['LISTEN_PORT']), self.config['LISTEN_HOST'])
|
||||||
|
print("Prometheus exporter started.")
|
||||||
|
|
||||||
|
threading.Thread(target=GiteaModule, args=(self,)).start()
|
84
api/gitea/__init__.py
Normal file
84
api/gitea/__init__.py
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import time
|
||||||
|
from prometheus_client import Gauge
|
||||||
|
|
||||||
|
from api.gitea.gitea import *
|
||||||
|
|
||||||
|
|
||||||
|
MODULE_NAME = "gitea"
|
||||||
|
|
||||||
|
GAUGES = {
|
||||||
|
"user": Gauge("{}_extra_user".format(MODULE_NAME), "Gitea user", ['username', 'full_name']),
|
||||||
|
"org": Gauge("{}_extra_org".format(MODULE_NAME), "Gitea org", ['username', 'full_name', 'visibility']),
|
||||||
|
"repo": Gauge("{}_extra_repo".format(MODULE_NAME), "Gitea repo", ['name', 'owner']),
|
||||||
|
"repo_size": Gauge("{}_extra_repo_size".format(MODULE_NAME), "Gitea repo size", ['name', 'owner', 'unit']),
|
||||||
|
"repo_empty": Gauge("{}_extra_repo_empty".format(MODULE_NAME), "Gitea repo empty", ['name', 'owner']),
|
||||||
|
"repo_archived": Gauge("{}_extra_repo_archived".format(MODULE_NAME), "Gitea repo archived", ['name', 'owner']),
|
||||||
|
"repo_stars": Gauge("{}_extra_repo_stars".format(MODULE_NAME), "Gitea repo stars", ['name', 'owner']),
|
||||||
|
"repo_commits": Gauge("{}_extra_repo_commits".format(MODULE_NAME), "Gitea repo commits", ['name', 'owner']),
|
||||||
|
"repo_branches": Gauge("{}_extra_repo_branches".format(MODULE_NAME), "Gitea repo branches", ['name', 'owner']),
|
||||||
|
"repo_forks": Gauge("{}_extra_repo_forks".format(MODULE_NAME), "Gitea repo forks", ['name', 'owner']),
|
||||||
|
"repo_issues": Gauge("{}_extra_repo_issues".format(MODULE_NAME), "Gitea repo issues", ['name', 'owner']),
|
||||||
|
"repo_pull_requests": Gauge("{}_extra_repo_pull_requests".format(MODULE_NAME), "Gitea repo pull_requests", ['name', 'owner'])
|
||||||
|
}
|
||||||
|
|
||||||
|
def module(app):
|
||||||
|
try:
|
||||||
|
interval = int(app.config['MODULE_CONFIG']['interval'])
|
||||||
|
except:
|
||||||
|
interval = 60
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
gitea_metrics = gitea_export(app)
|
||||||
|
|
||||||
|
GAUGES['user']._metrics.clear()
|
||||||
|
for user in gitea_metrics['users']:
|
||||||
|
GAUGES['user'].labels(username=user.username, full_name=user.full_name).set(1)
|
||||||
|
|
||||||
|
GAUGES['org']._metrics.clear()
|
||||||
|
for org in gitea_metrics['orgs']:
|
||||||
|
GAUGES['org'].labels(username=org.username, full_name=org.full_name, visibility=org.visibility).set(1)
|
||||||
|
|
||||||
|
GAUGES['repo']._metrics.clear()
|
||||||
|
GAUGES['repo_size']._metrics.clear()
|
||||||
|
GAUGES['repo_empty']._metrics.clear()
|
||||||
|
GAUGES['repo_archived']._metrics.clear()
|
||||||
|
GAUGES['repo_stars']._metrics.clear()
|
||||||
|
GAUGES['repo_commits']._metrics.clear()
|
||||||
|
GAUGES['repo_branches']._metrics.clear()
|
||||||
|
GAUGES['repo_forks']._metrics.clear()
|
||||||
|
GAUGES['repo_issues']._metrics.clear()
|
||||||
|
for repo in gitea_metrics['repos']:
|
||||||
|
GAUGES['repo'].labels(name=repo.name, owner=repo.owner.username).set(1)
|
||||||
|
GAUGES['repo_size'].labels(name=repo.name, owner=repo.owner.username, unit="bytes").set(repo.size)
|
||||||
|
|
||||||
|
if repo.empty:
|
||||||
|
GAUGES['repo_empty'].labels(name=repo.name, owner=repo.owner.username).set(1)
|
||||||
|
|
||||||
|
if repo.archived:
|
||||||
|
GAUGES['repo_archived'].labels(name=repo.name, owner=repo.owner.username).set(1)
|
||||||
|
|
||||||
|
if repo.stars_count > 0:
|
||||||
|
GAUGES['repo_stars'].labels(name=repo.name, owner=repo.owner.username).set(repo.stars_count)
|
||||||
|
|
||||||
|
if repo.commits_count > 0:
|
||||||
|
GAUGES['repo_commits'].labels(name=repo.name, owner=repo.owner.username).set(repo.commits_count)
|
||||||
|
|
||||||
|
if repo.branches_count > 0:
|
||||||
|
GAUGES['repo_branches'].labels(name=repo.name, owner=repo.owner.username).set(repo.branches_count)
|
||||||
|
|
||||||
|
if repo.forks_count > 0:
|
||||||
|
GAUGES['repo_forks'].labels(name=repo.name, owner=repo.owner.username).set(repo.forks_count)
|
||||||
|
|
||||||
|
if repo.open_issues_count > 0:
|
||||||
|
GAUGES['repo_issues'].labels(name=repo.name, owner=repo.owner.username).set(repo.open_issues_count)
|
||||||
|
|
||||||
|
if repo.open_pr_counter > 0:
|
||||||
|
GAUGES['repo_pull_requests'].labels(name=repo.name, owner=repo.owner.username).set(repo.open_pr_counter)
|
||||||
|
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
print("[WARNING] Unable to retrieve 'Gitea' metrics.")
|
||||||
|
|
||||||
|
time.sleep(interval)
|
59
api/gitea/gitea.py
Normal file
59
api/gitea/gitea.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
from gitea import *
|
||||||
|
|
||||||
|
def get_repo_commit_count(gitea, repo):
|
||||||
|
page_endpoint = Repository.REPO_COMMITS % (repo.owner.username, repo.name)
|
||||||
|
|
||||||
|
response = gitea.requests.get(gitea.url + "/api/v1" + page_endpoint + "?limit=1", headers=gitea.headers, params={})
|
||||||
|
|
||||||
|
return int(response.headers.get('X-Total'))
|
||||||
|
|
||||||
|
def gitea_export(app):
|
||||||
|
metrics = dict()
|
||||||
|
|
||||||
|
try:
|
||||||
|
gitea = Gitea(app.config['MODULE_CONFIG']['url'], app.config['MODULE_CONFIG']['auth']['token'])
|
||||||
|
gitea.get_version()
|
||||||
|
except Exception as e:
|
||||||
|
print("[WARNING] Unable to initiate connection with gitea.")
|
||||||
|
return metrics
|
||||||
|
|
||||||
|
try:
|
||||||
|
metrics['users'] = gitea.get_users()
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
print("[WARNING] Unable to retrieve 'Gitea Users'.")
|
||||||
|
metrics['users'] = dict()
|
||||||
|
|
||||||
|
try:
|
||||||
|
metrics['orgs'] = gitea.get_orgs()
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
print("[WARNING] Unable to retrieve 'Gitea Users'.")
|
||||||
|
metrics['orgs'] = dict()
|
||||||
|
|
||||||
|
|
||||||
|
metrics['repos'] = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
for user in metrics['users']:
|
||||||
|
metrics['repos'] += user.get_repositories()
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
print("[WARNING] Unable to retrieve 'Gitea Users repos'.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
for org in metrics['orgs']:
|
||||||
|
metrics['repos'] += org.get_repositories()
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
print("[WARNING] Unable to retrieve 'Gitea Orgs repos'.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
for repo in metrics['repos']:
|
||||||
|
repo.branches_count = len(repo.get_branches()) if not repo.empty else 0
|
||||||
|
repo.commits_count = get_repo_commit_count(gitea, repo) if not repo.empty else 0
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
print("[WARNING] Unable to retrieve 'Gitea repos git infos'.")
|
||||||
|
|
||||||
|
return metrics
|
12
config.yml.exemple
Normal file
12
config.yml.exemple
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
ENV: production
|
||||||
|
DEBUG: false
|
||||||
|
|
||||||
|
LISTEN_PORT: 9100
|
||||||
|
LISTEN_HOST: "0.0.0.0"
|
||||||
|
|
||||||
|
MODULE_CONFIG:
|
||||||
|
url: https://git.wabbit
|
||||||
|
auth:
|
||||||
|
token: sometoken
|
11
patch/py-gitea_user-get-orgs.diff
Normal file
11
patch/py-gitea_user-get-orgs.diff
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
--- /usr/local/lib/python3.9/site-packages/gitea/gitea.py
|
||||||
|
+++ /usr/local/lib/python3.9/site-packages/gitea/gitea.py
|
||||||
|
@@ -159,7 +159,7 @@
|
||||||
|
results = self.gitea.requests_get(url)
|
||||||
|
return [Repository.parse_response(self.gitea, result) for result in results]
|
||||||
|
|
||||||
|
- def get_repositories(self) -> List[Organization]:
|
||||||
|
+ def get_orgs(self) -> List[Organization]:
|
||||||
|
""" Get all Organizations this user is a member of."""
|
||||||
|
url = f"/users/{self.username}/orgs"
|
||||||
|
results = self.gitea.requests_get(url)
|
18
prometheus-exporter.py
Normal file
18
prometheus-exporter.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from api import App
|
||||||
|
|
||||||
|
|
||||||
|
def setup():
|
||||||
|
app = App(config_file=os.path.join(os.getcwd(), 'config.yml'))
|
||||||
|
|
||||||
|
app.setup()
|
||||||
|
|
||||||
|
return app
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app = setup()
|
||||||
|
|
||||||
|
app.start()
|
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
prometheus_client
|
||||||
|
PyYaml
|
||||||
|
py-gitea
|
Reference in New Issue
Block a user