Skip to content

Commit

Permalink
feat: gauge for uptime and login on startup
Browse files Browse the repository at this point in the history
  • Loading branch information
gilmrt committed Jan 25, 2024
1 parent f765df7 commit b063909
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 28 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ jobs:
steps:

- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3

- name: Build and export to Docker
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
Expand Down Expand Up @@ -68,7 +68,7 @@ jobs:
severity: "CRITICAL,HIGH"

- name: Upload Trivy scan results to GitHub Security
uses: github/codeql-action/upload-sarif@v2
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: 'trivy-results.sarif'
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ jobs:
steps:

- name: Checkout out
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Lint Code Base
uses: github/super-linter/slim@v4
uses: github/super-linter/slim@v5
env:
DEFAULT_BRANCH: main
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -38,12 +38,12 @@ jobs:
steps:

- name: Checkout out
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: "lts/*"

Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,29 @@ jobs:
steps:

- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3

- name: Log in to the Container registry
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v4
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

- name: Build and push
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ jobs:
steps:

- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: "lts/*"

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.12.0-alpine3.18
FROM python:3.12.1-alpine3.19

WORKDIR /app

Expand Down
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Access the webui at `http://<your-ip>:9922`.

## Usage

> You need to authenticate with an administrator account in order to get permissions needed for SRM API.
### docker-compose

```yaml
Expand All @@ -38,7 +40,7 @@ services:
- SRM_PORT=8001
- SRM_USERNAME=admin
- SRM_PASSWORD=password
- PERIODS=live,day,week,month
- PERIODS=live
- USE_HTTPS=True
- DISABLE_HTTPS_VERIFY=False
- EXPORTER_CACHE_FOR=0
Expand All @@ -57,7 +59,7 @@ docker run -d \
-e SRM_PORT=8001 \
-e SRM_USERNAME=admin \
-e SRM_PASSWORD=password \
-e PERIODS=live,day,week,month \
-e PERIODS=live \
-e USE_HTTPS=True \
-e DISABLE_HTTPS_VERIFY=False \
-e EXPORTER_CACHE_FOR=0 \
Expand Down Expand Up @@ -118,6 +120,7 @@ Real example where the tests will be done every 30s:
| srm_device_transferRXRate | SRM device RX transfert rate | `mac`, `hostname` |
| srm_device_transferTXRate | SRM device TX transfert rate | `mac`, `hostname` |
| srm_system_load | SRM System current load | |
| srm_system_up_time | SRM System up time | `hostname` |
| srm_disk_total_utilization | SRM Disk utilization total | |
| srm_memory_size | SRM System memory size on KB | |
| srm_avail_real | SRM System real memory availible | |
Expand All @@ -137,8 +140,19 @@ Under construction

## Known Issues

### Periods

Periods `month` seems not working on RT2600AC (see [comment](https://github.com/gilmrt/srm-exporter/issues/6#issuecomment-1789226784))

### Login failed / Permissions denied

Permissions needed for the API are only available for administrator accounts.

In SRM Control Panel > User, you may notice that an administrator account has a **little gold medal with a red ribbon** on the user icon (as does the default administrator account) which means that the account is part of the administrator group.
If you're not using this primary default admin account, follow steps [here](https://kb.synology.com/en-id/SRM/tutorial/Create_multiple_administrator_accounts_on_Synology_Router) or [here](https://community.synology.com/enu/forum/2/post/127805) to create a new one with admin permissions.

Another point concerns multi-factor authentication: even if you've disabled two-factor authentication, you still need to click on the administrator account and click on reset multi-factor authentication to disable it for a use that had already enabled it.

## Versioning

This library is maintained under the [semantic versioning](https://semver.org/) guidelines.
Expand Down
31 changes: 22 additions & 9 deletions src/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,9 @@
"ntp_server",
"ram_size",
"serial",
"up_time",
],
)
srm_system_up_time = Gauge("srm_system_up_time", "SRM System current up time", ["host"])

srm_system_load = Gauge("srm_system_load", "SRM System current load", ["host"])
srm_disk_total_utilization = Gauge(
Expand Down Expand Up @@ -178,6 +178,17 @@ def stringToBool(string: str) -> bool:
return False


def stringToSecond(timestr: str) -> float:
"""Get seconds from time.
:param timestr: hh:mm:ss.xxx string or mm:s.xxx or simply s.xxx where xxx is the fraction of seconds
:returns: time in float seconds
"""
seconds = 0.0
for part in timestr.split(":"):
seconds = seconds * 60.0 + float(part)
return seconds


def bytes_to_bits(bytes_per_sec):
return bytes_per_sec * 8

Expand Down Expand Up @@ -250,7 +261,6 @@ def get_system_info(client):


def get_srm_devices(client):

# Get devices connections
network_nsm_device = client.core.get_network_nsm_device()

Expand All @@ -260,7 +270,6 @@ def get_srm_devices(client):
device_connections = []

for device in network_nsm_device:

# Translate Mac address to hostname
mac_to_hostname[device["mac"].lower()] = device["hostname"]
if device["hostname"] == "":
Expand Down Expand Up @@ -404,11 +413,7 @@ def get_traffic_stats(client, mac_to_hostname, mac_to_ip_addr, period="day"):
@app.route("/metrics")
def updateResults():
global cache_until

if datetime.datetime.now() > cache_until:
# SRM Authentication
client = srm_auth()

# SRM system info
system_infos = get_system_info(client)
for info in system_infos:
Expand All @@ -425,8 +430,8 @@ def updateResults():
ntp_server=info["ntp_server"],
ram_size=info["ram_size"],
serial=info["serial"],
up_time=info["up_time"],
).set(1)
srm_system_up_time.labels(host=HOST).set(stringToSecond(info["up_time"]))

# SRM device connections type
device_connections, mac_to_hostname, mac_to_ip_addr = get_srm_devices(client)
Expand Down Expand Up @@ -480,7 +485,6 @@ def updateResults():

# SRM device traffic
periods = [p.strip() for p in os.environ.get("PERIODS", "live").split(",")]
# periods = ["live", "day", "week", "month"]
for period in periods:
(
device_traffics,
Expand Down Expand Up @@ -577,4 +581,13 @@ def mainPage():
if __name__ == "__main__":
PORT = os.environ.get("EXPORTER_PORT", 9922)
logging.info("Starting Synology-SRM-Exporter on http://localhost:" + str(PORT))
# SRM Authentication
logging.info(
"Loging to "
+ str(HOST)
+ " using "
+ str(os.environ.get("SRM_USERNAME", "admin"))
+ "user"
)
client = srm_auth()
serve(app, host="0.0.0.0", port=PORT)

0 comments on commit b063909

Please sign in to comment.