diff --git a/collectd/Dockerfile b/collectd/Dockerfile new file mode 100644 index 0000000..88f01f8 --- /dev/null +++ b/collectd/Dockerfile @@ -0,0 +1,43 @@ +FROM debian:bookworm + +ENV DEBIAN_FRONTEND=noninteractive +ENV TIMEZONE=Europe/Amsterdam + +RUN apt update --fix-missing +RUN apt dist-upgrade -y --no-install-recommends + +RUN echo $TIMEZONE > /etc/timezone +RUN dpkg-reconfigure -f noninteractive tzdata + +RUN apt install -y libsensors5 liblzo2-2 collectd btrfs-progs libatasmart4 speedtest-cli + +RUN apt install -y smartmontools + +RUN apt install -y wget git + +ENV HDDTEMP_VERSION=0.3.1 +RUN wget https://github.com/slowpeek/hddtemp/archive/refs/tags/${HDDTEMP_VERSION}.tar.gz \ + && tar xvf ${HDDTEMP_VERSION}.tar.gz && mv hddtemp-${HDDTEMP_VERSION}/hddtemp-lt /usr/sbin/hddtemp + +RUN apt -y install make g++ python3 python3-dev python3-pybind11 cmake + +COPY PMT /pmt +#RUN git clone https://git.astron.nl:/RD/pmt +RUN cmake -Spmt -Bpmt/build -DPMT_BUILD_RAPL=1 -DPMT_BUILD_BINARY=1 -DPMT_BUILD_PYTHON=1 -DCMAKE_INSTALL_PREFIX=/opt/pmt +RUN make -Cpmt/build -j install +ENV LD_LIBRARY_PATH="/opt/pmt/lib" +ENV PYTHONPATH="/opt/pmt/lib/python3.11/site-packages" +ENV PATH="$PATH:/opt/pmt/bin" +RUN apt -y remove make g++ python3-dev python3-pybind11 cmake +RUN apt autoremove -y + +RUN apt -y install sudo +RUN adduser collectd +RUN usermod -aG sudo collectd +RUN echo 'collectd ALL=(ALL) NOPASSWD:ALL' | sudo tee /etc/sudoers.d/collectd + + +RUN apt install -y --no-install-recommends python3-pip +RUN pip install --break-system-packages requests + +CMD ["/usr/sbin/collectd", "-f"] diff --git a/collectd/docker/Dockerfile.bookworm b/collectd/docker/Dockerfile.bookworm deleted file mode 100644 index 8760e79..0000000 --- a/collectd/docker/Dockerfile.bookworm +++ /dev/null @@ -1,35 +0,0 @@ -FROM debian:bookworm - -ENV LC_ALL=C -ENV DEBIAN_FRONTEND=noninteractive -ENV TIMEZONE=Europe/Amsterdam - -RUN apt update -RUN apt dist-upgrade -y --no-install-recommends - -RUN echo $TIMEZONE > /etc/timezone -RUN dpkg-reconfigure -f noninteractive tzdata - -RUN apt install -y libsensors5 liblzo2-2 collectd sudo btrfs-progs libatasmart4 speedtest-cli - -RUN apt install -y smartmontools - -RUN apt install -y wget git - -ENV HDDTEMP_VERSION=0.2.4 -RUN wget https://github.com/slowpeek/hddtemp/archive/refs/tags/${HDDTEMP_VERSION}.tar.gz \ - && tar xvf ${HDDTEMP_VERSION}.tar.gz && mv hddtemp-${HDDTEMP_VERSION}/hddtemp-lt /usr/sbin/hddtemp - -RUN apt install -y gcc python3-dev make -RUN git clone https://github.com/RRZE-HPC/likwid.git -RUN cd likwid && make -j && make install -RUN git clone https://github.com/RRZE-HPC/pylikwid.git -RUN cd pylikwid && python3 setup.py build_ext && python3 setup.py install -RUN apt remove -y gcc python-dev make -RUN apt autoremove -y - -RUN useradd collectd -RUN usermod -aG sudo collectd -RUN echo 'collectd ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers.d/collectd - -CMD /usr/sbin/collectd -f diff --git a/collectd/docker/Dockerfile.buster b/collectd/docker/Dockerfile.buster deleted file mode 100644 index eaca4a1..0000000 --- a/collectd/docker/Dockerfile.buster +++ /dev/null @@ -1,31 +0,0 @@ -FROM debian:buster - -ENV LC_ALL=C -ENV DEBIAN_FRONTEND=noninteractive -ENV TIMEZONE=Europe/Amsterdam - -RUN apt update -RUN apt dist-upgrade -y --no-install-recommends - -RUN echo $TIMEZONE > /etc/timezone -RUN dpkg-reconfigure -f noninteractive tzdata - -RUN apt install -y software-properties-common gpgv dirmngr psmisc wget curl python3-pip git gawk zip gperf unzip lbzip2 inetutils-ping inetutils-telnet rsync - -RUN pip3 install argparse - -RUN apt install -y libsensors5 liblzo2-2 hddtemp collectd sudo btrfs-progs libatasmart4 speedtest-cli - -RUN useradd collectd -RUN usermod -aG sudo collectd -RUN echo 'collectd ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers.d/collectd - -RUN apt install -y gcc python-dev make -RUN git clone https://github.com/RRZE-HPC/likwid.git -RUN cd likwid && make -j && make install -RUN git clone https://github.com/RRZE-HPC/pylikwid.git -RUN cd pylikwid && python setup.py build_ext && python setup.py install - -ENV LD_LIBRARY_PATH /usr/local/lib - -CMD /usr/sbin/collectd -f diff --git a/collectd/etc/collectd.conf b/collectd/etc/collectd.conf index 6b749a1..7af003b 100644 --- a/collectd/etc/collectd.conf +++ b/collectd/etc/collectd.conf @@ -12,12 +12,11 @@ # Global settings for the daemon. # ############################################################################## -Hostname "server" +Hostname "shuttle" FQDNLookup true #BaseDir "/var/lib/collectd" #PluginDir "/usr/lib/collectd" -#TypesDB "/usr/share/collectd/types.db" "/etc/collectd/my_types.db" - +#TypesDB "/usr/share/collectd/types.db" "/etc/collectd/my_types.db" #----------------------------------------------------------------------------# # When enabled, plugins are loaded automatically with the default options # # when an appropriate block is encountered. # @@ -32,7 +31,7 @@ FQDNLookup true # Interval 60 # # # #----------------------------------------------------------------------------# -#Interval 10 +Interval 10 #Timeout 2 #ReadThreads 5 @@ -52,120 +51,38 @@ FQDNLookup true ############################################################################## LoadPlugin logfile -#LoadPlugin syslog LogLevel "info" File "/var/lib/collectd/log/collectd.log" Timestamp true - PrintSeverity false + PrintSeverity true -# -# LogLevel info -# - ############################################################################## # LoadPlugin section # #----------------------------------------------------------------------------# # Specify what features to activate. # ############################################################################## -#LoadPlugin aggregation -#LoadPlugin amqp -#LoadPlugin apache -#LoadPlugin apcups -#LoadPlugin ascent -#LoadPlugin battery -#LoadPlugin bind -#LoadPlugin cgroups -#LoadPlugin conntrack -#LoadPlugin contextswitch LoadPlugin cpu LoadPlugin cpufreq -#LoadPlugin csv -#LoadPlugin curl -#LoadPlugin curl_json -#LoadPlugin curl_xml -#LoadPlugin dbi LoadPlugin df LoadPlugin disk -#LoadPlugin dns -#LoadPlugin email LoadPlugin entropy -#LoadPlugin ethstat -#LoadPlugin exec -#LoadPlugin filecount -#LoadPlugin fscache -#LoadPlugin gmond -#LoadPlugin hddtemp -LoadPlugin interface -#LoadPlugin ipmi -#LoadPlugin iptables -#LoadPlugin ipvs +#LoadPlugin interface #LoadPlugin irq -#LoadPlugin java -#LoadPlugin libvirt LoadPlugin load -#LoadPlugin lvm -#LoadPlugin madwifi -#LoadPlugin mbmon LoadPlugin md -#LoadPlugin memcachec -#LoadPlugin memcached LoadPlugin memory -#LoadPlugin modbus -#LoadPlugin multimeter -#LoadPlugin mysql -#LoadPlugin netlink LoadPlugin network -LoadPlugin nfs -#LoadPlugin nginx -#LoadPlugin notify_desktop -#LoadPlugin notify_email -#LoadPlugin ntpd -#LoadPlugin numa -#LoadPlugin nut -#LoadPlugin olsrd -#LoadPlugin openvpn -# -# Globals true -# -#LoadPlugin pinba -#LoadPlugin ping -#LoadPlugin postgresql -#LoadPlugin powerdns LoadPlugin processes -#LoadPlugin protocols -# -# Globals true -# -#LoadPlugin rrdcached LoadPlugin rrdtool LoadPlugin sensors -#LoadPlugin serial -#LoadPlugin snmp -#LoadPlugin statsd LoadPlugin swap -#LoadPlugin table -#LoadPlugin tail -#LoadPlugin tail_csv -#LoadPlugin tcpconns -#LoadPlugin teamspeak2 -#LoadPlugin ted -#LoadPlugin thermal -#LoadPlugin tokyotyrant -#LoadPlugin unixsock LoadPlugin uptime LoadPlugin users -#LoadPlugin uuid -#LoadPlugin varnish -#LoadPlugin vmem -#LoadPlugin vserver -#LoadPlugin wireless -#LoadPlugin write_graphite -#LoadPlugin write_http -#LoadPlugin write_riemann +LoadPlugin smart ############################################################################## # Plugin configuration # @@ -174,640 +91,6 @@ LoadPlugin users # ription of those options is available in the collectd.conf(5) manual page. # ############################################################################## -# -# -# #Host "unspecified" -# Plugin "cpu" -# PluginInstance "/[0,2,4,6,8]$/" -# Type "cpu" -# #TypeInstance "unspecified" -# -# SetPlugin "cpu" -# SetPluginInstance "even-%{aggregation}" -# -# GroupBy "Host" -# GroupBy "TypeInstance" -# -# CalculateNum false -# CalculateSum false -# CalculateAverage true -# CalculateMinimum false -# CalculateMaximum false -# CalculateStddev false -# -# - -# -# -# Host "localhost" -# Port "5672" -# VHost "/" -# User "guest" -# Password "guest" -# Exchange "amq.fanout" -# RoutingKey "collectd" -# Persistent false -# StoreRates false -# -# - -# -# -# URL "http://localhost/server-status?auto" -# User "www-user" -# Password "secret" -# VerifyPeer false -# VerifyHost false -# CACert "/etc/ssl/ca.crt" -# Server "apache" -# -# -# -# URL "http://some.domain.tld/status?auto" -# Host "some.domain.tld" -# Server "lighttpd" -# -# - -# -# Host "localhost" -# Port "3551" -# ReportSeconds true -# - -# -# URL "http://localhost/ascent/status/" -# User "www-user" -# Password "secret" -# VerifyPeer false -# VerifyHost false -# CACert "/etc/ssl/ca.crt" -# - -# -# URL "http://localhost:8053/" -# -# ParseTime false -# -# OpCodes true -# QTypes true -# ServerStats true -# ZoneMaintStats true -# ResolverStats false -# MemoryStats true -# -# -# QTypes true -# ResolverStats true -# CacheRRSets true -# -# Zone "127.in-addr.arpa/IN" -# -# - -# -# CGroup "libvirt" -# IgnoreSelected false -# - -# -# DataDir "/var/lib/collectd/csv" -# StoreRates false -# - -# -# -# URL "http://finance.google.com/finance?q=NYSE%3AAMD" -# User "foo" -# Password "bar" -# VerifyPeer false -# VerifyHost false -# CACert "/etc/ssl/ca.crt" -# MeasureResponseTime false -# -# Regex "]*> *([0-9]*\\.[0-9]+) *" -# DSType "GaugeAverage" -# Type "stock_value" -# Instance "AMD" -# -# -# - -# -## See: http://wiki.apache.org/couchdb/Runtime_Statistics -# -# Instance "httpd" -# -# Type "http_requests" -# -# -# -# Type "http_request_methods" -# -# -# -# Type "http_response_codes" -# -# -## Database status metrics: -# -# Instance "dbs" -# -# Type "gauge" -# -# -# Type "counter" -# -# -# Type "bytes" -# -# -# - -# -# -# Host "my_host" -# Instance "some_instance" -# User "collectd" -# Password "thaiNg0I" -# VerifyPeer true -# VerifyHost true -# CACert "/path/to/ca.crt" -# -# -# Type "magic_level" -# InstancePrefix "prefix-" -# InstanceFrom "td[1]" -# ValuesFrom "td[2]/span[@class=\"level\"]" -# -# -# - -# -# -# Statement "SELECT 'customers' AS c_key, COUNT(*) AS c_value \ -# FROM customers_tbl" -# MinVersion 40102 -# MaxVersion 50042 -# -# Type "gauge" -# InstancePrefix "customer" -# InstancesFrom "c_key" -# ValuesFrom "c_value" -# -# -# -# -# Driver "mysql" -# DriverOption "host" "localhost" -# DriverOption "username" "collectd" -# DriverOption "password" "secret" -# DriverOption "dbname" "custdb0" -# SelectDB "custdb0" -# Query "num_of_customers" -# Query "..." -# Host "..." -# -# - -# -# Disk "hda" -# Disk "/sda[23]/" -# IgnoreSelected false -# - -# -# Interface "eth0" -# IgnoreSource "192.168.0.1" -# SelectNumericQueryTypes false -# - -# -# SocketFile "/var/run/collectd-email" -# SocketGroup "collectd" -# SocketPerms "0770" -# MaxConns 5 -# - -# -# Interface "eth0" -# Map "rx_csum_offload_errors" "if_rx_errors" "checksum_offload" -# Map "multicast" "if_multicast" -# MappedOnly false -# - -# -# Exec user "/path/to/exec" -# Exec "user:group" "/path/to/exec" -# NotificationExec user "/path/to/exec" -# - -# -# -# Instance "foodir" -# Name "*.conf" -# MTime "-5m" -# Size "+10k" -# Recursive true -# IncludeHidden false -# -# - -# -# MCReceiveFrom "239.2.11.71" "8649" -# -# -# Type "swap" -# TypeInstance "total" -# DataSource "value" -# -# -# -# Type "swap" -# TypeInstance "free" -# DataSource "value" -# -# - -# -# Host "127.0.0.1" -# Port 7634 -# - -# -# Interface "eth0" -# IgnoreSelected false -# - - Interface "veth*" - IgnoreSelected true - - -# -# Sensor "some_sensor" -# Sensor "another_one" -# IgnoreSelected false -# NotifySensorAdd false -# NotifySensorRemove true -# NotifySensorNotPresent false -# - -# -# Chain "table" "chain" -# - -# -# Irq 7 -# Irq 8 -# Irq 9 -# IgnoreSelected true -# - -# -# JVMArg "-verbose:jni" -# JVMArg "-Djava.class.path=/usr/share/collectd/java/collectd-api.jar" -# -# LoadPlugin "org.collectd.java.GenericJMX" -# -# # See /usr/share/doc/collectd/examples/GenericJMX.conf -# # for an example config. -# -# - -# -# Connection "xen:///" -# RefreshInterval 60 -# Domain "name" -# BlockDevice "name:device" -# InterfaceDevice "name:device" -# IgnoreSelected false -# HostnameFormat name -# InterfaceFormat name -# - -# -# Interface "wlan0" -# IgnoreSelected false -# Source "SysFS" -# WatchSet "None" -# WatchAdd "node_octets" -# WatchAdd "node_rssi" -# WatchAdd "is_rx_acl" -# WatchAdd "is_scan_active" -# - -# -# Host "127.0.0.1" -# Port 411 -# - -# -# Device "/dev/md0" -# IgnoreSelected false -# - -# -# -# Server "localhost" -# Key "page_key" -# -# Regex "(\\d+) bytes sent" -# ExcludeRegex "" -# DSType CounterAdd -# Type "ipt_octets" -# Instance "type_instance" -# -# -# - -# -# -# Socket "/var/run/memcached.sock" -# or: -# Host "127.0.0.1" -# Port "11211" -# -# - -# -# -# RegisterBase 1234 -# RegisterType float -# Type gauge -# Instance "..." -# -# -# -# Address "addr" -# Port "1234" -# Interval 60 -# -# -# Instance "foobar" # optional -# Collect "data_name" -# -# -# - -# -# -# Host "database.serv.er" -# Port "3306" -# User "db_user" -# Password "secret" -# Database "db_name" -# MasterStats true -# -# -# -# Host "localhost" -# Socket "/var/run/mysql/mysqld.sock" -# SlaveStats true -# SlaveNotifications true -# -# - -# -# Interface "All" -# VerboseInterface "All" -# QDisc "eth0" "pfifo_fast-1:0" -# Class "ppp0" "htb-1:10" -# Filter "ppp0" "u32-1:0" -# IgnoreSelected false -# - -# -# # client setup: -# Server "ff18::efc0:4a42" "25826" -# -# SecurityLevel Encrypt -# Username "user" -# Password "secret" -# Interface "eth0" -# -# TimeToLive "128" -# -# # server setup: -# Listen "ff18::efc0:4a42" "25826" -# -# SecurityLevel Sign -# AuthFile "/etc/collectd/passwd" -# Interface "eth0" -# -# MaxPacketSize 1024 -# -# # proxy setup (client and server as above): -# Forward true -# -# # statistics about the network plugin itself -# ReportStats false -# -# # "garbage collection" -# CacheFlush 1800 -# - -# -# URL "http://localhost/status?auto" -# User "www-user" -# Password "secret" -# VerifyPeer false -# VerifyHost false -# CACert "/etc/ssl/ca.crt" -# - -# -# OkayTimeout 1000 -# WarningTimeout 5000 -# FailureTimeout 0 -# - -# -# SMTPServer "localhost" -# SMTPPort 25 -# SMTPUser "my-username" -# SMTPPassword "my-password" -# From "collectd@main0server.com" -# # on . -# # Beware! Do not use not more than two placeholders (%)! -# Subject "[collectd] %s on %s!" -# Recipient "email1@domain1.net" -# Recipient "email2@domain2.com" -# - -# -# Host "localhost" -# Port 123 -# ReverseLookups false -# IncludeUnitID true -# - -# -# UPS "upsname@hostname:port" -# - -# -# Host "127.0.0.1" -# Port "2006" -# CollectLinks "Summary" -# CollectRoutes "Summary" -# CollectTopology "Summary" -# - -# -# StatusFile "/etc/openvpn/openvpn-status.log" -# ImprovedNamingSchema false -# CollectCompression true -# CollectIndividualUsers true -# CollectUserCount false -# - -# -# IncludeDir "/my/include/path" -# BaseName "Collectd::Plugins" -# EnableDebugger "" -# LoadPlugin Monitorus -# LoadPlugin OpenVZ -# -# -# Foo "Bar" -# Qux "Baz" -# -# - -# -# Address "::0" -# Port "30002" -# -# Host "host name" -# Server "server name" -# Script "script name" -# -# - -# -# Host "host.foo.bar" -# Host "host.baz.qux" -# Interval 1.0 -# Timeout 0.9 -# TTL 255 -# SourceAddress "1.2.3.4" -# Device "eth0" -# MaxMissed -1 -# - -# -# -# Statement "SELECT magic FROM wizard WHERE host = $1;" -# Param hostname -# -# -# Type gauge -# InstancePrefix "magic" -# ValuesFrom "magic" -# -# -# -# -# Statement "SELECT COUNT(type) AS count, type \ -# FROM (SELECT CASE \ -# WHEN resolved = 'epoch' THEN 'open' \ -# ELSE 'resolved' END AS type \ -# FROM tickets) type \ -# GROUP BY type;" -# -# -# Type counter -# InstancePrefix "rt36_tickets" -# InstancesFrom "type" -# ValuesFrom "count" -# -# -# -# -# # See /usr/share/doc/collectd-core/examples/postgresql/collectd_insert.sql for details -# Statement "SELECT collectd_insert($1, $2, $3, $4, $5, $6, $7, $8, $9);" -# StoreRates true -# -# -# -# Host "hostname" -# Port 5432 -# User "username" -# Password "secret" -# -# SSLMode "prefer" -# KRBSrvName "kerberos_service_name" -# -# Query magic -# -# -# -# Interval 60 -# Service "service_name" -# -# Query backend # predefined -# Query rt36_tickets -# -# -# -# Service "collectd_store" -# Writer sqlstore -# # see collectd.conf(5) for details -# CommitInterval 30 -# -# - -# -# -# Collect "latency" -# Collect "udp-answers" "udp-queries" -# Socket "/var/run/pdns.controlsocket" -# -# -# Collect "questions" -# Collect "cache-hits" "cache-misses" -# Socket "/var/run/pdns_recursor.controlsocket" -# -# LocalSocket "/opt/collectd/var/run/collectd-powerdns" -# - -# -# Process "name" -# ProcessMatch "foobar" "/usr/bin/perl foobar\\.pl.*" -# - -# -# Value "/^Tcp:/" -# IgnoreSelected false -# - -# -# ModulePath "/path/to/your/python/modules" -# LogTraces true -# Interactive true -# Import "spam" -# -# -# spam "wonderful" "lovely" -# -# - -# -# DaemonAddress "unix:/var/run/rrdcached.sock" -# DataDir "/var/lib/rrdcached/db/collectd" -# CreateFiles true -# CreateFilesAsync false -# CollectStatistics true -# -# The following settings are rather advanced -# and should usually not be touched: -# StepSize 10 -# HeartBeat 20 -# RRARows 1200 -# RRATimespan 158112000 -# XFF 0.1 -# - DataDir "/var/lib/collectd/rrd" # CacheTimeout 120 @@ -825,250 +108,24 @@ LoadPlugin users # XFF 0.1 -# -# SensorConfigFile "/etc/sensors3.conf" -# Sensor "it8712-isa-0290/temperature-temp1" -# Sensor "it8712-isa-0290/fanspeed-fan3" -# Sensor "it8712-isa-0290/voltage-in8" -# IgnoreSelected false + + Disk "sda" + Disk "sdb" + Disk "nvme0" + IgnoreSelected false + + +# +# Device "/dev/md0" +# IgnoreSelected false # -# See /usr/share/doc/collectd/examples/snmp-data.conf.gz for a -# comprehensive sample configuration. -# -# -# Type "voltage" -# Table false -# Instance "input_line1" -# Scale 0.1 -# Values "SNMPv2-SMI::enterprises.6050.5.4.1.1.2.1" -# -# -# Type "users" -# Table false -# Instance "" -# Shift -1 -# Values "HOST-RESOURCES-MIB::hrSystemNumUsers.0" -# -# -# Type "if_octets" -# Table true -# InstancePrefix "traffic" -# Instance "IF-MIB::ifDescr" -# Values "IF-MIB::ifInOctets" "IF-MIB::ifOutOctets" -# -# -# -# Address "192.168.0.2" -# Version 1 -# Community "community_string" -# Collect "std_traffic" -# Inverval 120 -# -# -# Address "192.168.0.42" -# Version 2 -# Community "another_string" -# Collect "std_traffic" "hr_users" -# -# -# Address "192.168.0.3" -# Version 1 -# Community "more_communities" -# Collect "powerplus_voltge_input" -# Interval 300 -# -# - -# -# Host "::" -# Port "8125" -# DeleteCounters false -# DeleteTimers false -# DeleteGauges false -# DeleteSets false -# TimerPercentile 90.0 -# - -# -# ReportByDevice false -# ReportBytes true -# - -# -# -# Instance "slabinfo" -# Separator " " -# -# Type gauge -# InstancePrefix "active_objs" -# InstancesFrom 0 -# ValuesFrom 1 -# -# -# Type gauge -# InstancePrefix "objperslab" -# InstancesFrom 0 -# ValuesFrom 4 -# -#
-#
- -# -# -# Instance "exim" -# -# Regex "S=([1-9][0-9]*)" -# DSType "CounterAdd" -# Type "ipt_bytes" -# Instance "total" -# -# -# Regex "\\" -# ExcludeRegex "\\.*mail_spool defer" -# DSType "CounterInc" -# Type "counter" -# Instance "local_user" -# -# -# - -# -# -# Type "percent" -# Instance "dropped" -# ValueFrom 1 -# -# -# Type "bytes" -# Instance "wire-realtime" -# ValueFrom 2 -# -# -# Type "alerts_per_second" -# ValueFrom 3 -# -# -# Type "kpackets_wire_per_sec.realtime" -# ValueFrom 4 -# -# -# Instance "snort-eth0" -# Interval 600 -# Collect "dropped" "mbps" "alerts" "kpps" -# TimeFrom 0 -# -# - -# -# ListeningPorts false -# LocalPort "25" -# RemotePort "25" -# - -# -# Host "127.0.0.1" -# Port "51234" -# Server "8767" -# - -# -# Device "/dev/ttyUSB0" -# Retries 0 -# - -# -# ForceUseProcfs false -# Device "THRM" -# IgnoreSelected false -# - -# -# Host "localhost" -# Port "1978" -# - -# -# SocketFile "/var/run/collectd-unixsock" -# SocketGroup "collectd" -# SocketPerms "0660" -# DeleteSocket false -# - -# -# UUIDFile "/etc/uuid" -# - -# -# -# CollectCache true -# CollectBackend true -# CollectBan false # Varnish 3 only -# CollectConnections true -# CollectDirectorDNS false # Varnish 3 only -# CollectSHM true -# CollectESI false -# CollectFetch false -# CollectHCB false -# CollectObjects false -# CollectPurge false # Varnish 2 only -# CollectSession false -# CollectSMA false # Varnish 2 only -# CollectSMS false -# CollectSM false # Varnish 2 only -# CollectStruct false -# CollectTotals false -# CollectUptime false -# CollectdVCL false -# CollectWorkers false -# -# -# -# CollectCache true -# -# - -# -# Verbose false -# - -# -# -# Host "localhost" -# Port "2003" -# Protocol "udp" -# LogSendErrors true -# Prefix "collectd" -# Postfix "collectd" -# StoreRates true -# AlwaysAppendDS false -# EscapeCharacter "_" -# -# - -# -# -# User "collectd" -# Password "secret" -# VerifyPeer true -# VerifyHost true -# CACert "/etc/ssl/ca.crt" -# Format "Command" -# StoreRates false -# -# - -# -# -# Host "localhost" -# Port 5555 -# Protocol UDP -# StoreRates true -# AlwaysAppendDS false -# TTLFactor 2.0 -# -# Tag "foobar" -# + + Disk "sda" + Disk "sdb" + Disk "nvme0" + IgnoreSelected false + Filter "*.conf" diff --git a/collectd/etc/collectd.conf.d/btrfs-data.conf b/collectd/etc/collectd.conf.d/btrfs-data.conf index 5c70041..3e8fe80 100644 --- a/collectd/etc/collectd.conf.d/btrfs-data.conf +++ b/collectd/etc/collectd.conf.d/btrfs-data.conf @@ -1,6 +1,5 @@ LoadPlugin exec - Exec collectd "/host/usr/local/bin/btrfs-data" + Exec collectd "/host/usr/local/bin/btrfs-data" - diff --git a/collectd/etc/collectd.conf.d/cpufreq-data.conf b/collectd/etc/collectd.conf.d/cpufreq-data.conf new file mode 100644 index 0000000..f3b1e15 --- /dev/null +++ b/collectd/etc/collectd.conf.d/cpufreq-data.conf @@ -0,0 +1,5 @@ +LoadPlugin exec + + + Exec collectd "/host/usr/local/bin/cpufreq-data" + diff --git a/collectd/etc/collectd.conf.d/df.conf b/collectd/etc/collectd.conf.d/df.conf index a6a903d..594f9ee 100644 --- a/collectd/etc/collectd.conf.d/df.conf +++ b/collectd/etc/collectd.conf.d/df.conf @@ -1,6 +1,5 @@ - - MountPoint "/mnt/due" - MountPoint "/mnt/quattro" - MountPoint "/mnt/mezzo/var/lib/docker" + + MountPoint "/media/docker" + FSType "ext4" + IgnoreSelected false - diff --git a/collectd/etc/collectd.conf.d/du-data.conf b/collectd/etc/collectd.conf.d/du-data.conf index cc064d3..3382f7b 100644 --- a/collectd/etc/collectd.conf.d/du-data.conf +++ b/collectd/etc/collectd.conf.d/du-data.conf @@ -1,6 +1,5 @@ LoadPlugin exec - Exec collectd "/host/usr/local/bin/du-data" + Exec collectd "/host/usr/local/bin/du-data" - diff --git a/collectd/etc/collectd.conf.d/speedtest-data.conf b/collectd/etc/collectd.conf.d/speedtest-data.conf index 5d33a5a..1902744 100644 --- a/collectd/etc/collectd.conf.d/speedtest-data.conf +++ b/collectd/etc/collectd.conf.d/speedtest-data.conf @@ -1,6 +1,5 @@ LoadPlugin exec - Exec nobody "/host/usr/local/bin/speedtest-data" + Exec nobody "/host/usr/local/bin/speedtest-data" - diff --git a/collectd/usr/local/bin/btrfs-data b/collectd/usr/local/bin/btrfs-data index cd33608..d6ff53c 100755 --- a/collectd/usr/local/bin/btrfs-data +++ b/collectd/usr/local/bin/btrfs-data @@ -1,18 +1,20 @@ -#!/usr/bin/python -u +#!/usr/bin/python3 # # Imports # import sys import time -import commands +import subprocess import argparse +#sys.exit(1) + # # Misc # -#sys.tracebacklimit = 0 +# sys.tracebacklimit = 0 # @@ -28,26 +30,27 @@ size_snapshot_exclusive = 0 # Methods # def get_subvol_list(path): - command = 'sudo btrfs subvolume list -t %s' % (path) - status, output = commands.getstatusoutput(command) + command = "sudo btrfs subvolume list -t %s" % (path) + status, output = subprocess.getstatusoutput(command) - if status is not 0: + if status != 0: raise Exception(command) # Every line contains the following values: subvol_id, gen, toplevel, path return output.splitlines()[2:] -def get_filesystem_size(path): - command = 'sudo btrfs filesystem show --raw %s' % (path) - status, output = commands.getstatusoutput(command) - if status is not 0 or True: +def get_filesystem_size(path): + command = "sudo btrfs filesystem show --raw %s" % (path) + status, output = subprocess.getstatusoutput(command) + + if status != 0: # This command fails when running inside Docker container # return maximum size of any filesystem instead - command = 'sudo btrfs filesystem show --raw' - status, output = commands.getstatusoutput(command) + command = "sudo btrfs filesystem show --raw" + status, output = subprocess.getstatusoutput(command) lines = output.splitlines() - lines = filter(lambda x: 'devid' in x, lines) + lines = [x for x in lines if "devid" in x] sizes = [int(line.split()[3]) for line in lines] return max(sizes) @@ -57,11 +60,12 @@ def get_filesystem_size(path): # Element 3 and 5 respectively contain total and used sizes return int(line.split()[3]) + def get_id_root(name, path): lines = get_subvol_list(path) # Filter lines where toplevel == 5 - subvol_ids = filter(lambda x: int(x.split()[2]) == 5, lines) + subvol_ids = [x for x in lines if int(x.split()[2]) == 5] # Try to retrieve the subvol_id for the root subvolume (if any) if len(subvol_ids) == 1: @@ -70,18 +74,18 @@ def get_id_root(name, path): else: # The path contains a btrfs filesystem with multiple subvolumes for data try: - return int(filter(lambda x: x.split()[3] == name, subvol_ids)[0].split()[0]) + return int(list(filter(lambda x: x.split()[3] == name, subvol_ids))[0].split()[0]) except IndexError: pass - # Volume not found, root is probably the btrfs default (5) return 5 - + + def get_id_subvolumes(path, subvol_id): lines = get_subvol_list(path) - lines = filter(lambda x: int(x.split()[2]) == subvol_id, lines) - return list(map(lambda x: int(x.split()[0]), lines)) + lines = [x for x in lines if int(x.split()[2]) == subvol_id] + return list([int(x.split()[0]) for x in lines]) def get_disk_usage(name, path): @@ -90,10 +94,10 @@ def get_disk_usage(name, path): size_filesystem = get_filesystem_size(path) # Get disk usage from quota - command = 'sudo btrfs qgroup show --raw %s' % (path) - status, output = commands.getstatusoutput(command) + command = "sudo btrfs qgroup show --raw %s" % (path) + status, output = subprocess.getstatusoutput(command) - if status is not 0: + if status != 0: raise Exception(command) lines = output.splitlines()[2:] @@ -125,11 +129,11 @@ def get_disk_usage(name, path): size_total = 0 size_exclusive = 0 try: - subvol_id = int(split[0].split('/')[1]) + subvol_id = int(split[0].split("/")[1]) size_total = float(split[1]) size_exclusive = float(split[2]) except IndexError: - # ignore 'WARNING: Quota disabled' + # ignore "WARNING: Quota disabled" pass # size_exclusive is incorrect when snapshot is @@ -145,51 +149,83 @@ def get_disk_usage(name, path): size_snapshot_total += size_total size_snapshot_exclusive += size_exclusive + def rescan_quota(path): - command = 'sudo btrfs quota rescan %s' % (path) - status, output = commands.getstatusoutput(command) - if status is not 0: + command = "sudo btrfs quota rescan %s" % (path) + status, output = subprocess.getstatusoutput(command) + if status != 0: Exception(command) + def print_human_readable(name): global size_data_total global size_data_exclusive global size_snapshot_exclusive - size_data_total = size_data_total / (1024*1e6) - size_data_exclusive = size_data_exclusive / (1024*1e6) - size_snapshot_exclusive = size_snapshot_exclusive / (1024*1e6) - print '%10s: %6.1f Gb, %6.1f Gb, %6.1f Gb' % (name, size_data_total, size_data_exclusive, size_snapshot_exclusive) + size_data_total = size_data_total / (1024 * 1e6) + size_data_exclusive = size_data_exclusive / (1024 * 1e6) + size_snapshot_exclusive = size_snapshot_exclusive / (1024 * 1e6) + print( + "%10s: %6.1f Gb, %6.1f Gb, %6.1f Gb" + % (name, size_data_total, size_data_exclusive, size_snapshot_exclusive) + ) + def print_rrd(name): timestamp = int(time.time()) - print('PUTVAL {}/exec-btrfs_{}/gauge-data_total {}:{:.1f}'.format(hostname, name, timestamp, size_data_total)) - print('PUTVAL {}/exec-btrfs_{}/gauge-data_exclusive {}:{:.1f}'.format(hostname, name, timestamp, size_data_exclusive)) - print('PUTVAL {}/exec-btrfs_{}/gauge-snapshot_total {}:{:.1f}'.format(hostname, name, timestamp, size_snapshot_total)) - print('PUTVAL {}/exec-btrfs_{}/gauge-snapshot_exclusive {}:{:.1f}'.format(hostname, name, timestamp, size_snapshot_exclusive)) + print( + ( + "PUTVAL {}/exec-btrfs_{}/gauge-data_total {}:{:.1f}".format( + hostname, name, timestamp, size_data_total + ) + ) + ) + print( + ( + "PUTVAL {}/exec-btrfs_{}/gauge-data_exclusive {}:{:.1f}".format( + hostname, name, timestamp, size_data_exclusive + ) + ) + ) + print( + ( + "PUTVAL {}/exec-btrfs_{}/gauge-snapshot_total {}:{:.1f}".format( + hostname, name, timestamp, size_snapshot_total + ) + ) + ) + print( + ( + "PUTVAL {}/exec-btrfs_{}/gauge-snapshot_exclusive {}:{:.1f}".format( + hostname, name, timestamp, size_snapshot_exclusive + ) + ) + ) # # Volumes to scan # -hostname = 'server' +hostname = "shuttle" interval = 10 -volumes = [ - ['mezzo-scratch', '/mnt/mezzo/scratch'], - ['mezzo-sync', '/mnt/mezzo/sync'], - ['helium-personal', '/mnt/yotta/helium/personal'], - ['helium-shared', '/mnt/yotta/helium/shared'], - ['neon', '/mnt/yotta/neon'], - ['krypton', '/mnt/yotta/krypton'], - ['xenon-borg', '/mnt/yotta/xenon/borg'], - ['xenon-rsnapshot', '/mnt/yotta/xenon/rsnapshot'] -] +volumes = list() +# SSD +volumes.append(["scratch", "/host/root/mnt/mezzo/scratch"]) +volumes.append(["sync", "/host/root/mnt/mezzo/sync"]) + +# HDD +volumes.append(["personal", "/host/root/mnt/yotta/helium/personal"]) +volumes.append(["shared", "/host/root/mnt/yotta/helium/shared"]) +volumes.append(["neon", "/host/root/mnt/yotta/neon"]) +volumes.append(["krypton", "/host/root/mnt/yotta/krypton"]) +volumes.append(["borg", "/host/root/mnt/yotta/xenon/borg"]) +volumes.append(["rsnapshot", "/host/root/mnt/yotta/xenon/rsnapshot"]) # # Command line arguments # -parser = argparse.ArgumentParser(description='Get BTRFS disk usage') -parser.add_argument('-s', action='store_true', help='print in human readable format') +parser = argparse.ArgumentParser(description="Get BTRFS disk usage") +parser.add_argument("-s", action="store_true", help="print in human readable format") args = parser.parse_args() human_readable = args.s @@ -198,15 +234,17 @@ human_readable = args.s # Main # if human_readable: - for name, path in volumes: + for (name, path) in volumes: get_disk_usage(name, path) print_human_readable(name) else: # RRD mode while True: - for name, path in volumes: - get_disk_usage(name, path) + for (name, path) in volumes: + get_disk_usage(name, path) + print_rrd(name) + sys.stdout.flush() time.sleep(interval) - rescan_quota(path) + # rescan_quota(path) diff --git a/collectd/usr/local/bin/cpufreq-data b/collectd/usr/local/bin/cpufreq-data new file mode 100755 index 0000000..5a5ad30 --- /dev/null +++ b/collectd/usr/local/bin/cpufreq-data @@ -0,0 +1,58 @@ +#!/usr/bin/python3 + +import argparse +import time +import sys +import os + +hostname = "shuttle" +measurement_interval = 5 + + +def get_cpu_frequencies(): + frequencies = [] + try: + cpu_dirs = [ + d + for d in os.listdir("/sys/devices/system/cpu/") + if d.startswith("cpu") and d[3:].isdigit() + ] + for cpu_dir in cpu_dirs: + with open( + f"/sys/devices/system/cpu/{cpu_dir}/cpufreq/scaling_cur_freq", "r" + ) as f: + frequency = int(f.read().strip()) / 1000 # Convert Hz to MHz + frequencies.append((int(cpu_dir[3:]), frequency)) + except Exception as e: + print("Error:", e) + return frequencies + + +def main(): + parser = argparse.ArgumentParser(description="Query CPU frequencies.") + parser.add_argument( + "-s", + "--human-readable", + action="store_true", + help="Print frequencies in human-readable format", + ) + args = parser.parse_args() + + if args.human_readable: + frequencies = get_cpu_frequencies() + for cpu, frequency in frequencies: + print(f"CPU{cpu} Frequency: {frequency:.2f} MHz") + else: + while True: + frequencies = get_cpu_frequencies() + timestamp = int(time.time()) + for cpu, frequency in frequencies: + print( + f"PUTVAL {hostname}/cpu-frequency/gauge-cpu{cpu} {timestamp}:{frequency:.0f}" + ) + sys.stdout.flush() + time.sleep(measurement_interval) + + +if __name__ == "__main__": + main() diff --git a/collectd/usr/local/bin/du-data b/collectd/usr/local/bin/du-data index 68df7ad..b783b0c 100755 --- a/collectd/usr/local/bin/du-data +++ b/collectd/usr/local/bin/du-data @@ -1,12 +1,11 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Imports # -import os import sys import time -import commands +import subprocess import argparse @@ -14,13 +13,12 @@ import argparse # Methods # def get_disk_usage(path, human_readable): - '''disk usage in human readable format (e.g. '2,1GB')''' - arguments = '-sh' if human_readable else '-s' - path = os.path.realpath(path) - command = 'sudo du %s %s' % (arguments, path) - status, output = commands.getstatusoutput(command) + """disk usage in human readable format (e.g. '2,1GB')""" + arguments = "-sh" if human_readable else "-s" + command = "du %s %s" % (arguments, path) + status, output = subprocess.getstatusoutput(command) - if status is not 0: + if status != 0: raise Exception(command) disk_usage = output.split()[0] @@ -29,13 +27,13 @@ def get_disk_usage(path, human_readable): disk_usage = int(disk_usage) * 1024 return disk_usage + # # Directories to scan # -hostname = 'server' +hostname = 'shuttle' interval = 10 directories = [ - #['bram', '/media/data/Personal/Bram'], ['rik', '/media/data/Personal/Rik'], ['books', '/media/data/Shared/Books'], ['games', '/media/data/Shared/Games'], @@ -45,15 +43,14 @@ directories = [ ['music', '/media/data/Shared/Music'], ['photographs', '/media/data/Shared/Photographs'], ['pictures', '/media/data/Shared/Pictures'], - ['raw', '/media/data/Shared/Raw'], ['software', '/media/data/Shared/Software'] ] # # Command line arguments # -parser = argparse.ArgumentParser(description='Get BTRFS disk usage') -parser.add_argument('-s', action='store_true', help='print in human readable format') +parser = argparse.ArgumentParser(description="Get DU disk usage") +parser.add_argument("-s", action="store_true", help="print in human readable format") args = parser.parse_args() human_readable = args.s @@ -61,10 +58,10 @@ human_readable = args.s # # Main # -if (human_readable): +if human_readable: for (name, path) in directories: disk_usage = get_disk_usage(path, human_readable) - print('%s: %s' % (name, disk_usage)) + print(("%s: %s" % (name, disk_usage))) else: # RRD mode while True: @@ -72,6 +69,12 @@ else: disk_usage = get_disk_usage(path, human_readable) timestamp = int(time.time()) size = float(disk_usage) - print('PUTVAL {}/exec-du_{}/gauge-size {}:{:.1f}'.format(hostname, name, timestamp, size)) + print( + ( + "PUTVAL {}/exec-du_{}/gauge-size {}:{:.1f}".format( + hostname, name, timestamp, size + ) + ) + ) sys.stdout.flush() time.sleep(interval) diff --git a/collectd/usr/local/bin/funds-data b/collectd/usr/local/bin/funds-data index 8e5aeb8..0abe722 100755 --- a/collectd/usr/local/bin/funds-data +++ b/collectd/usr/local/bin/funds-data @@ -1,10 +1,11 @@ -#!/usr/bin/env python +#!/usr/bin/python3 + +import sys import os import requests import re import time import datetime -import sys import random collection = 'funds' @@ -55,7 +56,7 @@ def morningstar_ticker(funds): def put_value(fund, value, timestamp = 'N'): print('PUTVAL {}/exec-fund-{}/gauge-ticker interval={} {}:{}'.format(collection, fund, interval, timestamp, value)) sys.stdout.flush() - if timestamp is 'N': + if timestamp == 'N': timestamp = int(time.time()) # log.write('{},{},{}\n'.format(fund, timestamp, int(value))) diff --git a/collectd/usr/local/bin/power-data b/collectd/usr/local/bin/power-data index 8ef16d1..3f3f1fd 100755 --- a/collectd/usr/local/bin/power-data +++ b/collectd/usr/local/bin/power-data @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Imports @@ -6,61 +6,58 @@ import sys import time import argparse -import pylikwid +import pmt # # Configuration # -hostname = 'server' -cpuid = 0 -pinfo = pylikwid.getpowerinfo() -domainid = pinfo.get('domains').get('PKG').get('ID') -measurement_duration = 10 -measurement_interval = 60 -dinfo = pinfo.get('domains') -domain_names = dinfo.keys() -domain_ids = [domain['ID'] for domain in dinfo.values()] +hostname = "shuttle" +measurement_duration = 5 +measurement_interval = 15 +pm = pmt.create("rapl") # # Command line arguments # -parser = argparse.ArgumentParser(description='Get CPU power consumption') -parser.add_argument('-s', action='store_true', help='print in human readable format') +parser = argparse.ArgumentParser(description="Get CPU power consumption") +parser.add_argument("-s", action="store_true", help="print in human readable format") args = parser.parse_args() human_readable = args.s -# -# Methods -# -def get_power(): - #print dict(zip(domain_names, domain_ids)) - start = list() - end = list() - power = list() - for domain_id in domain_ids: - e_start = pylikwid.startpower(cpuid, domain_id) - start.append(e_start) - time.sleep(measurement_duration) - for domain_id in domain_ids: - e_stop = pylikwid.stoppower(cpuid, domain_id) - end.append(e_stop) - for events in zip(start, end, domain_ids): - power.append(pylikwid.getpower(events[0], events[1], events[2])) - return dict(zip(domain_names, power)) +# +# Methods +# +def get_power(): + time.sleep(measurement_duration) + measurements = dict() + state = pm.read() + for i in range(state.nr_measurements()): + name = state.name(i) + watts = state.watts(i) + measurements[name] = watts + return measurements + def print_rrd(measurements): timestamp = int(time.time()) - for measurement in measurements.items(): + for measurement in list(measurements.items()): name = measurement[0].lower() power = measurement[1] - print('PUTVAL {}/exec-power/gauge-{} {}:{:.1f}'.format(hostname, name, timestamp, power)) + print( + ( + "PUTVAL {}/exec-power/gauge-{} {}:{:.1f}".format( + hostname, name, timestamp, power + ) + ) + ) + # # Main # -if (human_readable): - print get_power() +if human_readable: + print(get_power()) else: while True: power = get_power() diff --git a/collectd/usr/local/bin/speedtest-data b/collectd/usr/local/bin/speedtest-data index 74a3453..bbe17c0 100755 --- a/collectd/usr/local/bin/speedtest-data +++ b/collectd/usr/local/bin/speedtest-data @@ -1,12 +1,16 @@ #!/bin/bash -SPEEDTEST=/sbin/speedtest-cli -COLLECTION=server -INTERVAL=1800 + +SPEEDTEST=/usr/bin/speedtest-cli +COLLECTION=shuttle +INTERVAL=900 while :; do SECONDS=0 RESULT=($($SPEEDTEST | grep Mbit | cut -d' ' -f 2)) - echo "PUTVAL $COLLECTION/exec-speedtest/gauge-download interval=$INTERVAL N:${RESULT[0]}" - echo "PUTVAL $COLLECTION/exec-speedtest/gauge-upload interval=$INTERVAL N:${RESULT[1]}" + TIMESTAMP=$(date +%s) + #echo "PUTVAL $COLLECTION/exec-speedtest/gauge-download interval=$INTERVAL N:${RESULT[0]}" + #echo "PUTVAL $COLLECTION/exec-speedtest/gauge-upload interval=$INTERVAL N:${RESULT[1]}" + echo "PUTVAL $COLLECTION/exec-speedtest/gauge-download ${TIMESTAMP}:${RESULT[0]}" + echo "PUTVAL $COLLECTION/exec-speedtest/gauge-upload ${TIMESTAMP}:${RESULT[1]}" sleep $((INTERVAL-$SECONDS)) done diff --git a/collectd/usr/local/bin/temperature-data b/collectd/usr/local/bin/temperature-data index 3a7f622..1c35158 100755 --- a/collectd/usr/local/bin/temperature-data +++ b/collectd/usr/local/bin/temperature-data @@ -1,23 +1,22 @@ -#!/usr/bin/python -u +#!/usr/bin/python3 # # Imports # import sys import time -import commands import argparse - +import subprocess # # Methods # def get_temperature(disks): command = "sudo smartctl -a /dev/%s | grep Temperature_Celsius | awk '{print $10}'" % disk - status, output = commands.getstatusoutput(command) + result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) try: - return int(output) + return int(result.stdout) except Exception as e: return None @@ -25,9 +24,9 @@ def get_temperature(disks): # # Settings # -hostname = 'server' +hostname = 'shuttle' interval = 10 -disks = ['sdd', 'sde', 'sdf'] +disks = ['sda', 'sdb', 'sdc', 'sdd'] # @@ -40,4 +39,3 @@ while True: if temperature: print('PUTVAL {}/exec-temperature/gauge-{}_total {}:{}'.format(hostname, disk, timestamp, temperature)) time.sleep(interval) - diff --git a/docker-compose.collectd.yaml b/docker-compose.collectd.yaml new file mode 100644 index 0000000..c4265b4 --- /dev/null +++ b/docker-compose.collectd.yaml @@ -0,0 +1,17 @@ +services: + collectd: + build: + context: /home/user/src + dockerfile: /opt/collectd/Dockerfile + container_name: collectd + image: collectd:bookworm + privileged: true + restart: unless-stopped + volumes: + - /opt/collectd/etc:/etc/collectd + - /opt/collectd/var:/var/lib/collectd + - /opt/collectd/usr:/host/usr + - /:/host/root:ro + - /media/data:/media/data:ro + - /var/lib/docker:/media/docker:ro + - /dev/mapper:/dev/mapper diff --git a/docker-compose.yaml b/docker-compose.yaml index 1b14a1b..5cf7fb8 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -6,6 +6,7 @@ include: - docker-compose.authentik.yaml # Other +- docker-compose.collectd.yaml - docker-compose.homarr.yaml - docker-compose.homeassistant.yaml - docker-compose.grafana.yaml