Introduction
Monitoring my Synology NAS has been at the back of my mind for a very long time. While Synology does provide some basic observability in DSM, it is rather cumbersome to click around every time just to find all the metrics and dashboards I care about. I wanted to a single pane of glass when it comes to observing my homelab. In my K3s cluster, I already have Prometheus and Grafana provisioned to monitor my cluster’s health. My goal is to have relevant Synology NAS metrics scraped by Prometheus, and eventually visualized on Grafana.
As shown above, I have decided to use the Prometheus SNMP exporter to get metrics from my NAS. In short, Simple Network Management Protocol (SNMP) is a protocol used for managing and monitoring of network-connected devices, such as a switch, UPS, and NAS.
Enabling SNMP on Synology DSM
Login to your Synology DSM and enable SNMP from the Control Planel
as shown above. For security purposes:
SNMPv3
is recommended overSNMPv1
andSNMPv2c
SHA
is recommended overMD5
AES
is recommended overDES
If you have enabled firewall, you will have to allow SNMP port 161 so that the SNMP exporter can access without issues.
Generating SNMP config file
In this section, we will prepare the SNMP config file which is required when you run the SNMP exporter later.
- Clone the SNMP exporter repository.
git clone https://github.com/prometheus/snmp_exporter.git
- Checkout the release tag.
git checkout tags/v0.26.0
- Edit
generator/generator.yml
. The changes I have done:auths.synology
to specify the proper authentication required as configured previously in Synology DSM- Removed all modules except
modules.if_mib
,modules.ip_mib
, andmodules.synology
- Added OIDs for host resource system and storage to
modules.synology.walk
to get some host resource metrics for the Grafana dashboard later - Replace
hrStorageIndex
label withhrStorageDescr
usingmodules.synology.lookups
to be compatible with the Grafana dashboard later
auths: synology: version: 3 username: REPLACE_ME security_level: authPriv password: REPLACE_ME auth_protocol: SHA priv_protocol: AES priv_password: REPLACE_ME modules: # Default IF-MIB interfaces table with ifIndex. if_mib: walk: [sysUpTime, interfaces, ifXTable] lookups: - source_indexes: [ifIndex] lookup: ifAlias - source_indexes: [ifIndex] # Uis OID to avoid conflict with PaloAlto PAN-COMMON-MIB. lookup: 1.3.6.1.2.1.2.2.1.2 # ifDescr - source_indexes: [ifIndex] # Use OID to avoid conflict with Netscaler NS-ROOT-MIB. lookup: 1.3.6.1.2.1.31.1.1.1.1 # ifName overrides: ifAlias: ignore: true # Lookup metric ifDescr: ignore: true # Lookup metric ifName: ignore: true # Lookup metric ifType: type: EnumAsInfo # Default IP-MIB with ipv4InterfaceTable for example. ip_mib: walk: [ipv4InterfaceTable] # Synology MIBs can be found here: # http://www.synology.com/support/snmp_mib.php # http://dedl.synology.com/download/Document/MIBGuide/Synology_MIB_File.zip synology: walk: - laNames - laLoadInt - ssCpuUser - ssCpuSystem - ssCpuIdle - memory - 1.3.6.1.4.1.6574.1 # synoSystem - 1.3.6.1.4.1.6574.2 # synoDisk - 1.3.6.1.4.1.6574.3 # synoRaid - 1.3.6.1.4.1.6574.4 # synoUPS - 1.3.6.1.4.1.6574.5 # synologyDiskSMART - 1.3.6.1.4.1.6574.6 # synologyService - 1.3.6.1.4.1.6574.101 # storageIO - 1.3.6.1.4.1.6574.102 # spaceIO - 1.3.6.1.4.1.6574.104 # synologyiSCSILUN - 1.3.6.1.2.1.25.1 # hrSystem - 1.3.6.1.2.1.25.2 # hrStorage lookups: - source_indexes: [spaceIOIndex] lookup: spaceIODevice drop_source_indexes: true - source_indexes: [storageIOIndex] lookup: storageIODevice drop_source_indexes: true - source_indexes: [serviceInfoIndex] lookup: serviceName drop_source_indexes: true - source_indexes: [diskIndex] lookup: diskID drop_source_indexes: true - source_indexes: [raidIndex] lookup: raidName drop_source_indexes: true - source_indexes: [laIndex] lookup: laNames drop_source_indexes: true - source_indexes: [hrStorageIndex] lookup: hrStorageDescr drop_source_indexes: true overrides: diskModel: type: DisplayString diskSMARTAttrName: type: DisplayString diskSMARTAttrStatus: type: DisplayString diskSMARTInfoDevName: type: DisplayString diskType: type: DisplayString modelName: type: DisplayString raidFreeSize: type: gauge raidName: type: DisplayString raidTotalSize: type: gauge serialNumber: type: DisplayString serviceName: type: DisplayString version: type: DisplayString
- (Optional) Edit
generator/Makefile
. Remove the unnecessary MIBs so they won’t be downloaded when generating the SNMP config. Specifically, I have left these in themibs
rule.mibs: \ $(MIBDIR)/IANA-CHARSET-MIB.txt \ $(MIBDIR)/IANA-IFTYPE-MIB.txt \ $(MIBDIR)/IANA-PRINTER-MIB.txt \ $(MIBDIR)/.net-snmp \ $(MIBDIR)/.synology
- Generate the SNMP config.
# if using docker make docker-generate # if running locally make generate
- You should see your SNMP config in
generator/snmp.yml
.
Deploying SNMP exporter
I have decided to deploy the SNMP exporter in my K3s cluster, so the instructions will be catered for that. There are no strict requirements where you run the SNMP exporter, as long as it has sufficient resources and access to your NAS, e.g. you could run it on a server using systemd.
Here are the Kubernetes manifests:
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: snmp-config
type: Opaque
stringData:
snmp.yml: |
REPLACE_ME_WITH_GENERATED_SNMP_YML
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: snmp-exporter
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: snmp-exporter
template:
metadata:
labels:
app.kubernetes.io/name: snmp-exporter
spec:
containers:
- name: snmp-exporter
image: quay.io/prometheus/snmp-exporter:v0.26.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9116
name: http
protocol: TCP
livenessProbe:
httpGet:
path: /
port: 9116
initialDelaySeconds: 0
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 3
readinessProbe:
httpGet:
path: /
port: 9116
initialDelaySeconds: 0
periodSeconds: 10
timeoutSeconds: 1
failureThreshold: 3
resources:
limits:
cpu: 250m
memory: 180Mi
requests:
cpu: 50m
memory: 180Mi
volumeMounts:
- mountPath: /etc/snmp_exporter
name: config
volumes:
- name: config
secret:
secretName: snmp-config
serviceAccountName: snmp-exporter
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: snmp-exporter
spec:
ports:
- name: http
port: 9116
protocol: TCP
targetPort: 9116
selector:
app.kubernetes.io/name: snmp-exporter
# serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: snmp-exporter
# servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: snmp-exporter
spec:
endpoints:
- interval: 5m
port: http
path: /snmp
params:
target:
- REPLACE_ME_WITH_NAS_IP
auth:
- synology
module:
- if_mib
- synology
selector:
matchLabels:
app.kubernetes.io/name: snmp-exporter
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: monitoring
commonLabels:
app.kubernetes.io/name: snmp-exporter
resources:
- deployment.yaml
- secret.yaml
- service.yaml
- serviceaccount.yaml
- servicemonitor.yaml
The above uses Kustomize to manage and customize the manifests. It also depends on the ServiceMonitor
custom resource from the Prometheus operator project. The ServiceMonitor
spec is then automatically translated to a Prometheus config and then reloaded in Prometheus once applied.
At this point, Prometheus is aware and begins scraping the /snmp
endpoint exposed by SNMP exporter. You can verify everything is working by querying a metric e.g. raidName
. If you would like to see the full list of metrics exposed by SNMP exporter, you can port-forward to the SNMP exporter and open the following in your browser: http://localhost:9116/snmp?target=REPLACE_ME_WITH_NAS_IP&auth=synology&module=synology&module=if_mib.
Visualizing on Grafana
Creating dashboards from scratch seems like a daunting task, especially when there are lots of metrics lying around. Thankfully, there are kind folks who shared their dashboards on Grafana and I found a comprehensive one for Synology NAS. After some modifications, fixes, and adaptations to my environment, here is the latest JSON model of my dashboard.
Do note that the scrape interval I have configured is 5 minutes to reduce the data points I collect since it is for my homelab. If you have done the same, you might want to update the scrape interval in the Prometheus data source in Grafana to match accordingly. Otherwise, $__rate_interval
used by the dashboard will not yield enough data points for rate
calculations. More on that here.
Thanks for following along up till this point! This concludes my guide on monitoring Synology NAS with Prometheus, Grafana, and SNMP exporter. Hope you found this guide useful and happy monitoring!