diff --git a/evolixisation.yml b/evolixisation.yml
index 03af200..950b46e 100644
--- a/evolixisation.yml
+++ b/evolixisation.yml
@@ -31,6 +31,7 @@
# - openvpn
# - ospf
# - bgp
+ # - { role: collectd, collectd_server: "127.0.0.1" }
post_tasks:
- include: "tasks/commit_etc_git.yml"
diff --git a/roles/collectd/README.md b/roles/collectd/README.md
new file mode 100644
index 0000000..e63b47b
--- /dev/null
+++ b/roles/collectd/README.md
@@ -0,0 +1,13 @@
+# Collectd
+
+Installation and custom configuration of Collectd daemon.
+
+## Tasks
+
+Everything is in the `tasks/main.yml` file.
+
+## Available variables
+
+The full list of variables (with default values) can be found in `defaults/main.yml`.
+
+* `collectd_server` : server to which the data will be sent (default: 127.0.0.1).
diff --git a/roles/collectd/defaults/main.yml b/roles/collectd/defaults/main.yml
new file mode 100644
index 0000000..7974087
--- /dev/null
+++ b/roles/collectd/defaults/main.yml
@@ -0,0 +1,31 @@
+---
+
+# destination server
+
+collectd_server: "127.0.0.1"
+
+# execution interval
+
+collectd_interval: "300"
+
+# exec plugin
+
+collectd_plugin_exec_interval: "{{ collectd_interval }}"
+collectd_plugin_exec_ifq_drops: false
+collectd_plugin_exec_dns_stats: false # Based on unbound
+collectd_plugin_exec_dns_stats_interval: "{{ collectd_interval }}"
+
+# others plugins
+
+collectd_plugin_cpu: true
+collectd_plugin_df: true
+collectd_plugin_disk: true
+collectd_plugin_interface: true
+collectd_plugin_load: true
+collectd_plugin_memory: true
+collectd_plugin_pf: true
+collectd_plugin_processes: true
+collectd_plugin_swap: true
+collectd_plugin_tcpconns: true
+collectd_plugin_uptime: true
+collectd_plugin_users: true
diff --git a/roles/collectd/files/dns_stats.sh b/roles/collectd/files/dns_stats.sh
new file mode 100755
index 0000000..8a11d3d
--- /dev/null
+++ b/roles/collectd/files/dns_stats.sh
@@ -0,0 +1,3 @@
+#!/bin/ksh
+
+echo "PUTVAL $(hostname)/dns_stats/count N:$(doas /bin/cat /var/log/daemon | grep "server stats" | grep -v "requestlist max" | awk '{print $13}' | tail -1)"
diff --git a/roles/collectd/files/ifq_drops.sh b/roles/collectd/files/ifq_drops.sh
new file mode 100755
index 0000000..25748f4
--- /dev/null
+++ b/roles/collectd/files/ifq_drops.sh
@@ -0,0 +1,3 @@
+#!/bin/ksh
+
+echo "PUTVAL $(hostname)/ifq_drops/count N:$(sysctl net.inet.ip.arpq.drops | awk -F= '{print $NF}')"
diff --git a/roles/collectd/handlers/main.yml b/roles/collectd/handlers/main.yml
new file mode 100644
index 0000000..00523b7
--- /dev/null
+++ b/roles/collectd/handlers/main.yml
@@ -0,0 +1,10 @@
+---
+- name: restart collectd
+ service:
+ name: collectd
+ state: restarted
+
+- name: reload unbound
+ service:
+ name: unbound
+ state: reloaded
diff --git a/roles/collectd/tasks/main.yml b/roles/collectd/tasks/main.yml
new file mode 100644
index 0000000..4ff066b
--- /dev/null
+++ b/roles/collectd/tasks/main.yml
@@ -0,0 +1,106 @@
+---
+- name: Install Collectd package
+ openbsd_pkg:
+ name: "collectd"
+ tags:
+ - collectd
+
+- name: Deploy Collectd configuration
+ template:
+ src: "collectd.conf.j2"
+ dest: "/etc/collectd.conf"
+ notify: restart collectd
+ tags:
+ - collectd
+
+- name: Enabling Collectd
+ service:
+ name: collectd
+ enabled: true
+ tags:
+ - collectd
+
+- name: Create scripts directory for exec plugins
+ file:
+ path: /usr/local/share/collectd/scripts
+ state: directory
+ when: collectd_plugin_exec_ifq_drops or collectd_plugin_exec_dns_stats
+ tags:
+ - collectd
+
+- name: Copy ifq_drops.sh
+ copy:
+ src: ifq_drops.sh
+ dest: /usr/local/share/collectd/scripts/ifq_drops.sh
+ mode: 0755
+ force: true
+ when: collectd_plugin_exec_ifq_drops
+ tags:
+ - collectd
+
+- name: Remove ifq_drops.sh
+ file:
+ path: /usr/local/share/collectd/scripts/ifq_drops.sh
+ state: absent
+ when: not collectd_plugin_exec_ifq_drops
+ tags:
+ - collectd
+
+- name: Copy dns_stats.sh
+ copy:
+ src: dns_stats.sh
+ dest: /usr/local/share/collectd/scripts/dns_stats.sh
+ mode: 0755
+ force: true
+ when: collectd_plugin_exec_dns_stats
+ tags:
+ - collectd
+
+- name: Add stats DNS on unbound
+ lineinfile:
+ path: /var/unbound/etc/unbound.conf
+ regexp: 'statistics-interval'
+ line:
+ ' statistics-interval: {{ collectd_plugin_exec_dns_stats_interval }}'
+ insertafter: 'hide-version:'
+ backup: true
+ notify: reload unbound
+ when: collectd_plugin_exec_dns_stats
+ tags:
+ - collectd
+
+- name: Remove dns_stats.sh
+ file:
+ path: /usr/local/share/collectd/scripts/dns_stats.sh
+ state: absent
+ when: not collectd_plugin_exec_dns_stats
+ tags:
+ - collectd
+
+- name: Remove stats DNS on unbound
+ lineinfile:
+ path: /var/unbound/etc/unbound.conf
+ regexp: 'statistics-interval'
+ backup: true
+ state: absent
+ notify: reload unbound
+ when: not collectd_plugin_exec_dns_stats
+ tags:
+ - collectd
+
+- name: Add doas configuration for dns_stats.sh execution
+ lineinfile:
+ path: /etc/doas.conf
+ line: 'permit nopass _collectd as root cmd /bin/cat'
+ when: collectd_plugin_exec_dns_stats
+ tags:
+ - collectd
+
+- name: Delete doas configuration for dns_stats.sh execution
+ lineinfile:
+ path: /etc/doas.conf
+ line: 'permit nopass _collectd as root cmd /bin/cat'
+ state: absent
+ when: not collectd_plugin_exec_dns_stats
+ tags:
+ - collectd
diff --git a/roles/collectd/templates/collectd.conf.j2 b/roles/collectd/templates/collectd.conf.j2
new file mode 100644
index 0000000..2cae0ac
--- /dev/null
+++ b/roles/collectd/templates/collectd.conf.j2
@@ -0,0 +1,122 @@
+Interval {{ collectd_interval }}
+Timeout 2
+
+LoadPlugin syslog
+
+ LogLevel warning
+
+
+{% if (collectd_plugin_exec_ifq_drops is sameas true) or (collectd_plugin_exec_dns_stats is sameas true) %}
+
+ Interval {{ collectd_plugin_exec_interval }}
+
+
+
+{% if collectd_plugin_exec_ifq_drops is sameas true %}
+ Exec "_collectd" "/usr/local/share/collectd/scripts/ifq_drops.sh"
+{% endif %}
+{% if collectd_plugin_exec_dns_stats is sameas true %}
+ Exec "_collectd" "/usr/local/share/collectd/scripts/dns_stats.sh"
+{% endif %}
+
+
+{% endif %}
+{% if collectd_plugin_load is sameas true %}
+LoadPlugin load
+{% endif %}
+{% if collectd_plugin_processes is sameas true %}
+LoadPlugin processes
+{% endif %}
+{% if collectd_plugin_uptime is sameas true %}
+LoadPlugin uptime
+{% endif %}
+{% if collectd_plugin_users is sameas true %}
+LoadPlugin users
+{% endif %}
+{% if collectd_plugin_pf is sameas true %}
+LoadPlugin pf
+{% endif %}
+
+{% if collectd_plugin_df is sameas true %}
+LoadPlugin df
+
+ # expose host's mounts into container using -v /:/host:ro (location inside container does not matter much)
+ # ignore rootfs; else, the root file-system would appear twice, causing
+ # one of the updates to fail and spam the log
+ ## Seems to be fixed with collectd 5.5+
+ ## FSType rootfs
+ # ignore the usual virtual / temporary file-systems
+ FSType sysfs
+ FSType proc
+ FSType devtmpfs
+ FSType devpts
+ FSType tmpfs
+ FSType fusectl
+ FSType cgroup
+ FSType overlay
+ FSType debugfs
+ FSType pstore
+ FSType securityfs
+ FSType hugetlbfs
+ FSType squashfs
+ FSType mqueue
+ IgnoreSelected true
+
+ ReportByDevice false
+ ReportInodes true # Default false
+ ValuesAbsolute true
+ ValuesPercentage true
+
+
+{% endif %}
+{% if collectd_plugin_disk is sameas true %}
+LoadPlugin disk
+
+ #Disk "/^[hsv]d[a-z]/"
+ IgnoreSelected false
+
+
+{% endif %}
+{% if collectd_plugin_cpu is sameas true %}
+LoadPlugin cpu
+
+ ValuesPercentage true
+
+
+{% endif %}
+{% if collectd_plugin_memory is sameas true %}
+LoadPlugin memory
+
+ ValuesPercentage true
+
+
+{% endif %}
+{% if collectd_plugin_swap is sameas true %}
+LoadPlugin swap
+
+ ValuesPercentage true
+
+
+{% endif %}
+{% if collectd_plugin_interface is sameas true %}
+LoadPlugin interface
+
+ Interface "/^lo[0-9]*/"
+ Interface "/^veth.*/"
+ Interface "/^docker.*/"
+ IgnoreSelected true
+ ReportInactive false
+
+
+{% endif %}
+{% if collectd_plugin_tcpconns is sameas true %}
+LoadPlugin tcpconns
+
+ AllPortsSummary true
+
+
+{% endif %}
+LoadPlugin network
+
+ Server "{{ collectd_server }}" "25826"
+