From a665addad5fec42919a62031ffc4606556a2d70a Mon Sep 17 00:00:00 2001 From: Phillipe Smith Date: Wed, 4 Nov 2020 01:53:31 -0300 Subject: [PATCH] Fix issues #2, #3 and #4 --- Dockerfile | 21 +++++++++++++++++---- Makefile | 35 +++++++++++++++++++++++++++++++++++ README.md | 11 +++++++++++ rundeck_exporter.py | 40 ++++++++++++++++++++++++++++++++++------ 4 files changed, 97 insertions(+), 10 deletions(-) create mode 100644 Makefile diff --git a/Dockerfile b/Dockerfile index 3d67a52..a71f677 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,23 @@ FROM python:alpine -LABEL version="1.2.0" \ - description="Rundeck metrics exporter to Prometheus" \ - maintainer="Phillipe Smith " +ARG BUILD_DATE +ARG VCS_REF +ARG VERSION -RUN pip install prometheus-client requests cachetools +LABEL maintainer="Phillipe Smith " \ + org.label-schema.build-date=$BUILD_DATE \ + org.label-schema.name="Rundeck Exporter" \ + org.label-schema.description="Rundeck metrics exporter for Prometheus" \ + org.label-schema.url="https://hub.docker.com/r/phsmith/rundeck-exporter" \ + org.label-schema.vcs-ref=$VCS_REF \ + org.label-schema.vcs-url="https://github.com/phsmith/rundeck_exporter" \ + org.label-schema.version=$VERSION \ + org.label-schema.schema-version="1.0" + +RUN pip install --no-cache-dir \ + cachetools==4.1.1 \ + prometheus-client==0.8.0 \ + requests==2.24.0 COPY rundeck_exporter.py /usr/bin diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..751eb07 --- /dev/null +++ b/Makefile @@ -0,0 +1,35 @@ +PROJECT_NAME = $(notdir $(PWD)) + +.SILENT: push + +default: build + +build: + docker run --rm -i hadolint/hadolint:latest < Dockerfile + + docker build \ + --rm \ + --network host \ + --tag="$(PROJECT_NAME):$(VERSION)" \ + --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \ + --build-arg VCS_REF=`git rev-parse --short HEAD` \ + --build-arg VERSION="$(VERSION)" . + +clean: + docker rmi --force $(PROJECT_NAME):$(VERSION) + +push: + [ -z "$(git status --short --untracked-files=no)" ] && (echo -e "\nNeed to commit changes before push.\n"; exit 1) + git tag -d latest + git tag latest + git push origin :latest + git tag "v$(VERSION)" + git push --all + +debug: + docker run --rm -it $(PROJECT_NAME):$(VERSION) /bin/sh + +run: + docker run --rm $(PROJECT_NAME):$(VERSION) \ + --host 0.0.0.0 \ + --rundeck.skip_ssl diff --git a/README.md b/README.md index 6d2b431..2be3929 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,9 @@ rundeck_services_ExecutionService_executionSuccessMeter_total 268.0 # HELP rundeck_api_requests_requestTimer_total Rundeck timers metrics # TYPE rundeck_api_requests_requestTimer_total counter rundeck_api_requests_requestTimer_total 39419.0 +# HELP rundeck_project_execution_status Rundeck Project servcom_install Execution Duration +# TYPE rundeck_project_execution_duration_seconds gauge +rundeck_project_execution_duration_seconds{job_id="servcom_install",job_name="Servcom Client",project_name="servcom_install"} 6000.0 # HELP rundeck_project_execution_status Rundeck Project servcom_install Execution Status # TYPE rundeck_project_execution_status gauge rundeck_project_execution_status{job_id="servcom_install",job_name="Servcom Client",project_name="servcom_install",status="succeeded"} 1.0 @@ -175,6 +178,9 @@ rundeck_project_execution_status{job_id="servcom_install",job_name="Servcom Clie # HELP rundeck_project_execution_status Rundeck Project servcom_install Execution Status # TYPE rundeck_project_execution_status gauge rundeck_project_execution_status{job_id="servcom_install",job_name="Servcom Client",project_name="servcom_install",status="unknown"} 0.0 +# HELP rundeck_project_execution_status Rundeck Project oracle_client_install Execution Druation +# TYPE rundeck_project_execution_duration_seconds gauge +rundeck_project_execution_duration_seconds{job_id="oracle_client_install",job_name="Oracle Client Install",project_name="oracle_client_install"} 20000.0 # HELP rundeck_project_execution_status Rundeck Project oracle_client_install Execution Status # TYPE rundeck_project_execution_status gauge rundeck_project_execution_status{job_id="oracle_client_install",job_name="Oracle Client Install",project_name="oracle_client_install",status="succeeded"} 1.0 @@ -239,3 +245,8 @@ docker run --rm -d -p 9620:9620 -e RUNDECK_TOKEN=$RUNDECK_TOKEN rundeck_exporter * Remove param --rundeck.projects.executions.limit * Remove rundeck_node label from all metrics * Change rundeck_project_executions_info metrics to rundeck_project_status{job_id=...,job_name=...,project_name=...,status=....} + +`v2.1.0`: +* Fix issue Long Running Jobs #2 - Add metric rundeck_project_execution_duration_seconds +* Fix issue Project executions metrics not show all jobs info #4 +* Add pull request fix order labels and values the same way in execution metrics #3 diff --git a/rundeck_exporter.py b/rundeck_exporter.py index 1a31c22..6fb121c 100755 --- a/rundeck_exporter.py +++ b/rundeck_exporter.py @@ -132,12 +132,12 @@ def cached_request_data_from(self, endpoint: str) -> dict: Method to get Rundeck projects executions info """ def get_project_executions(self, project: dict): - counter_name = 'rundeck_project_execution_status' project_name = project['name'] project_executions = None project_executions_status = list() + jobs_list = list() metrics = None - endpoint = f'/project/{project_name}/executions?max=1' + endpoint = f'/project/{project_name}/executions?recentFilter=1d' try: if self.args.rundeck_projects_executions_cache: @@ -146,9 +146,37 @@ def get_project_executions(self, project: dict): project_executions = self.request_data_from(endpoint) for project_execution in project_executions['executions']: - if not project_executions: + job_info = project_execution.get('job', {}) + job_id = job_info.get('id', 'None') + job_name = job_info.get('name', 'None') + + if not project_executions or job_id in jobs_list: continue + jobs_list.append(job_id) + + # Job start/end times + job_start_time = project_execution.get('date-started', {}).get('unixtime', 0) + job_end_time = project_execution.get('date-ended', {}).get('unixtime', 0) + job_execution_duration = (job_end_time - job_start_time) + + duration_metrics = GaugeMetricFamily( + 'rundeck_project_execution_duration_seconds', + f'Rundeck Project {project_name} Execution Duration', + labels=['project_name', 'job_id', 'job_name'] + ) + + duration_metrics.add_metric( + [ + project_name, + job_id, + job_name + ], + job_execution_duration + ) + + project_executions_status.append(duration_metrics) + for status in ['succeeded', 'running', 'failed', 'aborted', 'unknown']: value = 0 @@ -156,7 +184,7 @@ def get_project_executions(self, project: dict): value = 1 metrics = GaugeMetricFamily( - counter_name, + 'rundeck_project_execution_status', f'Rundeck Project {project_name} Execution Status', labels=['project_name', 'job_id', 'job_name', 'status'] ) @@ -164,8 +192,8 @@ def get_project_executions(self, project: dict): metrics.add_metric( [ project_name, - project_execution.get('job', {}).get('id', 'None'), - project_execution.get('job', {}).get('name', 'None'), + job_id, + job_name, status ], value