{"id":13621900,"url":"https://github.com/ar51an/unbound-dashboard","last_synced_at":"2025-04-09T20:13:23.118Z","repository":{"id":190101794,"uuid":"583624397","full_name":"ar51an/unbound-dashboard","owner":"ar51an","description":"Unbound Dashboard In Grafana With Prometheus \u0026 Loki","archived":false,"fork":false,"pushed_at":"2024-07-26T05:47:19.000Z","size":611,"stargazers_count":266,"open_issues_count":2,"forks_count":19,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-09T20:13:18.110Z","etag":null,"topics":["dashboard","go","golang","grafana","grafana-dashboard","grafana-loki","logs","loki","metrics","prometheus","prometheus-exporter","prometheus-metrics","unbound","unbound-dashboard","unbound-exporter"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ar51an.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2022-12-30T11:07:26.000Z","updated_at":"2025-04-09T12:50:28.000Z","dependencies_parsed_at":"2024-08-01T21:54:20.526Z","dependency_job_id":null,"html_url":"https://github.com/ar51an/unbound-dashboard","commit_stats":null,"previous_names":["ar51an/unbound-dashboard"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ar51an%2Funbound-dashboard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ar51an%2Funbound-dashboard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ar51an%2Funbound-dashboard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ar51an%2Funbound-dashboard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ar51an","download_url":"https://codeload.github.com/ar51an/unbound-dashboard/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248103872,"owners_count":21048245,"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":["dashboard","go","golang","grafana","grafana-dashboard","grafana-loki","logs","loki","metrics","prometheus","prometheus-exporter","prometheus-metrics","unbound","unbound-dashboard","unbound-exporter"],"created_at":"2024-08-01T21:01:11.823Z","updated_at":"2025-04-09T20:13:23.092Z","avatar_url":"https://github.com/ar51an.png","language":null,"funding_links":[],"categories":["Others","go"],"sub_categories":[],"readme":"## unbound dashboard\n\u003cdiv align=\"center\"\u003e\n\n![unbound](https://img.shields.io/badge/-unbound‑dashboard-D8BFD8?logo=unrealengine\u0026logoColor=3a3a3d)\n\u0026nbsp;\u0026nbsp;[![release](https://img.shields.io/github/v/release/ar51an/unbound-dashboard?display_name=release\u0026logo=rstudio\u0026color=90EE90\u0026logoColor=8FBC8F)](https://github.com/ar51an/unbound-dashboard/releases/latest/)\n\u0026nbsp;\u0026nbsp;![downloads](https://img.shields.io/github/downloads/ar51an/unbound-dashboard/total?color=orange\u0026label=downloads\u0026logo=github)\n\u0026nbsp;\u0026nbsp;![visitors](https://img.shields.io/endpoint?color=4883c2\u0026label=visitors\u0026logo=github\u0026url=https%3A%2F%2Fhits.dwyl.com%2Far51an%2Funbound-dashboard.json)\n\u0026nbsp;\u0026nbsp;![license](https://img.shields.io/github/license/ar51an/unbound-dashboard?color=CED8E1)\n\u003c/div\u003e\n\n\u003cbr/\u003e\n\n![Latest](https://github.com/ar51an/unbound-dashboard/blob/main/screenshots/dashboard-2.3.png)\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://user-images.githubusercontent.com/11185794/205388020-99c057ad-ee9d-440b-8df9-587f5c133f2e.png?raw=true\" alt=\"divider\"/\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"justify\"\u003e\n\n### Summary\n🔸 Unbound dashboard in `Grafana`  \n🔸 `Prometheus` time series database  \n🔸 Unbound metrics exporter in `Go`  \n🔸 Log aggregation with `Loki`  \n🔸 Unbound `setup` is available at [unbound-redis](https://github.com/ar51an/unbound-redis)  \n🔸 Refer to `info.md` for dashboard details and `release.md` for changes\n\n#### Specs:\n\u003e |Grafana |Prometheus|Loki   |Go      |OS                           |HW                      |\n\u003e |:-------|:---------|:------|:-------|:----------------------------|:-----------------------|\n\u003e |`11.1.0`|`2.42.0`  |`3.1.0`|`1.21.5`|`raspios-bookworm-arm64-lite`|`Raspberry Pi 4 Model B`|\n\n#\n### Steps\n\u0026nbsp;\u0026nbsp;🔸 Grafana ➜ Prometheus ➜ Unbound Exporter ➜ Loki ➜ Import Dashboard\n#### ❯ Grafana\n* **Download:**  \n  There are 2 versions **OSS** and **Enterprise**. OSS version is more than enough. Enterprise version installs too many extra packages (like unattended-upgrades and more). Below cmd downloads _Grafana OSS_ for arm64.\n  \u003e `wget https://dl.grafana.com/oss/release/grafana_11.1.0_arm64.deb`\n\n* **Install:**\n  \u003e `sudo apt install musl`\n  \n  \u003e `ℹ️` **Note:**  \n  \u003e `musl` package is required since _Grafana 10.2.3_\n\n  \u003e `sudo dpkg -i grafana_11.1.0_arm64.deb`\n\n  \u003e `ℹ️` **Note:**  \n  \u003e A tweaked `grafana.ini` is available in the release. It reduces memory footprint, removes usage collection, stops calls to grafana server/repo and has few more optimizations. You can use _grafana.ini_ **either** from the release **or** the default one. Default config is located at `/etc/grafana/grafana.ini`\n\n* **Start:**\n  \u003e `sudo systemctl daemon-reload`  \n  \u003e `sudo systemctl enable grafana-server`  \n  \u003e `sudo systemctl start grafana-server`\n\n* **UI:**\n  \u003e `http://\u003cRP-IP\u003e:3000/`  \n  \u003e Default user/pass ➟ admin/admin\n\n#\n#### ❯ Prometheus\n* **Install:**  \n  \u003e `sudo apt install prometheus`\n\n* **Config:**  \n  Enable _unbound-exporter_ scraping in prometheus. A trimmed down prometheus config, `prometheus.yml` is available in the release. Take a backup of existing _prometheus.yml_, if you are interested in the default config. Copy `prometheus.yml` from the release to `/etc/prometheus/` dir.\n\n  \u003e `ℹ️` **Note:**  \n  \u003e Provided `prometheus.yml` has only _unbound-exporter_ metric collection enabled. Default metric collection for _node_ and _prometheus_ exporters are removed. Scraping interval is set to _5m_.\n\n* **Remove Node Exporter:**  \n  Node exporter exports machine metrics. It is installed as part of prometheus pkg and runs as systemd service. It is not needed for _unbound-dashboard_. Unless you are already using it, remove node exporter. Below cmd will remove 8 node-exporter related pkgs. \n  \u003e **Remove:**  \n  \u003e `sudo apt --purge autoremove prometheus-node-exporter`  \n  \u003e **Disable scrape config:**  \n  \u003e Provided `prometheus.yml` has _node_ exporter scrapping config removed. \n\n* **UI:**\n  \u003e `http://\u003cRP-IP\u003e:9090/`\n\n#\n#### ❯ Unbound Exporter\n* I wrote my own exporter in `Go`. It is more efficient and tailored for this dashboard. A prebuilt binary (for arm64) is available in the release. Source code is available at [unbound-exporter](https://github.com/ar51an/unbound-exporter).\n\n* **Config:**  \n  Modify Unbound config. Edit `/etc/unbound/unbound.conf`\n  * Enable extended stats. Add option under **`server:`** tag  \n    \u003e `extended-statistics: yes`\n\n  * Enable Unix domain socket for collecting stats. It is faster than default TCP. Add below options under **`remote-control:`** tag  \n    \u003e `control-interface: \"/var/run/unbound.sock\"`  \n    \u003e `control-use-cert: no`\n\n* **Install:**  \n  Copy `unbound-exporter` binary from the release to `/usr/local/bin/` dir. Make sure it is under ownership of root and executable.\n  \u003e **Change ownership [If needed]:**  \n  \u003e `sudo chown root:root /usr/local/bin/unbound-exporter`  \n  \u003e **Make it executable [If needed]:**  \n  \u003e `sudo chmod +x /usr/local/bin/unbound-exporter`\n\n* **Service:**  \n  Create service to automatically run _unbound-exporter_ at startup. Copy `prometheus-unbound-exporter.service` from the release to `/etc/systemd/system/` dir. Make sure it is under the ownership of root. Enable and start the service.\n  \u003e **Change ownership [If needed]:**  \n  \u003e `sudo chown root:root /etc/systemd/system/prometheus-unbound-exporter.service`  \n  \u003e **Enable:**  \n  \u003e `sudo systemctl enable prometheus-unbound-exporter`  \n  \u003e **Start:**  \n  \u003e `sudo systemctl start prometheus-unbound-exporter`  \n  \u003e **Status:**  \n  \u003e `sudo systemctl status prometheus-unbound-exporter`\n\n  \u003e `ℹ️` **Note:**  \n  \u003e Provided `prometheus-unbound-exporter.service` passes 2 paramaters. Blocklist file path and Unbound unix domain socket URI. Change them accordingly if you are using different path and name.\n\n* **Usage:**\n  \u003e `unbound-exporter -h`  \n  \u003e\n  \u003e ![Usage](https://user-images.githubusercontent.com/11185794/213899374-457728c8-c92a-4280-b638-5116d165f934.png)\n\n#\n#### ❯ Loki\n* **Download:**  \n  Download `Loki` and `Promtail`\n  \u003e `curl -O -L \"https://github.com/grafana/loki/releases/download/v3.1.0/loki_3.1.0_arm64.deb\"`  \n  \u003e `curl -O -L \"https://github.com/grafana/loki/releases/download/v3.1.0/promtail_3.1.0_arm64.deb\"`\n\n* **Install:**\n  \u003e `sudo dpkg -i loki_3.1.0_arm64.deb`  \n  \u003e `sudo dpkg -i promtail_3.1.0_arm64.deb`\n\n* **Logging:**  \n  Enable Unbound logging.\n  * Edit `/etc/unbound/unbound.conf`. Add/Modify below options under **`server:`** tag  \n    \u003e `log-replies: yes`  \n    \u003e `log-tag-queryreply: yes`  \n    \u003e `log-local-actions: yes`  \n    \u003e `logfile: /var/log/unbound/unbound.log`\n\n    \u003e `ℹ️` **Note:**  \n    \u003e Make sure `verbosity:` is set to 0.\n\n  * Create log dir  \n    \u003e `sudo mkdir /var/log/unbound`  \n    \u003e `sudo chown unbound:unbound /var/log/unbound`\n\n  * Enable log rotation\n    \u003e Copy file `unbound` from the release under _logrotate_ dir to `/etc/logrotate.d/` dir. Make sure it is under the ownership of root.\n\n* **Config:**  \n  Replace `/etc/loki/config.yml` and `/etc/promtail/config.yml` with the `config.yml` files in the release under _loki_ and _promtail_ dirs respectively. Both should be under the ownership of root.\n\n  \u003e `ℹ️` **Note:**  \n  \u003e Provided _loki_ `config.yml` is optimized to process large data set and metrics calculation for Unbound logs. It is tweaked after some thorough testing in Unbound logs specific dashboard with 6 panels. Default _loki_ config can hardly handle 2 panels with small data set, it throws errors and timeouts with large data set and multiple requests.  \n  \u003e Provided _promtail_ `config.yml` enables Unbound logs scrapping.\n\n* **Restart:**\n  \u003e `sudo systemctl restart loki`  \n  \u003e `sudo systemctl restart promtail`\n\n#\n#### ❯ Import Dashboard\n* Open Grafana UI ➟ `http://\u003cRP-IP\u003e:3000/`\n\n  * Click `Data Sources` under `Configuration`. Click `Add data source` select **`Prometheus`**. Add below options:  \n    \u003e _Name_ ➟ `Prometheus`  \n    \u003e _Default_ ➟ `On`  \n    \u003e Add _URL_ ➟ `http://localhost:9090`  \n    \u003e Add _Scrape interval_ ➟ `5m`  \n    \u003e Hit ➟ `Save \u0026 test`\n\n  * Click `Data Sources` under `Configuration`. Click `Add data source` select **`Loki`**. Add below options:  \n    \u003e _Name_ ➟ `Loki`  \n    \u003e Add _URL_ ➟ `http://localhost:3100`  \n    \u003e Add _Maximum lines_ ➟ `100000`  \n    \u003e Hit ➟ `Save \u0026 test`\n\n  * Dashboard, `unbound-dashboard.json` is available in the release. Click `Import` under `Dashboards`. Click `Upload JSON file`. Select `unbound-dashboard.json`. Add below options:  \n    \u003e _Folder_ ➟ `Dashboards`  \n    \u003e Select _Prometheus_ ➟ `Data Source`  \n    \u003e Select _Loki_ ➟ `Data Source`  \n    \u003e Hit ➟ `Import`\n\n#\n#### ❯ `ℹ️` Tips \u0026 Notes\n* **Grafana:**  \n  How to ➟ Change grafana `landing page` to unbound dashboard **\u0026** Switch between `Dark` (default) and `Light` theme.\n\n  \u003e Open Grafana UI ➟ `http://\u003cRP-IP\u003e:3000/`  \n  \u003e Click `Profile` under top right icon  \n  \u003e Under `Preferences` select `General/Unbound` in `Home Dashboard` drop down  \n  \u003e Change theme in `Interface theme` drop down  \n  \u003e Hit `Save`\n\n  There is an additional panel in the dashboard at the top right, not visible in the preview. It shows _unbound-exporter_ status and may be beneficial. If you are not interested in that simply remove it. Screenshot below:  \n  \u003e ![Metrics](https://user-images.githubusercontent.com/11185794/217952236-ef8ec0cb-a754-49d1-a1b4-d3a7cf5f49ef.png)\n\n* **Prometheus:**  \n  How to ➟ `Remove` time series (metrics) collected by prometheus instantly for fresh start **\u0026** Reduce prometheus journal `logging`.\n  \u003e Enable admin API:  \n  \u003e `sudo nano /etc/default/prometheus`  \n  \u003e Add at the top:\n  \u003e `ARGS=\"--web.enable-admin-api --log.level=warn\"`  \n  \u003e Save \u0026 Exit\n\n  \u003e To delete all metrics of specific exporter add `job_name` as last argument in delete cmd:  \n  \u003e Delete:  \n  \u003e `curl -X POST -g 'http://localhost:9090/api/v1/admin/tsdb/delete_series?match[]={job=\"node\"}'`  \n  \u003e Purge:  \n  \u003e `curl -X POST -g 'http://localhost:9090/api/v1/admin/tsdb/clean_tombstones'`  \n  \u003e Restart:  \n  \u003e `sudo systemctl restart prometheus`\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Far51an%2Funbound-dashboard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Far51an%2Funbound-dashboard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Far51an%2Funbound-dashboard/lists"}