{"id":15062612,"url":"https://github.com/opsdis/monitor-exporter","last_synced_at":"2025-07-18T01:14:32.950Z","repository":{"id":38038617,"uuid":"202750095","full_name":"opsdis/monitor-exporter","owner":"opsdis","description":"The monitor-exporter utilize OP5 Monitors API to fetch service based performance data and publish it in a way that lets prometheus scrape the performance data as metrics.","archived":false,"fork":false,"pushed_at":"2023-05-23T00:52:11.000Z","size":131,"stargazers_count":6,"open_issues_count":3,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-10T10:15:21.080Z","etag":null,"topics":["grafana","monitor-exporter","op5-monitor","prometheus"],"latest_commit_sha":null,"homepage":"https://www.opsdis.com","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/opsdis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-16T15:12:57.000Z","updated_at":"2024-01-23T08:20:18.000Z","dependencies_parsed_at":"2025-04-10T10:08:51.986Z","dependency_job_id":"558b1b31-f75b-4af1-a8f3-fb3108441b73","html_url":"https://github.com/opsdis/monitor-exporter","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/opsdis/monitor-exporter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opsdis%2Fmonitor-exporter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opsdis%2Fmonitor-exporter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opsdis%2Fmonitor-exporter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opsdis%2Fmonitor-exporter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/opsdis","download_url":"https://codeload.github.com/opsdis/monitor-exporter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opsdis%2Fmonitor-exporter/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265687128,"owners_count":23811219,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["grafana","monitor-exporter","op5-monitor","prometheus"],"created_at":"2024-09-24T23:43:33.896Z","updated_at":"2025-07-18T01:14:32.930Z","avatar_url":"https://github.com/opsdis.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![PyPI version](https://badge.fury.io/py/monitor-exporter.svg)](https://badge.fury.io/py/monitor-exporter)\n\nmonitor-exporter\n-----------------------\n\n- [Overview](#overview)\n- [Metrics naming](#metrics-naming)\n    * [Service performance data](#service-performance-data)\n    * [Host performance data](#host-performance-data)\n    * [State](#state)\n    * [Metric labels](#metric-labels)\n    * [Performance metrics name to labels](#performance-metrics-name-to-labels)\n- [Configuration](#configuration)\n    * [monitor-exporter](#monitor-exporter-1)\n- [Using Redis cache](#using-redis-cache)\n- [Logging](#logging)\n- [Prometheus configuration](#prometheus-configuration)\n    * [Static config](#static-config)\n    * [File discovery config for usage with `monitor-promdiscovery`](#file-discovery-config-for-usage-with--monitor-promdiscovery-)\n- [Installing](#installing)\n- [Running](#running)\n    * [Development with Quart built in webserver](#development-with-quart-built-in-webserver)\n    * [Production deployment](#production-deployment)\n        + [Deploying with gunicorn](#deploying-with-gunicorn)\n    * [Test the connection](#test-the-connection)\n- [System requirements](#system-requirements)\n- [License](#license)\n\n# Overview\n\nThe monitor-exporter utilises ITRS, former OP5, Monitor's API to fetch host and service-based performance data and\npublish it in a way that lets Prometheus scrape the performance data and state as metrics.\n\nBenefits:\n\n- Enable advanced queries and aggregation on time series\n- Prometheus based alerting rules\n- Grafana graphing\n- Take advantage of metrics already collected by Monitor, without rerunning checks\n- Collect hosts and services performance data and state and translate to Prometheus metrics\n\nThis solution is a perfect gateway for any Monitor users that would like to start using Prometheus and Grafana.\n\n# Metrics naming\n## Service performance data\nMetrics that are scraped with the monitor-exporter will have the following naming structure:\n\n    monitor_\u003ccheck_command\u003e_\u003cperfname\u003e_\u003cunit\u003e\n\n\u003e Unit is only added if it exists for the performance data\n\nFor example the check command `check_ping` will result in two metrics:\n\n    monitor_check_ping_rta_seconds\n    monitor_check_ping_pl_ratio\n\n## Host performance data\nIn Monitor the host also have a check to verify the state of the host. The metric name is always called `monitor_check_host_alive`.\nIf this check as multiple performance values they will be reported as individual metrics, e.g.\n\n```\nmonitor_check_host_alive_pkt{hostname=\"foo.com\", environment=\"production\", service=\"isalive\"} 1\nmonitor_check_host_alive_rta{hostname=\"foo.com\", environment=\"production\", service=\"isalive\"} 2.547\nmonitor_check_host_alive_pl_ratio{hostname=\"foo.com\", environment=\"production\", service=\"isalive\"} 0.0\n```\n\n\u003e Service label will always be `isalive`\n\n\n## State\nState metrics is reported for both hosts and services.\nState metrics is reported as value 0 (okay), 1 (warning), 2 (critical) and 4 (unknown).\n\nFor hosts the metric name is:\n\n    monitor_host_state\n\nFor services the metric name is:\n\n    monitor_service_state\n\n\n## Metric labels\nThe monitor-exporter adds a number of labels to each metric:\n\n- **hostname** - is the `host_name` in Monitor\n- **service** - is the `service_description` in Monitor\n- **downtime** - if the host or service is currently in a downtime period - true/false. If the host is in downtime its\n  services are also in downtime. **Attention, downtime is only support if monitor-export is running in cache mode.**\n- **address** - the hosts real address\n- **acknowledged** - is applicable if a host or service is in warning or critical and have been acknowledged by operations -\n  0/1 where 1 is acknowledged.\n\nOptionally the monitor-exporter can be configured to pass all or specific custom variables configured in Monitor as\nlabels Prometheus.\n\n\u003e Any host based custom variables that is used as labels is also set for its services.\n\n\u003e Labels created from custom variables are all transformed to lowercase.\n\n## Performance metrics name to labels\nAs described above, the default naming of the Prometheus name is:\n\n    monitor_\u003ccheck_command\u003e_\u003cperfname\u003e_\u003cunit\u003e\n\nFor some check commands this does not work well like for the `self_check_by_snmp_disk_usage_v3` check command where the\nperfname are the unique mount paths.\nFor checks where the perfname is defined depending on a specific name, you can change it so the perfname becomes a\nlabel instead.\nThis is defined in the configuration like:\n\n```yaml\n  perfnametolabel:\n    # The command name\n    self_check_by_snmp_disk_usage_v3:\n      # the label name to be used\n      label_name: disk\n    check_disk_local_mb:\n      label_name: local_disk\n```\nSo if the check command is `self_check_by_snmp_disk_usage_v3`, the Prometheus metrics will have a format like:\n\n    monitor_self_check_by_snmp_disk_usage_v3_bytes{hostname=\"monitor\", service=\"Disk usage /\", disk=\"/_used\"} 48356130816.0\n\nIf we did not make this transformation, we would get the following:\n\n    monitor_self_check_by_snmp_disk_usage_v3_slash_used_bytes{hostname=\"monitor\", service=\"Disk usage /\"} 48356130816.0\n\nWhich is bad since we get specific metric name from the perfname.\n\n\u003e Please be aware of naming conventions for perfname and services, especially when they include a name depending on\n\u003e what is checked like a mountpoint or disk name.\n\n\n# Configuration\n## monitor-exporter\nAll configuration is made in the `config.yml` file. Please see read thee file for all configuration options.  \n\n\u003e When running with gunicorn the port is defined by gunicorn\n\n# Using Redis cache\nIf you have a large Monitor configuration, the load of the Monitor server can get high when collecting host and service data over the api with a high rate.\nWe strongly recommend that you instead collect host and service data in a batch and store it in a redis cache.\nThe interval of the batch collecting is configurable, but considering that most service checks in Monitor are often done in 5 minutes interval,\ncollecting every minute should be more than enough.\n\nTo use caching just add this to your `config.yml`:\n```\ncache:\n  # Use redis for cache - future may support others\n  # Values below is the default\n  redis:\n    # redis host\n    host: localhost\n    # redis port\n    port: 6379\n    # the auth string used in redis\n    #auth: secretstuff\n    # the redis db to use\n    db: 0\n  # The interval to collect data from Monitor in secoends\n  interval: 60\n  # The time to live for the stored Monitor objects in the redis cache\n  ttl: 300\n```\n\u003e Redis must be installed on some host on the network and be accessible from the server running monitor-exporter\n\n# Logging\nThe log stream is configure in the above config. If `logfile` is not set the logs will go to stdout.\n\nLogs are formatted as json so it's easy to store logs in log servers like Loki and Elasticsearch.\n\n# Prometheus configuration\nPrometheus can be used with static configuration or with dynamic file discovery using the project\n[monitor-promdiscovery](https://bitbucket.org/opsdis/monitor-promdiscovery)\n\nPlease add the the job to the scrape_configs in prometheus.yml.\n\n\u003e The target is the `host_name` configured in Monitor.\n\n## Static config\n```yaml\n\nscrape_configs:\n  - job_name: 'op5monitor'\n    metrics_path: /metrics\n    static_configs:\n      - targets:\n          - monitor\n          - google.se\n    relabel_configs:\n      - source_labels: [__address__]\n        target_label: __param_target\n      - source_labels: [__param_target]\n        target_label: instance\n      - target_label: __address__\n        replacement: localhost:9631\n\n```\n\n## File discovery config for usage with `monitor-promdiscovery`\n\n```yaml\n\nscrape_configs:\n  - job_name: 'op5monitor'\n    scrape_interval: 1m\n    metrics_path: /metrics\n    file_sd_configs:\n      - files:\n          - 'sd/monitor_sd.yml'\n    relabel_configs:\n      - source_labels: [__address__]\n        target_label: __param_target\n      - source_labels: [__param_target]\n        target_label: instance\n      - target_label: __address__\n        replacement: localhost:9631\n\n```\n# Installing\n1. Clone the git repo.\n2. Install dependencies\n\n   `pip install -r requirements.txt`\n\n3. Build a distribution\n\n   `python setup.py sdist`\n\n4. Install locally\n\n   `pip install dist/monitor-exporter-X.Y.Z.tar.gz`\n\n\n# Running\n## Development with Quart built in webserver\n\n    python -m  monitor_exporter -f config.yml\n\nThe switch -p enable setting of the port.\n\n## Production deployment\nThere are a number of ASGI containers that can be can use to deploy *monitor-exporter*. The dependency for these are not\nincluded in the distribution.\n\n### Deploying with gunicorn\nFirst install the guincorn dependency into the python environment.\n\n    pip install gunicorn==20.1.0\n    pip install uvicorn==0.14.0\n\nRunning with the default config.yml. The default location is current directory.\n\n    gunicorn --access-logfile /dev/null -w 4 -k uvicorn.workers.UvicornWorker \"wsgi:create_app()\"\n\nSet the path to the configuration file.\n\n    gunicorn --access-logfile /dev/null -w 4 -k uvicorn.workers.UvicornWorker \"wsgi:create_app('/etc/monitor-exporter/config.yml')\"\n\n\u003e Port for gunicorn is default 8000, but can be set with -b, e.g. `-b localhost:9631`\n\n## Docker\nAlt 1: Edit the config.yml in repo:\n\n    docker run -p 9631:9631 monitor-exporter\n\nAlt 2: Have config in separate location\n\n    docker run -v /path/to/config:/monitor-exporter/config/ -p 9631:9631 monitor-exporter\n\n## Test the connection\n\nCheck if the exporter is working.\n\n    curl -s http://localhost:9631/health\n\nGet metrics for a host where `target` is a host using the same `host_name` in Monitor\n\n    curl -s http://localhost:9631/metrics?target=foo.com\n\n# System requirements\nPython 3.8\n\nFor required packages, please review `requirements.txt`\n\n# License\nThe monitor-exporter is licensed under GPL version 3.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopsdis%2Fmonitor-exporter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopsdis%2Fmonitor-exporter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopsdis%2Fmonitor-exporter/lists"}