git: 50120f0b8fae - main - sysutils/beats9: New port

From: Palle Girgensohn <girgen_at_FreeBSD.org>
Date: Tue, 17 Mar 2026 15:46:47 UTC
The branch main has been updated by girgen:

URL: https://cgit.FreeBSD.org/ports/commit/?id=50120f0b8faed7ff444d6b6b1bf783a2d8b10457

commit 50120f0b8faed7ff444d6b6b1bf783a2d8b10457
Author:     Palle Girgensohn <girgen@FreeBSD.org>
AuthorDate: 2026-03-17 13:55:00 +0000
Commit:     Palle Girgensohn <girgen@FreeBSD.org>
CommitDate: 2026-03-17 15:46:08 +0000

    sysutils/beats9: New port
    
    Add sysutils/beats9, beats component for ELK 9.x.
    
    WWW:    https://github.com/elastic/beats/tree/v9.3.1
---
 sysutils/Makefile                                  |    1 +
 sysutils/beats8/Makefile                           |    4 +-
 sysutils/beats9/Makefile                           |  133 ++
 sysutils/beats9/distinfo                           |   11 +
 sysutils/beats9/files/auditbeat.in                 |   51 +
 sysutils/beats9/files/filebeat.in                  |   43 +
 sysutils/beats9/files/heartbeat.in                 |   44 +
 sysutils/beats9/files/metricbeat.in                |   51 +
 sysutils/beats9/files/packetbeat.in                |   43 +
 .../files/patch-auditbeat_auditbeat.reference.yml  |   20 +
 .../beats9/files/patch-auditbeat_auditbeat.yml     |   13 +
 .../beats9/files/patch-dev-tools_mage_settings.go  |   20 +
 .../files/patch-filebeat_filebeat.reference.yml    |   26 +
 sysutils/beats9/files/patch-filebeat_filebeat.yml  |   33 +
 sysutils/beats9/files/patch-go-sysinfo             | 1314 ++++++++++++++++++++
 .../files/patch-heartbeat_heartbeat.reference.yml  |   20 +
 .../beats9/files/patch-heartbeat_heartbeat.yml     |   11 +
 ...libbeat_autodiscover_providers_docker_config.go |   11 +
 ...libbeat_autodiscover_providers_docker_docker.go |   20 +
 ...eat_autodiscover_providers_kubernetes_config.go |   11 +
 ...autodiscover_providers_kubernetes_kubernetes.go |   11 +
 .../beats9/files/patch-libbeat_scripts_Makefile    |   26 +
 .../patch-metricbeat_metricbeat.reference.yml      |   20 +
 .../beats9/files/patch-metricbeat_metricbeat.yml   |   33 +
 .../patch-packetbeat_packetbeat.reference.yml      |   11 +
 .../beats9/files/patch-packetbeat_packetbeat.yml   |   23 +
 ...tic_elastic-agent-autodiscover_docker_client.go |   13 +
 ...ic_elastic-agent-autodiscover_docker_watcher.go |   13 +
 ...t-system-metrics_metric_cpu_metrics__freebsd.go |   10 +
 ...m-metrics_metric_cpu_metrics__procfs__common.go |   20 +
 ...em-metrics_metric_system_filesystem_fs__unix.go |   14 +
 sysutils/beats9/files/patch-vendor_modules.txt     |   10 +
 sysutils/beats9/files/pkg-message.in               |   10 +
 sysutils/beats9/pkg-descr                          |   18 +
 sysutils/beats9/pkg-plist                          |   21 +
 35 files changed, 2131 insertions(+), 2 deletions(-)

diff --git a/sysutils/Makefile b/sysutils/Makefile
index 4b4bda31015c..a9bfc4cbda13 100644
--- a/sysutils/Makefile
+++ b/sysutils/Makefile
@@ -117,6 +117,7 @@
     SUBDIR += bchunk
     SUBDIR += beadm
     SUBDIR += beats8
+    SUBDIR += beats9
     SUBDIR += bfs
     SUBDIR += bhyve-firmware
     SUBDIR += bhyve-rc
diff --git a/sysutils/beats8/Makefile b/sysutils/beats8/Makefile
index 169bfff398b2..5adb4b4a34b3 100644
--- a/sysutils/beats8/Makefile
+++ b/sysutils/beats8/Makefile
@@ -1,7 +1,7 @@
 PORTNAME=	beats
 DISTVERSIONPREFIX=	v
 DISTVERSION=	8.14.3
-PORTREVISION=	16
+PORTREVISION=	17
 CATEGORIES=	sysutils
 MASTER_SITES=	https://raw.githubusercontent.com/${GH_ACCOUNT}/${GH_PROJECT}/${DISTVERSIONFULL}/:gomod
 PKGNAMESUFFIX?=	8
@@ -25,7 +25,7 @@ CGO_CFLAGS=	-I.
 CGO_LDFLAGS=	-L.
 MAKE_ENV+=	GOBUILD_FLAGS="-mod=vendor"
 
-CONFLICTS=	beats6 beats7
+CONFLICTS=	beats6 beats7 beats9
 
 PORTSCOUT=	limit:^8
 
diff --git a/sysutils/beats9/Makefile b/sysutils/beats9/Makefile
new file mode 100644
index 000000000000..642e0d19e048
--- /dev/null
+++ b/sysutils/beats9/Makefile
@@ -0,0 +1,133 @@
+PORTNAME=	beats
+DISTVERSIONPREFIX=	v
+DISTVERSION=	9.3.1
+CATEGORIES=	sysutils
+MASTER_SITES=	https://raw.githubusercontent.com/${GH_ACCOUNT}/${GH_PROJECT}/${DISTVERSIONFULL}/:gomod
+PKGNAMESUFFIX?=	9
+DISTFILES=	go.mod:gomod
+
+MAINTAINER=	elastic@FreeBSD.org
+COMMENT=	Send logs, network, metrics and heartbeat to Elasticsearch or Logstash
+WWW=		https://www.elastic.co/products/beats/
+
+LICENSE=	APACHE20
+
+USES=		go:modules
+USE_GITHUB=	yes
+
+GH_ACCOUNT=	elastic
+
+USE_RC_SUBR=	${GO_TARGET:C,\./,,g}
+
+GO_MODULE=	github.com/elastic/beats/v9
+CGO_CFLAGS=	-I.
+CGO_LDFLAGS=	-L.
+MAKE_ENV+=	GOBUILD_FLAGS="-mod=vendor"
+
+CONFLICTS=	beats6 beats7 beats8
+
+PORTSCOUT=	limit:^9
+
+SUB_FILES=	pkg-message
+
+OPTIONS_DEFINE=		AUDITBEAT FILEBEAT HEARTBEAT METRICBEAT PACKETBEAT
+OPTIONS_DEFAULT=	FILEBEAT HEARTBEAT METRICBEAT
+OPTIONS_SUB=		yes
+
+AUDITBEAT_DESC=			Auditbeat
+FILEBEAT_DESC=			Filebeat
+HEARTBEAT_DESC=			Heartbeat
+METRICBEAT_DESC=		Metricbeat
+PACKETBEAT_DESC=		Packetbeat
+AUDITBEAT_MASTER_SITES=		https://artifacts.elastic.co/downloads/beats/auditbeat/:auditbeat
+AUDITBEAT_DISTFILES=		auditbeat-${DISTVERSION}-darwin-x86_64.tar.gz:auditbeat
+AUDITBEAT_VARS=			GO_TARGET+=./auditbeat
+FILEBEAT_MASTER_SITES=		https://artifacts.elastic.co/downloads/beats/filebeat/:filebeat
+FILEBEAT_DISTFILES=		filebeat-${DISTVERSION}-darwin-x86_64.tar.gz:filebeat
+FILEBEAT_VARS=			GO_TARGET+=./filebeat
+HEARTBEAT_MASTER_SITES=		https://artifacts.elastic.co/downloads/beats/heartbeat/:heartbeat
+HEARTBEAT_DISTFILES=		heartbeat-${DISTVERSION}-darwin-x86_64.tar.gz:heartbeat
+HEARTBEAT_VARS=			GO_TARGET+=./heartbeat
+METRICBEAT_MASTER_SITES=	https://artifacts.elastic.co/downloads/beats/metricbeat/:metricbeat
+METRICBEAT_DISTFILES=		metricbeat-${DISTVERSION}-darwin-x86_64.tar.gz:metricbeat
+METRICBEAT_VARS=		GO_TARGET+=./metricbeat
+PACKETBEAT_MASTER_SITES=	https://artifacts.elastic.co/downloads/beats/packetbeat/:packetbeat
+PACKETBEAT_DISTFILES=		packetbeat-${DISTVERSION}-darwin-x86_64.tar.gz:packetbeat
+PACKETBEAT_VARS=		CGO_CFLAGS+=-I/usr/include \
+				CGO_LDFLAGS+=-L/usr/lib \
+				GO_TARGET+=./packetbeat
+
+.include <bsd.port.options.mk>
+
+post-patch:
+	${REINPLACE_CMD} -e "s|%%BEATSVERSION%%|v${PORTVERSION}|g" ${WRKSRC}/dev-tools/mage/settings.go
+.for BEATMOD in ${GO_TARGET:C,\./,,g}
+	${REINPLACE_CMD} -e "s|%%DATADIR%%|${DATADIR}|g" \
+		${WRKSRC}/${BEATMOD}/${BEATMOD}.yml ${WRKSRC}/${BEATMOD}/${BEATMOD}.reference.yml
+.endfor
+
+do-install:
+	${MKDIR} ${STAGEDIR}${ETCDIR}
+.for BEATMOD in ${GO_TARGET:C,^\./,,g}
+	${MKDIR} ${STAGEDIR}/var/db/beats/${BEATMOD} && \
+	${INSTALL_PROGRAM} ${WRKDIR}/bin/${BEATMOD} \
+		${STAGEDIR}${PREFIX}/sbin && \
+	${INSTALL_DATA} ${WRKSRC}/${BEATMOD}/${BEATMOD}.yml \
+		${STAGEDIR}${ETCDIR}/${BEATMOD}.yml.sample && \
+	${INSTALL_DATA} ${WRKSRC}/${BEATMOD}/${BEATMOD}.reference.yml \
+		${STAGEDIR}${ETCDIR}/${BEATMOD}.yml.reference
+	(MODULE_SRC=${WRKDIR}/${BEATMOD}-${DISTVERSION}-darwin-x86_64/module; \
+	 if [ -d $${MODULE_SRC} ]; then \
+	   MODULE_DEST=${STAGEDIR}${DATADIR}/${BEATMOD}/module && \
+	   ${MKDIR} $${MODULE_DEST} && \
+	   cd $${MODULE_SRC} && ${COPYTREE_SHARE} . $${MODULE_DEST} && \
+	   cd $${MODULE_DEST} && \
+	   ${FIND} . -type d -empty | ${SORT} | \
+	   ${SED} -e 's,^\.,@dir ${DATADIR_REL}/${BEATMOD}/module,' >> ${TMPPLIST} && \
+	   ${FIND} . -not -type d | ${SORT} | \
+	   ${SED} -e 's,^\.,${DATADIR_REL}/${BEATMOD}/module,' >> ${TMPPLIST}; \
+	 fi) && \
+	(MODULESD_SRC=${WRKDIR}/${BEATMOD}-${DISTVERSION}-darwin-x86_64/modules.d; \
+	 if [ -d $${MODULESD_SRC} ]; then \
+	   MODULESD_DEST=${STAGEDIR}${EXAMPLESDIR}/${BEATMOD}.modules.d && \
+	   ${MKDIR} $${MODULESD_DEST} && \
+	   cd $${MODULESD_SRC} && ${COPYTREE_SHARE} . $${MODULESD_DEST} && \
+	   cd $${MODULESD_DEST} && \
+	   ${FIND} . -type d -empty | ${SORT} | \
+	   ${SED} -e 's,^\.,@dir ${EXAMPLESDIR_REL}/${BEATMOD}.modules.d,' >> ${TMPPLIST} && \
+	   ${FIND} . -not -type d | ${SORT} | \
+	   ${SED} -e 's,^\.,${EXAMPLESDIR_REL}/${BEATMOD}.modules.d,' >> ${TMPPLIST}; \
+	   ${MKDIR} ${STAGEDIR}${ETCDIR}/${BEATMOD}.modules.d && \
+	   ${ECHO_CMD} "The modules.d files are now in ${EXAMPLESDIR}/${BEATMOD}.modules.d" > \
+	     ${STAGEDIR}${ETCDIR}/${BEATMOD}.modules.d/README; \
+	   ${ECHO_CMD} ${ETCDIR_REL}/${BEATMOD}.modules.d/README >> ${TMPPLIST}; \
+	 fi) && \
+	(MONITORSD_SRC=${WRKDIR}/${BEATMOD}-${DISTVERSION}-darwin-x86_64/monitors.d; \
+	 if [ -d $${MONITORSD_SRC} ]; then \
+	   MONITORSD_DEST=${STAGEDIR}${EXAMPLESDIR}/${BEATMOD}.monitors.d && \
+	   ${MKDIR} $${MONITORSD_DEST} && \
+	   cd $${MONITORSD_SRC} && ${COPYTREE_SHARE} . $${MONITORSD_DEST} && \
+	   cd $${MONITORSD_DEST} && \
+	   ${FIND} . -type d -empty | ${SORT} | \
+	   ${SED} -e 's,^\.,@dir ${EXAMPLESDIR_REL}/${BEATMOD}.monitors.d,' >> ${TMPPLIST} && \
+	   ${FIND} . -not -type d | ${SORT} | \
+	   ${SED} -e 's,^\.,${EXAMPLESDIR_REL}/${BEATMOD}.monitors.d,' >> ${TMPPLIST}; \
+	   ${MKDIR} ${STAGEDIR}${ETCDIR}/${BEATMOD}.monitors.d && \
+	   ${ECHO_CMD} "The monitors.d files are now in ${EXAMPLESDIR}/${BEATMOD}.monitors.d" > \
+	     ${STAGEDIR}${ETCDIR}/${BEATMOD}.monitors.d/README; \
+	   ${ECHO_CMD} ${ETCDIR_REL}/${BEATMOD}.monitors.d/README >> ${TMPPLIST}; \
+	 fi) && \
+	(KIBANA_SRC=${WRKDIR}/${BEATMOD}-${DISTVERSION}-darwin-x86_64/kibana; \
+	 if [ -d $${KIBANA_SRC} ]; then \
+	   KIBANA_PATH=${STAGEDIR}${DATADIR}/${BEATMOD}/kibana; \
+	   ${MKDIR} $${KIBANA_PATH} && \
+	   cd $${KIBANA_SRC} && ${COPYTREE_SHARE} . $${KIBANA_PATH}; \
+	   cd $${KIBANA_PATH} && \
+	   ${FIND} . -type d -empty | ${SORT} | \
+	   ${SED} -e 's,^\.,@dir ${DATADIR_REL}/${BEATMOD}/kibana,' >> ${TMPPLIST}; \
+	   ${FIND} . -not -type d | ${SORT} | \
+	   ${SED} -e 's,^\.,${DATADIR_REL}/${BEATMOD}/kibana,' >> ${TMPPLIST}; \
+	 fi)
+.endfor
+
+.include <bsd.port.mk>
diff --git a/sysutils/beats9/distinfo b/sysutils/beats9/distinfo
new file mode 100644
index 000000000000..f7a3906545ed
--- /dev/null
+++ b/sysutils/beats9/distinfo
@@ -0,0 +1,11 @@
+TIMESTAMP = 1773752247
+SHA256 (go/sysutils_beats9/elastic-beats-v9.3.1_GH0/go.mod) = 12a772a95a1c7e8a86e5cef7bac4ffcaf86ba08a7f5c741fa748b63f728d12cb
+SIZE (go/sysutils_beats9/elastic-beats-v9.3.1_GH0/go.mod) = 28847
+SHA256 (go/sysutils_beats9/elastic-beats-v9.3.1_GH0/filebeat-9.3.1-darwin-x86_64.tar.gz) = 9d1f0af9ab8ce78525496506adea24688744f8ad91eee063dc48e7763e05bcac
+SIZE (go/sysutils_beats9/elastic-beats-v9.3.1_GH0/filebeat-9.3.1-darwin-x86_64.tar.gz) = 56132282
+SHA256 (go/sysutils_beats9/elastic-beats-v9.3.1_GH0/heartbeat-9.3.1-darwin-x86_64.tar.gz) = 60e5169dc1d5454faf3d5ca3b72b401255acb5a07f237ec18ed8b1b189ead94d
+SIZE (go/sysutils_beats9/elastic-beats-v9.3.1_GH0/heartbeat-9.3.1-darwin-x86_64.tar.gz) = 35745443
+SHA256 (go/sysutils_beats9/elastic-beats-v9.3.1_GH0/metricbeat-9.3.1-darwin-x86_64.tar.gz) = e8885267e1c9229e87dd4a0f81afe06bd99e2fbef1131a8914a243457d8e1172
+SIZE (go/sysutils_beats9/elastic-beats-v9.3.1_GH0/metricbeat-9.3.1-darwin-x86_64.tar.gz) = 60065375
+SHA256 (go/sysutils_beats9/elastic-beats-v9.3.1_GH0/elastic-beats-v9.3.1_GH0.tar.gz) = 77851327be677219aa116531e8d37c6359d59aff9ab6feff9e5f3d570a54a221
+SIZE (go/sysutils_beats9/elastic-beats-v9.3.1_GH0/elastic-beats-v9.3.1_GH0.tar.gz) = 104227700
diff --git a/sysutils/beats9/files/auditbeat.in b/sysutils/beats9/files/auditbeat.in
new file mode 100644
index 000000000000..67909ad68d67
--- /dev/null
+++ b/sysutils/beats9/files/auditbeat.in
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+# PROVIDE: auditbeat
+# REQUIRE: DAEMON
+# BEFORE: LOGIN
+# KEYWORD: shutdown
+
+# Add the following lines to /etc/rc.conf to enable auditbeat:
+#
+# auditbeat_enable (bool):	Set to YES to enable auditbeat
+# 				Default: NO
+# auditbeat_flags (str):	Extra flags passed to auditbeat
+# auditbeat_config (str):	auditbeat configuration directory
+#				Default: ${PREFIX}/etc/beats
+# auditbeat_conffile (str):	auditbeat configuration file
+#				relative to ${auditbeat_conf}
+#				Default: auditbeat.yml
+
+. /etc/rc.subr
+
+name="auditbeat"
+rcvar=${name}_enable
+load_rc_config $name
+
+: ${auditbeat_enable:="NO"}
+: ${auditbeat_config:="%%ETCDIR%%"}
+: ${auditbeat_conffile:="auditbeat.yml"}
+: ${auditbeat_home:="%%DATADIR%%/auditbeat"}
+: ${auditbeat_logs:="/var/log/beats"}
+: ${auditbeat_data:="/var/db/beats/auditbeat"}
+
+# daemon
+start_precmd=auditbeat_prestart
+command=/usr/sbin/daemon
+pidfile="/var/run/${name}"
+command_args="-frP ${pidfile} %%PREFIX%%/sbin/${name} ${auditbeat_flags} --path.config ${auditbeat_config} --path.home ${auditbeat_home} --path.data ${auditbeat_data} --path.logs ${auditbeat_logs} -c ${auditbeat_conffile}"
+
+auditbeat_prestart() {
+# Have to empty rc_flags so they don't get passed to daemon(8)
+	rc_flags=""
+}
+
+# auditbeat will refuse to quit if linprocfs is mounted, and sadly requires -9
+[ -f /compat/linux/proc/cpuinfo ] && stop_cmd=auditbeat_stop
+
+auditbeat_stop() {
+	pkill -9 -F ${pidfile} > /dev/null 2>&1
+	pkill -9 -F ${pidfile}.child > /dev/null 2>&1
+}
+
+run_rc_command "$1"
diff --git a/sysutils/beats9/files/filebeat.in b/sysutils/beats9/files/filebeat.in
new file mode 100644
index 000000000000..8ae08af5b398
--- /dev/null
+++ b/sysutils/beats9/files/filebeat.in
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+# PROVIDE: filebeat
+# REQUIRE: DAEMON
+# BEFORE: LOGIN
+# KEYWORD: shutdown
+
+# Add the following lines to /etc/rc.conf to enable filebeat:
+#
+# filebeat_enable (bool):	Set to YES to enable filebeat
+# 				Default: NO
+# filebeat_flags (str):		Extra flags passed to filebeat
+# filebeat_config (str):	filebeat configuration directory
+#				Default: ${PREFIX}/etc/beats
+# filebeat_conffile (str):	filebeat configuration file
+#				relative to ${filebeat_conf}
+#				Default: filebeat.yml
+
+. /etc/rc.subr
+
+name="filebeat"
+rcvar=${name}_enable
+load_rc_config $name
+
+: ${filebeat_enable:="NO"}
+: ${filebeat_config:="%%ETCDIR%%"}
+: ${filebeat_conffile:="filebeat.yml"}
+: ${filebeat_home:="%%DATADIR%%/filebeat"}
+: ${filebeat_logs:="/var/log/beats"}
+: ${filebeat_data:="/var/db/beats/filebeat"}
+
+# daemon
+start_precmd=filebeat_prestart
+command=/usr/sbin/daemon
+pidfile="/var/run/${name}"
+command_args="-frP ${pidfile} %%PREFIX%%/sbin/${name} ${filebeat_flags} --path.config ${filebeat_config} --path.home ${filebeat_home} --path.data ${filebeat_data} --path.logs ${filebeat_logs} -c ${filebeat_conffile}"
+
+filebeat_prestart() {
+# Have to empty rc_flags so they don't get passed to daemon(8)
+	rc_flags=""
+}
+
+run_rc_command "$1"
diff --git a/sysutils/beats9/files/heartbeat.in b/sysutils/beats9/files/heartbeat.in
new file mode 100644
index 000000000000..d99374ab011c
--- /dev/null
+++ b/sysutils/beats9/files/heartbeat.in
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+# PROVIDE: heartbeat
+# REQUIRE: DAEMON
+# BEFORE: LOGIN
+# KEYWORD: shutdown
+
+# Add the following lines to /etc/rc.conf to enable heartbeat:
+#
+# heartbeat_enable (bool):	Set to YES to enable heartbeat
+# 				Default: NO
+# heartbeat_flags (str):	Extra flags passed to heartbeat
+# heartbeat_config (str):	heartbeat configuration directory
+#				Default: ${PREFIX}/etc/beats
+# heartbeat_conffile (str):	heartbeat configuration file
+#				relative to ${heartbeat_conf}
+#				Default: heartbeat.yml
+
+. /etc/rc.subr
+
+name="heartbeat"
+rcvar=${name}_enable
+load_rc_config $name
+
+: ${heartbeat_enable:="NO"}
+: ${heartbeat_config:="%%ETCDIR%%"}
+: ${heartbeat_conffile:="heartbeat.yml"}
+: ${heartbeat_home:="%%DATADIR%%/heartbeat"}
+: ${heartbeat_logs:="/var/log/beats"}
+: ${heartbeat_data:="/var/db/beats/heartbeat"}
+
+
+# daemon
+start_precmd=heartbeat_prestart
+command=/usr/sbin/daemon
+pidfile="/var/run/${name}"
+command_args="-frP ${pidfile} %%PREFIX%%/sbin/${name} ${heartbeat_flags} --path.config ${heartbeat_config} --path.home ${heartbeat_home} --path.data ${heartbeat_data} --path.logs ${heartbeat_logs} -c ${heartbeat_conffile}"
+
+heartbeat_prestart() {
+# Have to empty rc_flags so they don't get passed to daemon(8)
+	rc_flags=""
+}
+
+run_rc_command "$1"
diff --git a/sysutils/beats9/files/metricbeat.in b/sysutils/beats9/files/metricbeat.in
new file mode 100644
index 000000000000..270966c4f669
--- /dev/null
+++ b/sysutils/beats9/files/metricbeat.in
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+# PROVIDE: metricbeat
+# REQUIRE: DAEMON
+# BEFORE: LOGIN
+# KEYWORD: shutdown
+
+# Add the following lines to /etc/rc.conf to enable metricbeat:
+#
+# metricbeat_enable (bool):	Set to YES to enable metricbeat
+# 				Default: NO
+# metricbeat_flags (str):	Extra flags passed to metricbeat
+# metricbeat_config (str):	metricbeat configuration directory
+#				Default: ${PREFIX}/etc/beats
+# metricbeat_conffile (str):	metricbeat configuration file
+#				relative to ${metricbeat_conf}
+#				Default: metricbeat.yml
+
+. /etc/rc.subr
+
+name="metricbeat"
+rcvar=${name}_enable
+load_rc_config $name
+
+: ${metricbeat_enable:="NO"}
+: ${metricbeat_config:="%%ETCDIR%%"}
+: ${metricbeat_conffile:="metricbeat.yml"}
+: ${metricbeat_home:="%%DATADIR%%/metricbeat"}
+: ${metricbeat_logs:="/var/log/beats"}
+: ${metricbeat_data:="/var/db/beats/metricbeat"}
+
+# daemon
+start_precmd=metricbeat_prestart
+command=/usr/sbin/daemon
+pidfile="/var/run/${name}"
+command_args="-frP ${pidfile} %%PREFIX%%/sbin/${name} ${metricbeat_flags} --path.config ${metricbeat_config} --path.home ${metricbeat_home} --path.data ${metricbeat_data} --path.logs ${metricbeat_logs} -c ${metricbeat_conffile}"
+
+metricbeat_prestart() {
+# Have to empty rc_flags so they don't get passed to daemon(8)
+	rc_flags=""
+}
+
+# metricbeat will refuse to quit if linprocfs is mounted, and sadly requires -9
+[ -f /compat/linux/proc/cpuinfo ] && stop_cmd=metricbeat_stop
+
+metricbeat_stop() {
+	pkill -9 -F ${pidfile} > /dev/null 2>&1
+	pkill -9 -F ${pidfile}.child > /dev/null 2>&1
+}
+
+run_rc_command "$1"
diff --git a/sysutils/beats9/files/packetbeat.in b/sysutils/beats9/files/packetbeat.in
new file mode 100644
index 000000000000..4dc21856c49a
--- /dev/null
+++ b/sysutils/beats9/files/packetbeat.in
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+# PROVIDE: packetbeat
+# REQUIRE: DAEMON
+# BEFORE: LOGIN
+# KEYWORD: shutdown
+
+# Add the following lines to /etc/rc.conf to enable packetbeat
+#
+# packetbeat_enable (bool):	Set to YES to enable packetbeat
+# 				Default: NO
+# packetbeat_flags (str):	Extra flags passed to packetbeat
+# packetbeat_config (str):	packetbeat configuration directory
+#				Default: ${PREFIX}/etc/beats
+# packetbeat_conffile (str):	packetbeat configuration file
+#				relative to ${packetbeat_conf}
+#				Default: packetbeat.yml
+
+. /etc/rc.subr
+
+name="packetbeat"
+rcvar=${name}_enable
+load_rc_config $name
+
+: ${packetbeat_enable:="NO"}
+: ${packetbeat_config:="%%ETCDIR%%"}
+: ${packetbeat_conffile:="packetbeat.yml"}
+: ${packetbeat_home:="%%DATADIR%%/packetbeat"}
+: ${packetbeat_logs:="/var/log/beats"}
+: ${packetbeat_data:="/var/db/beats/packetbeat"}
+
+# daemon
+start_precmd=packetbeat_prestart
+command=/usr/sbin/daemon
+pidfile="/var/run/${name}"
+command_args="-frP ${pidfile} %%PREFIX%%/sbin/${name} ${packetbeat_flags} --path.config ${packetbeat_config} --path.home ${packetbeat_home} --path.data ${packetbeat_data} --path.logs ${packetbeat_logs} -c ${packetbeat_conffile}"
+
+packetbeat_prestart() {
+# Have to empty rc_flags so they don't get passed to daemon(8)
+	rc_flags=""
+}
+
+run_rc_command "$1"
diff --git a/sysutils/beats9/files/patch-auditbeat_auditbeat.reference.yml b/sysutils/beats9/files/patch-auditbeat_auditbeat.reference.yml
new file mode 100644
index 000000000000..04ef963d9642
--- /dev/null
+++ b/sysutils/beats9/files/patch-auditbeat_auditbeat.reference.yml
@@ -0,0 +1,20 @@
+--- auditbeat/auditbeat.reference.yml.orig	2025-09-15 19:57:17 UTC
++++ auditbeat/auditbeat.reference.yml
+@@ -14,7 +14,7 @@ auditbeat.config.modules:
+ auditbeat.config.modules:
+ 
+   # Glob pattern for configuration reloading
+-  path: ${path.config}/modules.d/*.yml
++  path: ${path.config}/auditbeat.modules.d/*.yml
+ 
+   # Period on which files under path should be checked for changes
+   reload.period: 10s
+@@ -1250,7 +1250,7 @@ output.elasticsearch:
+ 
+ # The directory from where to read the dashboards. The default is the `kibana`
+ # folder in the home path.
+-#setup.dashboards.directory: ${path.home}/kibana
++#setup.dashboards.directory: %%DATADIR%%/auditbeat/kibana
+ 
+ # The URL from where to download the dashboard archive. It is used instead of
+ # the directory if it has a value.
diff --git a/sysutils/beats9/files/patch-auditbeat_auditbeat.yml b/sysutils/beats9/files/patch-auditbeat_auditbeat.yml
new file mode 100644
index 000000000000..b9c74affaee6
--- /dev/null
+++ b/sysutils/beats9/files/patch-auditbeat_auditbeat.yml
@@ -0,0 +1,13 @@
+--- auditbeat/auditbeat.yml.orig	2025-09-15 19:57:17 UTC
++++ auditbeat/auditbeat.yml
+@@ -82,6 +82,10 @@ setup.template.settings:
+ # website.
+ #setup.dashboards.url:
+ 
++# The directory from where to read the dashboards. The default is the `kibana`
++# folder in the home path.
++#setup.dashboards.directory: %%DATADIR%%/auditbeat/kibana
++
+ # =================================== Kibana ===================================
+ 
+ # Starting with Beats version 6.0.0, the dashboards are loaded via the Kibana API.
diff --git a/sysutils/beats9/files/patch-dev-tools_mage_settings.go b/sysutils/beats9/files/patch-dev-tools_mage_settings.go
new file mode 100644
index 000000000000..fff0c065e200
--- /dev/null
+++ b/sysutils/beats9/files/patch-dev-tools_mage_settings.go
@@ -0,0 +1,20 @@
+--- dev-tools/mage/settings.go.orig	2025-09-15 19:57:17 UTC
++++ dev-tools/mage/settings.go
+@@ -31,7 +31,6 @@ import (
+ 	"sync"
+ 	"time"
+ 
+-	"github.com/magefile/mage/sh"
+ 	"golang.org/x/text/cases"
+ 	"golang.org/x/text/language"
+ 	"gopkg.in/yaml.v3"
+@@ -282,7 +281,8 @@ func CommitHash() (string, error) {
+ func CommitHash() (string, error) {
+ 	var err error
+ 	commitHashOnce.Do(func() {
+-		commitHash, err = sh.Output("git", "rev-parse", "HEAD")
++		err = nil
++		commitHash = "%%BEATSVERSION%%"
+ 	})
+ 	return commitHash, err
+ }
diff --git a/sysutils/beats9/files/patch-filebeat_filebeat.reference.yml b/sysutils/beats9/files/patch-filebeat_filebeat.reference.yml
new file mode 100644
index 000000000000..33dc3a22fd11
--- /dev/null
+++ b/sysutils/beats9/files/patch-filebeat_filebeat.reference.yml
@@ -0,0 +1,26 @@
+--- filebeat/filebeat.reference.yml.orig	2025-09-15 19:57:17 UTC
++++ filebeat/filebeat.reference.yml
+@@ -1329,12 +1329,12 @@ - type: filestream
+ #filebeat.config:
+   #inputs:
+     #enabled: false
+-    #path: inputs.d/*.yml
++    #path: filebeat.inputs.d/*.yml
+     #reload.enabled: true
+     #reload.period: 10s
+   #modules:
+     #enabled: true
+-    #path: modules.d/*.yml
++    #path: filebeat.modules.d/*.yml
+     #reload.enabled: true
+     #reload.period: 10s
+ 
+@@ -2408,7 +2408,7 @@ output.elasticsearch:
+ 
+ # The directory from where to read the dashboards. The default is the `kibana`
+ # folder in the home path.
+-#setup.dashboards.directory: ${path.home}/kibana
++#setup.dashboards.directory: %%DATADIR%%/filebeat/kibana
+ 
+ # The URL from where to download the dashboard archive. It is used instead of
+ # the directory if it has a value.
diff --git a/sysutils/beats9/files/patch-filebeat_filebeat.yml b/sysutils/beats9/files/patch-filebeat_filebeat.yml
new file mode 100644
index 000000000000..c9a078cc6ffb
--- /dev/null
+++ b/sysutils/beats9/files/patch-filebeat_filebeat.yml
@@ -0,0 +1,33 @@
+--- filebeat/filebeat.yml.orig	2025-09-15 19:57:17 UTC
++++ filebeat/filebeat.yml
+@@ -81,7 +81,7 @@ filebeat.config.modules:
+ 
+ filebeat.config.modules:
+   # Glob pattern for configuration loading
+-  path: ${path.config}/modules.d/*.yml
++  path: ${path.config}/filebeat.modules.d/*.yml
+ 
+   # Set to true to enable config reloading
+   reload.enabled: false
+@@ -124,6 +124,10 @@ setup.template.settings:
+ # website.
+ #setup.dashboards.url:
+ 
++# The directory from where to read the dashboards. The default is the `kibana`
++# folder in the home path.
++#setup.dashboards.directory: %%DATADIR%%/filebeat/kibana
++
+ # =================================== Kibana ===================================
+ 
+ # Starting with Beats version 6.0.0, the dashboards are loaded via the Kibana API.
+@@ -195,8 +199,8 @@ processors:
+   - add_host_metadata:
+       when.not.contains.tags: forwarded
+   - add_cloud_metadata: ~
+-  - add_docker_metadata: ~
+-  - add_kubernetes_metadata: ~
++#  - add_docker_metadata: ~
++#  - add_kubernetes_metadata: ~
+ 
+ # ================================== Logging ===================================
+ 
diff --git a/sysutils/beats9/files/patch-go-sysinfo b/sysutils/beats9/files/patch-go-sysinfo
new file mode 100644
index 000000000000..2ac3e3daee55
--- /dev/null
+++ b/sysutils/beats9/files/patch-go-sysinfo
@@ -0,0 +1,1314 @@
+--- vendor/github.com/elastic/go-sysinfo/internal/cgo/disabled.go.orig	2025-09-19 18:12:17 UTC
++++ vendor/github.com/elastic/go-sysinfo/internal/cgo/disabled.go
+@@ -0,0 +1,23 @@
++// Licensed to Elasticsearch B.V. under one or more contributor
++// license agreements. See the NOTICE file distributed with
++// this work for additional information regarding copyright
++// ownership. Elasticsearch B.V. licenses this file to you under
++// the Apache License, Version 2.0 (the "License"); you may
++// not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++//     http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing,
++// software distributed under the License is distributed on an
++// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++// KIND, either express or implied.  See the License for the
++// specific language governing permissions and limitations
++// under the License.
++
++//go:build !cgo
++
++package cgo
++
++// Enabled is true if cgo was enabled at compile-time.
++const Enabled = false
+--- vendor/github.com/elastic/go-sysinfo/internal/cgo/enabled.go.orig	2025-09-19 18:12:17 UTC
++++ vendor/github.com/elastic/go-sysinfo/internal/cgo/enabled.go
+@@ -0,0 +1,23 @@
++// Licensed to Elasticsearch B.V. under one or more contributor
++// license agreements. See the NOTICE file distributed with
++// this work for additional information regarding copyright
++// ownership. Elasticsearch B.V. licenses this file to you under
++// the Apache License, Version 2.0 (the "License"); you may
++// not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++//     http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing,
++// software distributed under the License is distributed on an
++// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++// KIND, either express or implied.  See the License for the
++// specific language governing permissions and limitations
++// under the License.
++
++//go:build cgo
++
++package cgo
++
++// Enabled is true if cgo was enabled at compile-time.
++const Enabled = true
+--- vendor/github.com/elastic/go-sysinfo/providers/freebsd/defs_freebsd.go.orig	2025-09-19 18:12:17 UTC
++++ vendor/github.com/elastic/go-sysinfo/providers/freebsd/defs_freebsd.go
+@@ -0,0 +1,33 @@
++// Licensed to Elasticsearch B.V. under one or more contributor
++// license agreements. See the NOTICE file distributed with
++// this work for additional information regarding copyright
++// ownership. Elasticsearch B.V. licenses this file to you under
++// the Apache License, Version 2.0 (the "License"); you may
++// not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++//     http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing,
++// software distributed under the License is distributed on an
++// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++// KIND, either express or implied.  See the License for the
++// specific language governing permissions and limitations
++// under the License.
++
++//go:build ignore
++// +build ignore
++
++package freebsd
++
++/*
++#include <sys/types.h>
++#include <sys/vmmeter.h>
++#include <sys/time.h>
++#include <kvm.h>
++*/
++import "C"
++
++type kvmSwap C.struct_kvm_swap
++
++type clockInfo C.struct_clockinfo
+--- vendor/github.com/elastic/go-sysinfo/providers/freebsd/doc.go.orig	2025-09-19 18:12:17 UTC
++++ vendor/github.com/elastic/go-sysinfo/providers/freebsd/doc.go
+@@ -0,0 +1,22 @@
++// Licensed to Elasticsearch B.V. under one or more contributor
++// license agreements. See the NOTICE file distributed with
++// this work for additional information regarding copyright
++// ownership. Elasticsearch B.V. licenses this file to you under
++// the Apache License, Version 2.0 (the "License"); you may
++// not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++//     http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing,
++// software distributed under the License is distributed on an
++// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++// KIND, either express or implied.  See the License for the
++// specific language governing permissions and limitations
++// under the License.
++
++// Package freebsd implements the HostProvider and ProcessProvider interfaces
++// for providing information about FreeBSD.
++package freebsd
++
++//go:generate sh -c "go tool cgo -godefs defs_freebsd.go > ztypes_freebsd.go"
+--- vendor/github.com/elastic/go-sysinfo/providers/freebsd/host_freebsd_cgo.go.orig	2025-09-19 18:12:17 UTC
++++ vendor/github.com/elastic/go-sysinfo/providers/freebsd/host_freebsd_cgo.go
+@@ -0,0 +1,238 @@
++// Licensed to Elasticsearch B.V. under one or more contributor
++// license agreements. See the NOTICE file distributed with
++// this work for additional information regarding copyright
++// ownership. Elasticsearch B.V. licenses this file to you under
++// the Apache License, Version 2.0 (the "License"); you may
++// not use this file except in compliance with the License.
++// You may obtain a copy of the License at
++//
++//     http://www.apache.org/licenses/LICENSE-2.0
++//
++// Unless required by applicable law or agreed to in writing,
++// software distributed under the License is distributed on an
++// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++// KIND, either express or implied.  See the License for the
++// specific language governing permissions and limitations
++// under the License.
++
++//go:build freebsd && cgo
++
++package freebsd
++
++import (
++	"context"
++	"errors"
++	"os"
++	"path/filepath"
++	"time"
++
++	"github.com/prometheus/procfs"
++
++	"github.com/elastic/go-sysinfo/internal/registry"
++	"github.com/elastic/go-sysinfo/providers/shared"
++	"github.com/elastic/go-sysinfo/types"
++)
++
++func init() {
++	registry.Register(newFreeBSDSystem())
++}
++
++type freebsdSystem struct{}
++
++func newFreeBSDSystem() freebsdSystem {
++	return freebsdSystem{}
++}
++
++func (s freebsdSystem) Host() (types.Host, error) {
++	return newHost()
++}
++
++type host struct {
++	procFS procFS
++	info   types.HostInfo
++}
++
++func (h *host) Info() types.HostInfo {
++	return h.info
++}
++
++func (h *host) CPUTime() (types.CPUTimes, error) {
++	cpu := types.CPUTimes{}
++	r := &reader{}
++	r.cpuTime(&cpu)
++	return cpu, r.Err()
++}
++
++func (h *host) Memory() (*types.HostMemoryInfo, error) {
++	m := &types.HostMemoryInfo{}
++	r := &reader{}
++	r.memInfo(m)
++	return m, r.Err()
++}
++
++func (h *host) FQDNWithContext(ctx context.Context) (string, error) {
++	return shared.FQDNWithContext(ctx)
++}
++
++func (h *host) FQDN() (string, error) {
++	return h.FQDNWithContext(context.Background())
++}
++
++func newHost() (*host, error) {
++	h := &host{}
++	r := &reader{}
++	r.architecture(h)
++	r.bootTime(h)
++	r.hostname(h)
++	r.network(h)
++	r.kernelVersion(h)
++	r.os(h)
++	r.time(h)
++	r.uniqueID(h)
++	return h, r.Err()
++}
++
++type reader struct {
++	errs []error
++}
++
++func (r *reader) addErr(err error) bool {
++	if err != nil {
++		if !errors.Is(err, types.ErrNotImplemented) {
++			r.errs = append(r.errs, err)
++		}
++		return true
++	}
++	return false
++}
++
++func (r *reader) Err() error {
++	return errors.Join(r.errs...)
++}
++
++func (r *reader) cpuTime(cpu *types.CPUTimes) {
++	times, err := cpuStateTimes()
++	if r.addErr(err) {
++		return
++	}
++	*cpu = *times
++}
++
++func (r *reader) memInfo(m *types.HostMemoryInfo) {
++	// Memory counter calculations:
++	//   total = physical memory
++	//   used = active + wired
++	//   free = free
++	//   available = buffers + inactive + cache + free
++
++	pageSize, err := pageSizeBytes()
++	if r.addErr(err) {
++		return
++	}
++
++	m.Total = totalPhysicalMem(r)
++	activePages := activePageCount(r)
++
++	m.Metrics = make(map[string]uint64, 6)
++	m.Metrics["active_bytes"] = activePages * pageSize
++
++	wirePages := wirePageCount(r)
++	m.Metrics["wired_bytes"] = wirePages * pageSize
++
++	inactivePages := inactivePageCount(r)
++	m.Metrics["inactive_bytes"] = inactivePages * pageSize
++
++	cachePages := cachePageCount(r)
++	m.Metrics["cache_bytes"] = cachePages * pageSize
++
++	freePages := freePageCount(r)
++	m.Metrics["free_bytes"] = freePages * pageSize
++
++	buffers := buffersUsedBytes(r)
++	m.Metrics["buffer_bytes"] = buffers
++
++	m.Used = (activePages + wirePages) * pageSize
++	m.Free = freePages * pageSize
++	m.Available = (inactivePages+cachePages+freePages)*pageSize + buffers
++
++	// Virtual (swap) Memory
++	swap, err := kvmGetSwapInfo()
++	if r.addErr(err) {
++		return
++	}
++
++	m.VirtualTotal = uint64(swap.Total) * pageSize
++	m.VirtualUsed = uint64(swap.Used) * pageSize
++	m.VirtualFree = m.VirtualTotal - m.VirtualUsed
++}
++
++func (r *reader) architecture(h *host) {
++	v, err := architecture()
++	if r.addErr(err) {
++		return
++	}
++	h.info.Architecture = v
++}
++
++func (r *reader) bootTime(h *host) {
++	v, err := bootTime()
++	if r.addErr(err) {
++		return
++	}
++	h.info.BootTime = v
++}
++
++func (r *reader) hostname(h *host) {
++	v, err := os.Hostname()
++	if r.addErr(err) {
++		return
++	}
++	h.info.Hostname = v
++}
++
++func (r *reader) network(h *host) {
++	ips, macs, err := shared.Network()
++	if r.addErr(err) {
++		return
++	}
++	h.info.IPs = ips
++	h.info.MACs = macs
++}
++
++func (r *reader) kernelVersion(h *host) {
++	v, err := kernelVersion()
++	if r.addErr(err) {
++		return
++	}
++	h.info.KernelVersion = v
++}
++
++func (r *reader) os(h *host) {
++	v, err := operatingSystem()
++	if r.addErr(err) {
++		return
++	}
++	h.info.OS = v
++}
++
++func (r *reader) time(h *host) {
*** 1426 LINES SKIPPED ***