From 1d998ccee993d81977fb75b31fb0f1278533c062 Mon Sep 17 00:00:00 2001 From: Francesco Manghi Date: Mon, 16 Feb 2026 11:58:19 +0100 Subject: [PATCH 01/15] Added support for Network Name and Device Position in InfluxDB consiguration --- README.md | 4 ++++ backend/internal/api/config.go | 2 ++ backend/internal/conf/read.go | 4 ++++ backend/internal/conf/write.go | 2 ++ backend/internal/influx/influx.go | 19 ++++++++++++++----- backend/internal/models/models.go | 2 ++ frontend/src/components/Config/Influx.tsx | 8 ++++++++ frontend/src/functions/exports.ts | 4 ++++ 8 files changed, 40 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1a97e7e..b45821a 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,8 @@ This config matches Grafana's config for InfluxDB data source | INFLUX_BUCKET | InfluxDB2 bucket | | test | | INFLUX_ORG | InfluxDB2 org | | home | | INFLUX_TOKEN | Secret token, generated by InfluxDB2 | | | +| INFLUX_NETWORK_NAME | Tag value for network name | | Home LAN | +| INFLUX_DEVICE_LOCATION | Tag value for device location | | Server Rack | ### Prometheus config This config configures the Prometheus data source @@ -143,7 +145,9 @@ host: 0.0.0.0 ifaces: enp4s0 influx_addr: "" influx_bucket: "" +influx_device_location: "" influx_enable: false +influx_network_name: "" influx_org: "" influx_skip_tls: false influx_token: "" diff --git a/backend/internal/api/config.go b/backend/internal/api/config.go index 9f1999c..64e7538 100644 --- a/backend/internal/api/config.go +++ b/backend/internal/api/config.go @@ -66,6 +66,8 @@ func saveInfluxHandler(c *gin.Context) { conf.AppConfig.InfluxToken = c.PostForm("token") conf.AppConfig.InfluxOrg = c.PostForm("org") conf.AppConfig.InfluxBucket = c.PostForm("bucket") + conf.AppConfig.InfluxNetworkName = c.PostForm("network_name") + conf.AppConfig.InfluxDeviceLocation = c.PostForm("device_location") enable := c.PostForm("enable") skip := c.PostForm("skip") diff --git a/backend/internal/conf/read.go b/backend/internal/conf/read.go index 6f5d0ae..4775076 100644 --- a/backend/internal/conf/read.go +++ b/backend/internal/conf/read.go @@ -28,6 +28,8 @@ func read(path string) (config models.Conf) { viper.SetDefault("PG_CONNECT", "") viper.SetDefault("INFLUX_ENABLE", false) + viper.SetDefault("INFLUX_NETWORK_NAME", "") + viper.SetDefault("INFLUX_DEVICE_LOCATION", "") viper.SetDefault("PROMETHEUS_ENABLE", false) @@ -60,6 +62,8 @@ func read(path string) (config models.Conf) { config.InfluxToken, _ = viper.Get("INFLUX_TOKEN").(string) config.InfluxOrg, _ = viper.Get("INFLUX_ORG").(string) config.InfluxBucket, _ = viper.Get("INFLUX_BUCKET").(string) + config.InfluxNetworkName, _ = viper.Get("INFLUX_NETWORK_NAME").(string) + config.InfluxDeviceLocation, _ = viper.Get("INFLUX_DEVICE_LOCATION").(string) config.PrometheusEnable = viper.GetBool("PROMETHEUS_ENABLE") diff --git a/backend/internal/conf/write.go b/backend/internal/conf/write.go index 201ecb9..6013cbe 100644 --- a/backend/internal/conf/write.go +++ b/backend/internal/conf/write.go @@ -40,6 +40,8 @@ func Write(config models.Conf) { viper.Set("influx_token", config.InfluxToken) viper.Set("influx_org", config.InfluxOrg) viper.Set("influx_bucket", config.InfluxBucket) + viper.Set("influx_network_name", config.InfluxNetworkName) + viper.Set("influx_device_location", config.InfluxDeviceLocation) viper.Set("PROMETHEUS_ENABLE", config.PrometheusEnable) diff --git a/backend/internal/influx/influx.go b/backend/internal/influx/influx.go index 0c32050..8ab798b 100644 --- a/backend/internal/influx/influx.go +++ b/backend/internal/influx/influx.go @@ -13,6 +13,14 @@ import ( "github.com/aceberg/WatchYourLAN/internal/models" ) +func tagValueEscaped(value string) string { + value = strings.ReplaceAll(value, " ", "\\ ") + value = strings.ReplaceAll(value, ",", "\\,") + value = strings.ReplaceAll(value, "=", "\\=") + + return value +} + // Add - write data to InfluxDB2 func Add(appConfig models.Conf, oneHist models.Host) { var ctx context.Context @@ -29,15 +37,16 @@ func Add(appConfig models.Conf, oneHist models.Host) { if ping { writeAPI := client.WriteAPIBlocking(appConfig.InfluxOrg, appConfig.InfluxBucket) - // Escape special characters in strings - oneHist.Name = strings.ReplaceAll(oneHist.Name, " ", "\\ ") - oneHist.Name = strings.ReplaceAll(oneHist.Name, ",", "\\,") - oneHist.Name = strings.ReplaceAll(oneHist.Name, "=", "\\=") + // Escape special characters in tag values + oneHist.Name = tagValueEscaped(oneHist.Name) if oneHist.Name == "" { oneHist.Name = "unknown" } - line := fmt.Sprintf("WatchYourLAN,IP=%s,iface=%s,name=%s,mac=%s,known=%d state=%d", oneHist.IP, oneHist.Iface, oneHist.Name, oneHist.Mac, oneHist.Known, oneHist.Now) + networkName := tagValueEscaped(appConfig.InfluxNetworkName) + deviceLocation := tagValueEscaped(appConfig.InfluxDeviceLocation) + + line := fmt.Sprintf("WatchYourLAN,IP=%s,iface=%s,name=%s,mac=%s,known=%d,network_name=%s,device_location=%s state=%d", oneHist.IP, oneHist.Iface, oneHist.Name, oneHist.Mac, oneHist.Known, networkName, deviceLocation, oneHist.Now) // slog.Debug("Writing to InfluxDB", "line", line) err = writeAPI.WriteRecord(context.Background(), line) diff --git a/backend/internal/models/models.go b/backend/internal/models/models.go index 7fcfd16..9872446 100644 --- a/backend/internal/models/models.go +++ b/backend/internal/models/models.go @@ -27,6 +27,8 @@ type Conf struct { InfluxToken string InfluxOrg string InfluxBucket string + InfluxNetworkName string + InfluxDeviceLocation string InfluxSkipTLS bool // Prometheus PrometheusEnable bool diff --git a/frontend/src/components/Config/Influx.tsx b/frontend/src/components/Config/Influx.tsx index fa6b658..4d0ceab 100644 --- a/frontend/src/components/Config/Influx.tsx +++ b/frontend/src/components/Config/Influx.tsx @@ -36,6 +36,14 @@ function Influx() { Bucket + + Network Name + + + + Device Location + + Skip TLS verify diff --git a/frontend/src/functions/exports.ts b/frontend/src/functions/exports.ts index 2cb1ea4..12ebf5e 100644 --- a/frontend/src/functions/exports.ts +++ b/frontend/src/functions/exports.ts @@ -36,6 +36,8 @@ export interface Conf { InfluxToken: string; InfluxOrg: string; InfluxBucket: string; + InfluxNetworkName: string; + InfluxDeviceLocation: string; InfluxSkipTLS: boolean; // Prometheus PrometheusEnable: boolean; @@ -75,6 +77,8 @@ export const emptyConf:Conf = { InfluxToken: "", InfluxOrg: "", InfluxBucket: "", + InfluxNetworkName: "", + InfluxDeviceLocation: "", InfluxSkipTLS: false, PrometheusEnable: false, }; From ef7b9a30b5ad5c5c28e51c427ea5e233e5740128 Mon Sep 17 00:00:00 2001 From: Francesco Manghi Date: Mon, 16 Feb 2026 13:25:42 +0100 Subject: [PATCH 02/15] updated frontend --- backend/internal/web/public/assets/Config.js | 2 +- backend/internal/web/public/assets/index.js | 2 +- frontend/package-lock.json | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/internal/web/public/assets/Config.js b/backend/internal/web/public/assets/Config.js index 894ad64..997e30b 100644 --- a/backend/internal/web/public/assets/Config.js +++ b/backend/internal/web/public/assets/Config.js @@ -1 +1 @@ -import{c as J,o as K,a as X,t,i as r,b,s as H,d as W,e as c,S as V,f as e,F as M,g as Z,h as tt,j as Q}from"./index.js";var et=t('
About ()
Swagger API docs/swagger/index.html
Local node-bootstrap URLlocal themes and fonts (optional). If empty, the app will pull everything from cdn
Shoutrrr URLprovides notifications to Discord, Email, Gotify, Telegram and other services. Link to documentation
Interfacesone or more, space separated
Timeout (seconds)time between scans
Args for arp-scanpass your own arguments to arp-scan. Enable debug log level to see resulting command. (Example: -r 1). See docs for more
Arp Stringscan setup scans for vlans, docker0 and etcetera. See docs for more
Trim Historyremove history after (hours)
PG Connect URLaddress to connect to PostgreSQL DB. (Example: postgres://username:password@192.168.0.1:5432/dbname?sslmode=disable). Full list of URL parameters here');function rt(){const[i,d]=J(""),[s,a]=J("");return K(async()=>{const l=await X();d(l),a("https://github.com/aceberg/WatchYourLAN/releases/tag/"+l)}),(()=>{var l=et(),n=l.firstChild,o=n.firstChild,p=o.nextSibling;return r(p,i),b(()=>H(p,"href",s())),l})()}var lt=t("