Logs and Conf

This commit is contained in:
aceberg 2025-07-26 17:03:27 +07:00
parent 595f04540b
commit 4d820890bb
15 changed files with 94 additions and 79 deletions

View file

@ -29,8 +29,8 @@ func main() {
// http.ListenAndServe("localhost:8085", nil) // http.ListenAndServe("localhost:8085", nil)
// }() // }()
// Generate AppConfig // Make AppConfig
conf.Generate(*dirPtr, *nodePtr) conf.Start(*dirPtr, *nodePtr)
gdb.Start() gdb.Start()

View file

@ -62,7 +62,7 @@ export const apiPortScan = async (ip:string, port:number) => {
}; };
export const apiGetHistory = async (mac:string) => { export const apiGetHistory = async (mac:string) => {
const url = apiPath+'/api/history/'+mac+'/?num=200'; const url = apiPath+'/api/history/'+mac+'/?num=210';
const hosts = await (await fetch(url)).json(); const hosts = await (await fetch(url)).json();
return hosts; return hosts;

View file

@ -17,7 +17,7 @@ import (
func getAllHosts(c *gin.Context) { func getAllHosts(c *gin.Context) {
allHosts := gdb.Select("now") allHosts, _ := gdb.Select("now")
c.IndentedJSON(http.StatusOK, allHosts) c.IndentedJSON(http.StatusOK, allHosts)
} }
@ -34,7 +34,7 @@ func getConfig(c *gin.Context) {
func getHistory(c *gin.Context) { func getHistory(c *gin.Context) {
hosts := gdb.Select("history") hosts, _ := gdb.Select("history")
c.IndentedJSON(http.StatusOK, hosts) c.IndentedJSON(http.StatusOK, hosts)
} }
@ -120,7 +120,7 @@ func getStatus(c *gin.Context) {
var status models.Stat var status models.Stat
var searchHosts []models.Host var searchHosts []models.Host
allHosts := gdb.Select("now") allHosts, _ := gdb.Select("now")
iface := c.Param("iface") iface := c.Param("iface")
iface = iface[1:] iface = iface[1:]

View file

@ -1,13 +1,14 @@
package api package api
import ( import (
"log/slog"
"net/http" "net/http"
"strconv" "strconv"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/aceberg/WatchYourLAN/internal/conf" "github.com/aceberg/WatchYourLAN/internal/conf"
"github.com/aceberg/WatchYourLAN/internal/gdb"
"github.com/aceberg/WatchYourLAN/internal/routines"
) )
func saveConfigHandler(c *gin.Context) { func saveConfigHandler(c *gin.Context) {
@ -21,8 +22,6 @@ func saveConfigHandler(c *gin.Context) {
conf.Write(conf.AppConfig) conf.Write(conf.AppConfig)
slog.Info("Writing new config to " + conf.AppConfig.ConfPath)
c.Redirect(http.StatusFound, c.Request.Referer()) c.Redirect(http.StatusFound, c.Request.Referer())
} }
@ -32,8 +31,14 @@ func saveSettingsHandler(c *gin.Context) {
conf.AppConfig.ArpArgs = c.PostForm("arpargs") conf.AppConfig.ArpArgs = c.PostForm("arpargs")
conf.AppConfig.Ifaces = c.PostForm("ifaces") conf.AppConfig.Ifaces = c.PostForm("ifaces")
conf.AppConfig.UseDB = c.PostForm("usedb") useDB := c.PostForm("usedb")
conf.AppConfig.PGConnect = c.PostForm("pgconnect") pgConnect := c.PostForm("pgconnect")
if useDB != conf.AppConfig.UseDB || pgConnect != conf.AppConfig.PGConnect {
conf.AppConfig.UseDB = c.PostForm("usedb")
conf.AppConfig.PGConnect = c.PostForm("pgconnect")
gdb.Connect()
}
timeout := c.PostForm("timeout") timeout := c.PostForm("timeout")
trimHist := c.PostForm("trim") trimHist := c.PostForm("trim")
@ -50,11 +55,7 @@ func saveSettingsHandler(c *gin.Context) {
conf.Write(conf.AppConfig) conf.Write(conf.AppConfig)
slog.Debug("ARP_STRS", "", conf.AppConfig.ArpArgs) routines.ScanRestart()
slog.Info("Writing new config to " + conf.AppConfig.ConfPath)
// TODO:
// updateRoutines() // routines-upd.go
c.Redirect(http.StatusFound, c.Request.Referer()) c.Redirect(http.StatusFound, c.Request.Referer())
} }
@ -65,24 +66,14 @@ func saveInfluxHandler(c *gin.Context) {
conf.AppConfig.InfluxToken = c.PostForm("token") conf.AppConfig.InfluxToken = c.PostForm("token")
conf.AppConfig.InfluxOrg = c.PostForm("org") conf.AppConfig.InfluxOrg = c.PostForm("org")
conf.AppConfig.InfluxBucket = c.PostForm("bucket") conf.AppConfig.InfluxBucket = c.PostForm("bucket")
enable := c.PostForm("enable") enable := c.PostForm("enable")
skip := c.PostForm("skip") skip := c.PostForm("skip")
conf.AppConfig.InfluxEnable = enable == "on"
if enable == "on" { conf.AppConfig.InfluxSkipTLS = skip == "on"
conf.AppConfig.InfluxEnable = true
} else {
conf.AppConfig.InfluxEnable = false
}
if skip == "on" {
conf.AppConfig.InfluxSkipTLS = true
} else {
conf.AppConfig.InfluxSkipTLS = false
}
conf.Write(conf.AppConfig) conf.Write(conf.AppConfig)
slog.Info("Writing new config to " + conf.AppConfig.ConfPath)
c.Redirect(http.StatusFound, c.Request.Referer()) c.Redirect(http.StatusFound, c.Request.Referer())
} }
@ -93,7 +84,5 @@ func savePrometheusHandler(c *gin.Context) {
conf.Write(conf.AppConfig) conf.Write(conf.AppConfig)
slog.Info("Writing new config to " + conf.AppConfig.ConfPath)
c.Redirect(http.StatusFound, c.Request.Referer()) c.Redirect(http.StatusFound, c.Request.Referer())
} }

View file

@ -8,8 +8,8 @@ import (
// AppConfig - app config // AppConfig - app config
var AppConfig models.Conf var AppConfig models.Conf
// Generate - initial config // Start - initial config
func Generate(dirPath, nodePath string) { func Start(dirPath, nodePath string) {
confPath := dirPath + "/config_v2.yaml" confPath := dirPath + "/config_v2.yaml"
check.Path(confPath) check.Path(confPath)

View file

@ -1,6 +1,8 @@
package conf package conf
import ( import (
"log/slog"
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/aceberg/WatchYourLAN/internal/check" "github.com/aceberg/WatchYourLAN/internal/check"
@ -10,6 +12,8 @@ import (
// Write - write config to file // Write - write config to file
func Write(config models.Conf) { func Write(config models.Conf) {
slog.Info("Writing new config to " + config.ConfPath)
viper.SetConfigFile(config.ConfPath) viper.SetConfigFile(config.ConfPath)
viper.SetConfigType("yaml") viper.SetConfigType("yaml")

View file

@ -1,16 +1,17 @@
package gdb package gdb
import ( import (
"github.com/aceberg/WatchYourLAN/internal/check"
"github.com/aceberg/WatchYourLAN/internal/models" "github.com/aceberg/WatchYourLAN/internal/models"
) )
// Select - get all hosts // Select - get all hosts
func Select(table string) (dbHosts []models.Host) { func Select(table string) (dbHosts []models.Host, ok bool) {
tab := db.Table(table) tab := db.Table(table)
tab.Find(&dbHosts) err := tab.Find(&dbHosts).Error
return dbHosts return dbHosts, !check.IfError(err)
} }
// SelectByID - get host by ID // SelectByID - get host by ID
@ -31,7 +32,7 @@ func SelectByMAC(mac string) (hosts []models.Host) {
return hosts return hosts
} }
// SelectByDate - get all hosts by MAC // SelectByDate - get all hosts by MAC and DATE
func SelectByDate(mac, date string) (hosts []models.Host) { func SelectByDate(mac, date string) (hosts []models.Host) {
tab := db.Table("history") tab := db.Table("history")

View file

@ -19,12 +19,12 @@ import (
) )
var db *gorm.DB var db *gorm.DB
var gormConf *gorm.Config
// Start working with DB // Start working with DB
func Start() { func Start() {
var tab *gorm.DB var tab *gorm.DB
var err error var err error
var pgFail bool
newLogger := logger.New( newLogger := logger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), log.New(os.Stdout, "\r\n", log.LstdFlags),
@ -35,7 +35,7 @@ func Start() {
Colorful: true, Colorful: true,
}, },
) )
gormConf := &gorm.Config{ gormConf = &gorm.Config{
Logger: newLogger, Logger: newLogger,
NamingStrategy: schema.NamingStrategy{ NamingStrategy: schema.NamingStrategy{
NoLowerCase: true, NoLowerCase: true,
@ -43,26 +43,7 @@ func Start() {
}, },
} }
// Choose DB and connect Connect()
if conf.AppConfig.UseDB == "postgres" {
db, err = gorm.Open(postgres.Open(conf.AppConfig.PGConnect), gormConf)
if err != nil {
pgFail = true
slog.Error("PostgreSQL connection error:", "err", err)
slog.Warn("Falling back to SQLite")
}
}
if pgFail || conf.AppConfig.UseDB != "postgres" {
db, err = gorm.Open(sqlite.Open(conf.AppConfig.DBPath), gormConf)
check.IfError(err)
db.Exec("PRAGMA journal_mode = wal;")
db.Exec("PRAGMA busy_timeout = 5000;")
}
// Migrate the schema // Migrate the schema
tab = db.Table("now") tab = db.Table("now")
@ -73,3 +54,33 @@ func Start() {
err = tab.AutoMigrate(&models.Host{}) err = tab.AutoMigrate(&models.Host{})
check.IfError(err) check.IfError(err)
} }
// Connect - choose DB and connect
func Connect() {
var err error
var pgFail bool
if conf.AppConfig.UseDB == "postgres" {
db, err = gorm.Open(postgres.Open(conf.AppConfig.PGConnect), gormConf)
if err != nil {
pgFail = true
slog.Error("PostgreSQL connection error:", "err", err)
slog.Warn("Falling back to SQLite")
} else {
slog.Info("Connected to DB: PostgreSQL")
}
}
if pgFail || conf.AppConfig.UseDB != "postgres" {
db, err = gorm.Open(sqlite.Open(conf.AppConfig.DBPath), gormConf)
if !check.IfError(err) {
slog.Info("Connected to DB: SQLite")
db.Exec("PRAGMA journal_mode = wal;")
db.Exec("PRAGMA busy_timeout = 5000;")
}
}
}

View file

@ -4,18 +4,20 @@ import (
"net/http" "net/http"
"strconv" "strconv"
"github.com/aceberg/WatchYourLAN/internal/models"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/aceberg/WatchYourLAN/internal/conf"
"github.com/aceberg/WatchYourLAN/internal/models"
) )
// Handler - display Prometheus metrics // Handler - display Prometheus metrics
func Handler(enabled bool) func(c *gin.Context) { func Handler() func(c *gin.Context) {
h := promhttp.Handler() h := promhttp.Handler()
return func(c *gin.Context) { return func(c *gin.Context) {
if !enabled { if !conf.AppConfig.PrometheusEnable {
c.AbortWithStatus(http.StatusNotFound) c.AbortWithStatus(http.StatusNotFound)
return return
} }

View file

@ -15,7 +15,7 @@ func ScanRestart() {
close(quitScan) close(quitScan)
slog.Debug("Restarting scan routine") slog.Info("Restarting scan routine")
setLogLevel() setLogLevel()
quitScan = make(chan bool) quitScan = make(chan bool)
@ -25,18 +25,16 @@ func ScanRestart() {
func setLogLevel() { func setLogLevel() {
var level slog.Level var level slog.Level
slog.Info("Log level: " + conf.AppConfig.LogLevel)
switch conf.AppConfig.LogLevel { switch conf.AppConfig.LogLevel {
case "debug": case "debug":
slog.Info("Log level=DEBUG")
level = slog.LevelDebug level = slog.LevelDebug
case "info": case "info":
slog.Info("Log level=INFO")
level = slog.LevelInfo level = slog.LevelInfo
case "warn": case "warn":
slog.Info("Log level=WARN")
level = slog.LevelWarn level = slog.LevelWarn
case "error": case "error":
slog.Info("Log level=ERROR")
level = slog.LevelError level = slog.LevelError
default: default:
slog.Error("Invalid log level. Setting default level INFO") slog.Error("Invalid log level. Setting default level INFO")

View file

@ -47,7 +47,11 @@ func startScan(quit chan bool) {
func compareHosts(foundHostsMap map[string]models.Host) { func compareHosts(foundHostsMap map[string]models.Host) {
allHosts := gdb.Select("now") allHosts, ok := gdb.Select("now")
if !ok {
return
}
for _, aHost := range allHosts { for _, aHost := range allHosts {
fHost, exists := foundHostsMap[aHost.Mac] fHost, exists := foundHostsMap[aHost.Mac]

View file

@ -10,8 +10,11 @@ import (
// HistoryTrim - routine for History // HistoryTrim - routine for History
func HistoryTrim() { func HistoryTrim() {
go func() { go func() {
for { for {
time.Sleep(time.Duration(1) * time.Hour) // Every hour
hours := conf.AppConfig.TrimHist hours := conf.AppConfig.TrimHist
nowMinus := time.Now().Add(-time.Duration(hours) * time.Hour) nowMinus := time.Now().Add(-time.Duration(hours) * time.Hour)
date := nowMinus.Format("2006-01-02 15:04:05") date := nowMinus.Format("2006-01-02 15:04:05")
@ -20,8 +23,6 @@ func HistoryTrim() {
n := gdb.DeleteOldHistory(date) n := gdb.DeleteOldHistory(date)
slog.Info("Removed records from History", "n", n) slog.Info("Removed records from History", "n", n)
time.Sleep(time.Duration(1) * time.Hour) // Every hour
} }
}() }()
} }

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
VERSION=2.1.2 VERSION=2.1.3

View file

@ -25,19 +25,24 @@ var pubFS embed.FS
// Gui - start web server // Gui - start web server
func Gui() { func Gui() {
const (
colorCyan = "\033[36m"
colorReset = "\033[0m"
)
file, err := pubFS.ReadFile("public/version") file, err := pubFS.ReadFile("public/version")
check.IfError(err) check.IfError(err)
conf.AppConfig.Version = string(file)[8:] conf.AppConfig.Version = string(file)[8:]
slog.Info("Config dir", "path", conf.AppConfig.DirPath)
address := conf.AppConfig.Host + ":" + conf.AppConfig.Port address := conf.AppConfig.Host + ":" + conf.AppConfig.Port
slog.Info("=================================== ") slog.Info(colorCyan + "\n=================================== " +
slog.Info("Version: " + conf.AppConfig.Version) "\n WatchYourLAN Version: " + conf.AppConfig.Version +
slog.Info("Web GUI at http://" + address) "\n Config dir: " + conf.AppConfig.DirPath +
slog.Info("=================================== ") "\n Default DB: " + conf.AppConfig.UseDB +
"\n Log level: " + conf.AppConfig.LogLevel +
"\n Web GUI: http://" + address +
"\n=================================== " + colorReset)
gin.SetMode(gin.ReleaseMode) gin.SetMode(gin.ReleaseMode)
router := gin.New() router := gin.New()
@ -52,7 +57,7 @@ func Gui() {
router.GET("/config", indexHandler) // index.go router.GET("/config", indexHandler) // index.go
router.GET("/history", indexHandler) // index.go router.GET("/history", indexHandler) // index.go
router.GET("/host/*any", indexHandler) // index.go router.GET("/host/*any", indexHandler) // index.go
router.GET("/metrics", prometheus.Handler(conf.AppConfig.PrometheusEnable)) router.GET("/metrics", prometheus.Handler())
api.Routes(router) api.Routes(router)