{"id":23992899,"url":"https://github.com/salvoxia/graphite-smart-exporter","last_synced_at":"2025-08-01T16:38:47.631Z","repository":{"id":226887106,"uuid":"769899586","full_name":"Salvoxia/graphite-smart-exporter","owner":"Salvoxia","description":"Drop-in S.M.A.R.T. exporter for TrueNAS SCALE. Monitors drive S.M.A.R.T. attributes and periodically sends them to a Graphite compatible server as tagged metrics to complement TrueNAS SCALE's own metrics.","archived":false,"fork":false,"pushed_at":"2024-03-26T19:56:13.000Z","size":111,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-07T20:39:33.661Z","etag":null,"topics":["exporter","graphite","prometheus","smart","smartctl","truenas","truenas-scale"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Salvoxia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2024-03-10T11:37:18.000Z","updated_at":"2024-12-02T08:58:24.000Z","dependencies_parsed_at":"2024-03-26T20:45:49.032Z","dependency_job_id":null,"html_url":"https://github.com/Salvoxia/graphite-smart-exporter","commit_stats":null,"previous_names":["salvoxia/graphite-smart-exporter"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Salvoxia%2Fgraphite-smart-exporter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Salvoxia%2Fgraphite-smart-exporter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Salvoxia%2Fgraphite-smart-exporter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Salvoxia%2Fgraphite-smart-exporter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Salvoxia","download_url":"https://codeload.github.com/Salvoxia/graphite-smart-exporter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240614058,"owners_count":19829270,"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":["exporter","graphite","prometheus","smart","smartctl","truenas","truenas-scale"],"created_at":"2025-01-07T20:37:54.378Z","updated_at":"2025-02-25T06:21:34.808Z","avatar_url":"https://github.com/Salvoxia.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Graphite S.M.A.R.T. Exporter\n\n_Monitors drive S.M.A.R.T. attributes and periodically sends them to a Graphite compatible server as tagged metrics_\n\nThis script was conceived to be an addon to [TrueNAS's](https://www.truenas.com/) own metrics system using [Graphite](https://graphiteapp.org/). The goal of this script was to run out-of-the-box on a TrueNAS SCALE and provide detailed S.M.A.R.T. metrics for all S.M.A.R.T. capable devices in the system.  \n\nIt sends plain-text tagged Graphite metrics, which are compatible with the [Prometheus Graphite Exporter](https://github.com/prometheus/graphite_exporter) out-of-the-box. No configuration is necessary in Graphite Exporter, since it supports tagged metrics. To get all of TrueNAS' metrics into Prometheus, Supporterino's [Graphite Mapping File for Prometheus Graphite Exporter](https://github.com/Supporterino/truenas-graphite-to-prometheus) is very helpful.\n\nIf a TrueNAS system is already monitored, a Graphite compatible receiver endpoint is available as well, so this script plugs right into that endpoint.\n\nOther solutions to get S.M.A.R.T. metrics from a system exist, such as [smartctl_exporter](https://github.com/prometheus-community/smartctl_exporter) or [prometheus-smartctl](https://github.com/matusnovak/prometheus-smartctl), but these would either need to be run in a privileged container using TrueNAS SCALE's app system (`smartctl_exporter`) or need additional python modules not available on a TrueNAS installation (`prometheus-smartctl`). With TrueNAS being an appliance (and moving to a read-only file system with Dragonfish release), installing python modules is not a viable option.\n\n__Requirements:__\n - [bash](https://www.gnu.org/software/bash/)\n - [smartctl 7.0](https://www.smartmontools.org/)\n - [jq](https://jqlang.github.io/jq/) with oniguruma library (Developed and tested with v1.6, works with v1.5 as well)\n - [netcat](https://nc110.sourceforge.io/)\n\nThis script uses `smartctl`'s json output mode, which was introduced with version `7.0`, hence the requirement.  \n\nEven though this script was developed with TrueNAS SCALE in mind, and this documentation mentions use cases related to this scenario in special, it should be able to run on any machine providing the above prerequisites.\n\nTested on:\n  - TrueNAS SCALE 23.10.1\n  - Debian 12.4 Bookworm \n  - Synology DSM 7.1 (with manually installed smartctl v7.4 and netcat via [Entware](https://github.com/Entware/Entware))\n\nMight/should work on TrueNAS CORE, test results are welcome!\n\n## Key Features\n  - [Run at startup and send metrics with customizable frequency](#set-up-script-to-run-at-truenas-startup-with-custom-frequency)\n  - [Tags to make metrics resilient against device name changes after reboots](#exported-metrics-and-tags)\n  - [Continue to send last known metrics for devices in STANDBY](#continue-to-send-last-known-metrics-for-devices-in-standby)\n  - [Special metrics for device's power state](#exported-metrics-and-tags)\n  - [ZFS Support: Provides pool name in info metric](#zfs-support)\n  - [Manually specify devices to monitor](#manually-specifying-devices-to-monitor)\n  - [Manually specify device types](#manually-specify-device-types)\n  - [Logging](#logging)\n\n## Disclaimer\n\nThis script was heavily inspired by ngandrass's [TrueNAS Spindown Timer](https://github.com/ngandrass/truenas-spindown-timer). In fact, it was developed to be used in conjunction with the `truenas-spindown-timer` script, since periodic S.M.A.R.T. queries will prevent a device from spinning down on its own. With `truenas-spindown-timer`, drives will still spin down and not be disturbed by this script.  \n\nOne of the main motivations for the development of this script was to gather statistics on how often drives are getting spun down and woken up with a specific usage profile to determine whether disk spindown is worth the potential shortening of disk life vs. energy consumption savings.\n\n## Usage\n```\nGraphite S.M.A.R.T. exporter version 1.1.4\nUsage:\n  ./graphite_smart_exporter.sh [-h] -d [-p] -n \u003cHOSTNAME\u003e [-f \u003cFREQUENCY\u003e] [-c] [-m \u003cDEVICE\u003e] [-t \u003cDEVICE=TYPE\u003e ] [-v] [-q] [-l \u003cLOG_FILE\u003e] [-s \u003cSMART_TEMP_FILE_NAME\u003e]\n\nGathers S.M.A.R.T. data about all S.M.A.R.T. capable drives in the system\nand sends them as metrics to a Graphite server.\n\nOptions:\n  -d DESTINATION            : The destnation IP address or host name under which the Graphite\n                              server is reachable.\n  -p PORT                   : The port the Graphite server is listening on for the plaintext protocol.\n  -n HOSTNAME               : The host name to set for the metrics' 'instance' tag.\n  -f FREQUENCY              : Frequency metrics are gathered and sent to Graphite with in seconds\n                              (default: 300)\n  -l LOG_FILE               : Name of the log file to log into. File logging is only enabled if a file name is provided. (default: empty)\n  -c                        : Continue sending last known/stale data if a drive is in standby/spun down. If a drive is spun down, S.M.A.R.T. attributes \n                              cannot be read without waking it up. If this option is set, the script continues to send the last known S.M.A.R.T. \n                              metrics for a drive that is spun down to prevent gaps in data.\n                              Otherwise no metrics are sent until the drive is awake again.\n  -m DEVICE                 : List devices to monitor using this argument, once per drive to minor, e.g. -m /dev/sda -m /dev/sdc\n  -t DEVICE=TYPE            : Manually specify the device type for a device. Use this if smartctl device type autodetection does not work for your case. Does NOT disable device discovery. Example: -t /dev/sda=nvme\n  -s SMART_TEMP_FILE_NAME   : Name of the temp file the S.M.A.R.T. output is written to during each cycle the script is running.\n                              Explicitly set if you plan on running multiple instances of this script to prevent collisions. (default: smart_output.json)\n  -o                        : Omit device name tag from info metric. If you're dealing with a system that changes device names frequently, set this flag to avoid multiple time series after the device changed name.\n  -q                        : Quiet mode. Outputs are suppressed set. Can not be set if -v is set.\n  -v                        : Verbose mode. Prints additional information during execution. File logging is only enabled in verbose mode. Can not be set if -q is set.\n  -h                        : Print this help message.\nExample usage:\n./graphite_smart_exporter.sh -d graphite.mydomain.com -n myhost\n./graphite_smart_exporter.sh -d graphite.mydomain.com -p 9198 -n myhost -f 600\n./graphite_smart_exporter.sh -d graphite.mydomain.com -n myhost -f 600 -o -m /dev/sda -m /dev/sdc -t /dev/sdc=sat\n```\n\n## Set up script to run at TrueNAS startup with custom frequency\nTo automatically run the script after startup, use TrueNAS' [Init/Shutdown Scripts](https://www.truenas.com/docs/scale/scaleuireference/systemsettings/advancedsettingsscreen/#init/shutdown-scripts-widget) feature.   \nDownload the script onto your machine. In your TrueNAS UI, navigate to `System Settings -\u003e Advanced -\u003e Init/Shutdown Scripts` and create a new script with the following settings:\n - __Description:__ `Graphite SMART Exporter`\n - __Type:__ `Command`\n - __Command:__ `sudo /path/to/script/graphite_smart_exporter.sh -d graphite.mydomain.com -n myhost -f 60`\n - __When:__ `Post Init`\n\n![Init Script Settings](images/init_script_setup.png)\n\nSince `smartctl` is only available for root, the script must be executed with `sudo`.  ö\nThe command above will send S.M.A.R.T. metrics to your Graphite instance every 60 seconds.\n\n## Exported Metrics and Tags\n\nAt the moment, the script supports metrics for `sat` and `nvme` type of devices.  \n(If you need additional device types supported, [open an issue] and append an example output of `smartctl --json=c -a`.)  \nSee [graphite_export.md](example_data/graphite_export.md) for a sample of this script's exported metrics.\n\n### Metrics\nThe script will export the following metrics:\n| Metric Name                |  Device Types | Description   |\n| :--------------------------| :----------- | :------------ |\n| `smart_disk_info`          | all          | Info metric with the sole purpose to provide tags to be joined to actual metrics using the serial number; has a static value of `1` |\n| `smart_attribute`          | `sat`        | Standard ATA S.M.A.R.T. attribute | \n| `smart_nvme_attribute`     | `nvme`       | NVME S.M.A.R.T Health Information |\n| `smart_device_temperature` | all          | Device Temperature in °C |\n| `smart_power_cycle_count`  | all          | Number of count of full power on/off cycles |\n| `smart_power_on_time_hours`| all          | Number of hours the device has been powered |\n| `smart_power_status`       | all          | Indicator whether the device is active or in standby/spun down |\n| `smart_status_passed`      | all          | Indicating whether the latest S.M.A.R.T. test has passed |\n\n\n### Disk Info Tags\nThe following tags/labels are added to the `smart_disk_info` info metric:\n| Tag Name                   | Description   |\n| :--------------------------| :------------ |\n| `model_name`               | The device's model name (if present), e.g. `HGST_HUH721010ALE600` | \n| `model_family`             | The device's model family (if present), e.g. `HGST_Ultrastar_He10`|\n| `serial_number`            | The device's serial number, e.g. `1EHXXXXX`; can be used make sure a certain metric always refers to the same phyiscal device if logical device names change during reboots |\n| `firmware_version`         | The firmware version reported by the device, e.g. `LHGNT384`|\n| `user_capacity_bytes`      | The drive's capacity in bytes, e.g. `10000831348736` |\n| `device_name`              | The shortened logical device name, e.g. `sda`; might change during reboots; not presetn it `-o` argument is set |\n| `device_type`              | The device type, e.g. `sat` |\n| `instance`                 | The host name passed to the script using `-n` |  \n| `zfs_pool`                 | If the disk is part of a ZFS pool, this tag contains the name of that pool |\n\n## Common Tags\nAll other metrics have the following common tags:\n| Tag Name                   | Description   |\n| :--------------------------| :------------ |\n| `serial_number`            | The device's serial number, e.g. `1EHXXXXX`; can be used to join to `smart_disk_info` metric for additional tags |\n\n### NVME Specific Tags\n`smart_nvme_attribute` metrics have these additional tags to the [common tags](#common-tags):\n| Tag Name                   | Description   |\n| :--------------------------| :------------ |\n| `value_type`               | Fixed to `raw` | \n| `attribute_name`           | Name of the reported NVME Health Information, e.g. `available_spare` |\n\n### SAT Specific Tags\n`smart_attribute` metrics have these additional tags to the [common tags](#common-tags):\n| Tag Name                   | Description   |\n| :--------------------------| :------------ |\n| `value_type`               | One of `value`, `worst`, `thresh` or `raw` | \n| `attribute_name`           | Name of the reported ATA S.M.A.R.T. attribute, e.g. `Start_Stop_Count` |\n| `attribute_id`             | Unique ID of the S.M.A.R.T. attribute, e.g. `4` |\n\n\n### Limitations for tag values\nThe [Graphite Documentation on tagged metrics](https://graphite.readthedocs.io/en/latest/tags.html) reads the following about tag values: \n\u003e Tag values must also have a length \u003e= 1, they may contain any ascii characters except  `;` and the first character must not be `~`.\n\nFor values that might not always exist (such as `model_name` or `model_family`) that means that the whole tag cannot be added if the value is empty.  \nEven though the definition for allowed tag value characters implies that a whitespace is allowed, whitespaces in tag values seem to break some Graphite servers such as the Prometheus Graphite Exporter. This is why this script will replace blanks ` ` in tag values with underscores `_`.\n\n## Omit Device Name from Info Metric\nIf the device names change between reboots or if devices are added to the system, this will cause multiple time series to be created due to the now differing `device_name` tag. To avoid this, start the script specifying the `-o` flag, which will cause the `device_name` tag to be omitted from the `smart_disk_info` metric.\nIf `device_name` is volatile, it is of limited value anyway.\n\n## ZFS Support\nSince the script was originally designed to be run on a TrueNAS based system, information about ZFS pool assignment for each disk is a logical supplement for the disk's info metrics.\nIf the script detects ZFS on the system, it will try to find the ZFS pool each monitored disk is assigned to and add a `zfs_pool` tag to the `smart_disk_info` metric. \n\n\n## Continue to send last known metrics for devices in STANDBY\n\nIf a device is in standby / spun down, querying S.M.A.R.T. attributes would wake it up, which this script will not do. On the other hand this means there are no metrics available for disks that are in standby.  \n\nThe script offers the argument `-c`. If that argument is set, it will continue to send the last queried metrics for a device in standby to prevent gaps in the metric time series. The only metric that will be updated is `smart_power_state` (which will reflect the standby state by being `0`).  \n⚠️ Be aware that this has the side effect of continuous metrics such as `smart_device_temp` or `smart_power_on_hours` to show sudden jumps in graphs when the updated values are sent after the device has woken up again.\n\n\n## Manually specify devices to monitor\n\nBy default, the script will scan for all S.M.A.R.T. capable device in the system at startup and send metrics for all these devices. If only a specific subset of devices should be monitored, these devices may be passed to the script with the argument `-m`, specifying the argument once per device to monitor.  \nThe following example will only monitor devices `/dev/sda` and `/dev/sdc` and will not scan for other devices:\n```bash\n./graphite_smart_exporter.sh -d graphite.mydomain.com -n myhost -m /dev/sda -m /dev/sdc\n```\n\n## Manually specify device types\n\n`smartctl` will try to guess the correct device type when querying a specific device. However, it might not get it right for all devices, which might result in wrong/missing output.  \nTo manually force the script to use a specific device type for a certain device, specify it using the arugment `-t` in the form `\u003cdevice_name\u003e=\u003ctype\u003e`, once per device.  \nThe following example will only monitor devices `/dev/sda` and `/dev/sdc`, but force `/dev/sdc` to be treated as `sat` type device:\n```bash\n./graphite_smart_exporter.sh -d graphite.mydomain.com -n myhost -m /dev/sda -m /dev/sdc -t /dev/sdc=sat\n```\n\nNote that specifying `-t` alone without `-m` will not disable scanning for devices, but will honor the device type for the specified devices.\n\n## Logging\n\nThe script uses `logfmt` as a logging format and supports normal logging to console, logging to a file and no log output at all:\n - pass no additional arguments to only use normal log output on console\n - pass `-v` to enable debug log output\n - pass `-l graphite_smart_exporter.log` to enable logging to the `graphite_smart_exporter.log` file using the specified verbosity level\n - pass `-q` to disable all logging\n\nNote that `-v` and `-q` cannot be set at the same time.\n\nexport PATH=/opt/sbin:/opt/bin:$PATH\nBASEDIR=$(dirname \"$0\")\nbash $BASEDIR/graphite_smart_exporter.sh -v -d graphite.local.salvoxia.de -p 9109 -n samvault.local.salvoxia.de -s smart_output2.json -f 60 -l graphite_smart_exporter.log -t /dev/sda=sat -t /dev/sdb=sat\n\n\n## Installation on Synology DSM\n\nSynology DSM 7.1 uses an older version of `smartctl` that does not support json formatted output. In order to use Graphite S.M.A.R.T. Exporter, a newer version of `smartctl` must be installed.  \nThis can be done using [Entware](https://github.com/Entware/Entware).  \n\n### Guide\n1. Follow the [installation instructions for Entware](https://github.com/Entware/Entware/wiki/Install-on-Synology-NAS)\n2. Install `smartctl` using Entware\n   ```bash\n   sudo opkg install smartctl\n    ```\n3. Copy `graphite_smart_exporter.sh` and `synolgoy_wrapper.sh` to a suitable folder on your Synology NAS\n4. Make `graphite_smart_exporter.sh` and `synolgoy_wrapper.sh` executable\n   ```\n   chmod +x graphite_smart_exporter.sh synolgoy_wrapper.sh\n   ```\n5. Log in to DSM Web interface DSM \u003e Control Panel \u003e Task Scheduler\n    - Create \u003e Triggered Task \u003e User Defined Script\n      - General\n        - Task: Graphite S.M.A.R.T. Exporter\n        - User: root\n        - Event: Boot-up\n        - Pre-task: Entware\n      - Task Settings\n        - Run Command: (see bellow)\n\n   ```\n   /bin/bash /path/to/exporter/synology_wrapper.sh \u003cexporterArgs\u003e\n   ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsalvoxia%2Fgraphite-smart-exporter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsalvoxia%2Fgraphite-smart-exporter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsalvoxia%2Fgraphite-smart-exporter/lists"}