diff --git a/.github/workflows/DockerBuildAndPush.yml b/.github/workflows/DockerBuildAndPush.yml new file mode 100644 index 0000000..2398f8b --- /dev/null +++ b/.github/workflows/DockerBuildAndPush.yml @@ -0,0 +1,38 @@ +name: DockerBuildAndPush + +on: + push: + branches: + - master + - docker + +jobs: + multi: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v3 + - + name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - + name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.CR_PAT }} + - + name: Build and push + uses: docker/build-push-action@v4 + with: + context: . + file: ./Dockerfile + platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x + push: true + tags: | + ghcr.io/ncareau/gpsd-prometheus-exporter:latest \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d62cbd8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +FROM python:alpine3.10 + +RUN pip install prometheus_client +RUN pip install gps + +WORKDIR /app + +COPY . /app + +ENV GEOPOINT_LON=38.897809878104574 +ENV GEOPOINT_LAT=-77.03655125936501 + + +CMD [ "./entrypoint.sh" ] + diff --git a/README.md b/README.md index 6507c80..41c3b38 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ It connects to the TCP port of the GPSD daemon and records relevant statistics a ![Graphana dashboard DOP](https://github.com/brendanbank/gpsd-prometheus-exporter/blob/ce8d05be537ec7fe935bad0c9479cf3e0770b41a/img/dop.png?raw=true) -## Instalation: +## Installation: Make sure gpsd, prometheus and grafana are properly running. `gpsd-prometheus-exporter`needs `python3` and the following python libraries: @@ -42,7 +42,7 @@ And enable the serivce to run at boot. Some U-Blox GPS units need to be forced to 115200 baud -Check out [gps_setserial.serivce](https://github.com/brendanbank/gpsd-prometheus-exporter/blob/master/gps_setserial.service) to run at boot time. +Check out [gps_setserial.service](https://github.com/brendanbank/gpsd-prometheus-exporter/blob/master/gps_setserial.service) to run at boot time. The default tcp port is 9015. You can test if the exporter is up by running the follwing command on the local machine: @@ -102,7 +102,7 @@ Be carefull not to break with the yml document format as it will block propper s I've included a [grafana dashboard json file](https://raw.githubusercontent.com/brendanbank/gpsd-prometheus-exporter/main/gpsd_grafana_dashboard.json) which you can load into grafana. -## Per Satilite data +## Per Satellite data ![](https://github.com/brendanbank/gpsd-prometheus-exporter/blob/ce8d05be537ec7fe935bad0c9479cf3e0770b41a/img/sats.png?raw=true) ## PPS @@ -116,7 +116,7 @@ the exporter will monitor the clock offset from from the pps signal. And you can To eable pps monitoring add `--pps-histogram` to the runtime arguments of `gpsd_exporter.py` -## Graph offset from a stationairy +## Graph offset from a stationary ![](https://github.com/brendanbank/gpsd-prometheus-exporter/blob/ce8d05be537ec7fe935bad0c9479cf3e0770b41a/img/geo_offset.png?raw=true) ## runtime commands @@ -165,9 +165,63 @@ To eable pps monitoring add `--pps-histogram` to the runtime arguments of `gpsd_ Bucket count of Geo histogram [default: 40] --pps-histogram generate histogram data from pps devices. --pps-bucket-size PPS_BUCKET_SIZE - Bucket side of PPS histogram [default: 250 ns] (nano seconds) + Bucket side of PPS histogram in nanoseconds. [default: 250 ns] --pps-bucket-count PPS_BUCKET_COUNT Bucket count of PPS histogram [default: 40] --pps-time1 PPS_TIME1 Local pps clock (offset) time1 (ntp.conf) [default: 0] +## Docker + +You can run this software with docker. + +### Docker Run + + docker run -d --name gpsd-exporter \ + -p 9015:9015 \ + -e GPSD_HOST=192.168.1.10 \ + -e GPSD_PORT=2947 \ + -e GEOPOINT_LON=38.897809878 \ + -e GEOPOINT_LAT=-77.036551259 \ + ghcr.io/ncareau/gpsd-prometheus-exporter:latest + +### Docker Compose + +An example `docker-compose.yml` is provided in the root directory of this project. + + gpsd-exporter: + image: ghcr.io/ncareau/gpsd-prometheus-exporter:latest + container_name: gpsd-exporter + ports: + - 9015:9015 + environment: + - GPSD_HOST=127.0.0.1 + - GPSD_PORT=2947 + - GEOPOINT_LON=38.897809878 + - GEOPOINT_LAT=-77.036551259 + restart: unless-stopped + +### GPSd on Host + +If the gpsd daemon run directly on the host, you must either use network_mode: host + + # Docker CLI + --network=host + + # Docker Compose + network_mode: host + +or by adding `host.docker.internal` to connect the host + + # Docker CLI - Remove "-p 9015:9015" + -e GPSD_HOST=host.docker.internal \ + --add-host=host.docker.internal:host-gateway \ + + + # Docker compose - Remove `ports:` + extra_hosts: + - "host.docker.internal:host-gateway" + + environment: + - GPSD_HOST=host.docker.internal + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..831fe87 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +version: "3" +services: + + gpsd-exporter: + image: ghcr.io/ncareau/gpsd-prometheus-exporter:latest + container_name: gpsd-exporter + ports: + - 9015:9015 + environment: + - GPSD_HOST=host.docker.internal + - GPSD_PORT=2947 + - GEOPOINT_LON=38.897809878 + - GEOPOINT_LAT=-77.036551259 + - PPS_BUCKET_SIZE=50000 + extra_hosts: + - "host.docker.internal:host-gateway" + restart: unless-stopped \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..24fb99f --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +EXPORTER_ARGS="" + +[[ -z "${DEBUG}" ]] || EXPORTER_ARGS="${EXPORTER_ARGS} -d" + +[[ -z "${GPSD_HOST}" ]] || EXPORTER_ARGS="${EXPORTER_ARGS} --hostname ${GPSD_HOST}" +[[ -z "${GPSD_PORT}" ]] || EXPORTER_ARGS="${EXPORTER_ARGS} --port ${GPSD_PORT}" +[[ -z "${EXPORTER_PORT}" ]] || EXPORTER_ARGS="${EXPORTER_ARGS} --exporter-port ${EXPORTER_PORT}" + +[[ -z "${GEOPOINT_LON}" ]] || EXPORTER_ARGS="${EXPORTER_ARGS} --geopoint-lon ${GEOPOINT_LON}" +[[ -z "${GEOPOINT_LAT}" ]] || EXPORTER_ARGS="${EXPORTER_ARGS} --geopoint-lat ${GEOPOINT_LAT}" + +[[ -z "${GEO_BUCKET_SIZE}" ]] || EXPORTER_ARGS="${EXPORTER_ARGS} --geo-bucket-size ${GEO_BUCKET_SIZE}" +[[ -z "${GEO_BUCKET_COUNT}" ]] || EXPORTER_ARGS="${EXPORTER_ARGS} --geo-bucket-count ${GEO_BUCKET_COUNT}" + +[[ -z "${PPS_BUCKET_SIZE}" ]] || EXPORTER_ARGS="${EXPORTER_ARGS} --pps-bucket-size ${PPS_BUCKET_SIZE}" +[[ -z "${PPS_BUCKET_COUNT}" ]] || EXPORTER_ARGS="${EXPORTER_ARGS} --pps-bucket-count ${PPS_BUCKET_COUNT}" + +echo ./gpsd_exporter.py -v --pps-histogram --offset-from-geopoint $EXPORTER_ARGS +./gpsd_exporter.py -v --pps-histogram --offset-from-geopoint $EXPORTER_ARGS + diff --git a/gpsd_exporter.py b/gpsd_exporter.py index bfbfa23..08dee6f 100755 --- a/gpsd_exporter.py +++ b/gpsd_exporter.py @@ -436,7 +436,7 @@ def drop_privileges(uid_name='nobody', gid_name='nogroup'): def loop_connection(metrics, args): - gpsd = gps.gps(host=args.hostname, verbose=1, mode=gps.WATCH_ENABLE | gps.WATCH_NEWSTYLE | gps.WATCH_SCALED) + gpsd = gps.gps(host=args.hostname, port=args.port, verbose=1, mode=gps.WATCH_ENABLE | gps.WATCH_NEWSTYLE | gps.WATCH_SCALED) drop_privileges() if not (gpsd):