Browse Source

auto update script executed

tobychui 1 year ago
parent
commit
f299b7970c
10 changed files with 294 additions and 48 deletions
  1. 6 7
      acme.go
  2. 5 6
      cert.go
  3. 7 8
      config.go
  4. 12 0
      log/zr_2023-10.log
  5. 10 4
      main.go
  6. 103 0
      mod/info/logger/logger.go
  7. 122 0
      mod/info/logviewer/logviewer.go
  8. 15 16
      reverseproxy.go
  9. 13 5
      start.go
  10. 1 2
      wrappers.go

+ 6 - 7
acme.go

@@ -4,7 +4,6 @@ import (
 	"encoding/json"
 	"fmt"
 	"io"
-	"log"
 	"math/rand"
 	"net/http"
 	"regexp"
@@ -29,7 +28,7 @@ func getRandomPort(minPort int) int {
 
 // init the new ACME instance
 func initACME() *acme.ACMEHandler {
-	log.Println("Starting ACME handler")
+	SystemWideLogger.Println("Starting ACME handler")
 	rand.Seed(time.Now().UnixNano())
 	// Generate a random port above 30000
 	port := getRandomPort(30000)
@@ -44,7 +43,7 @@ func initACME() *acme.ACMEHandler {
 
 // create the special routing rule for ACME
 func acmeRegisterSpecialRoutingRule() {
-	log.Println("Assigned temporary port:" + acmeHandler.Getport())
+	SystemWideLogger.Println("Assigned temporary port:" + acmeHandler.Getport())
 
 	err := dynamicProxyRouter.AddRoutingRules(&dynamicproxy.RoutingRule{
 		ID: "acme-autorenew",
@@ -79,7 +78,7 @@ func acmeRegisterSpecialRoutingRule() {
 	})
 
 	if err != nil {
-		log.Println("[Err] " + err.Error())
+		SystemWideLogger.PrintAndLog("ACME", "Unable register temp port for DNS resolver", err)
 	}
 }
 
@@ -89,7 +88,7 @@ func AcmeCheckAndHandleRenewCertificate(w http.ResponseWriter, r *http.Request)
 	if dynamicProxyRouter.Option.Port == 443 {
 		//Enable port 80 to 443 redirect
 		if !dynamicProxyRouter.Option.ForceHttpsRedirect {
-			log.Println("Temporary enabling HTTP to HTTPS redirect for ACME certificate renew requests")
+			SystemWideLogger.Println("Temporary enabling HTTP to HTTPS redirect for ACME certificate renew requests")
 			dynamicProxyRouter.UpdateHttpToHttpsRedirectSetting(true)
 		} else {
 			//Set this to true, so after renew, do not turn it off
@@ -110,7 +109,7 @@ func AcmeCheckAndHandleRenewCertificate(w http.ResponseWriter, r *http.Request)
 	if dynamicProxyRouter.Option.Port == 443 {
 		if !isForceHttpsRedirectEnabledOriginally {
 			//Default is off. Turn the redirection off
-			log.Println("Restoring HTTP to HTTPS redirect settings")
+			SystemWideLogger.PrintAndLog("ACME", "Restoring HTTP to HTTPS redirect settings", nil)
 			dynamicProxyRouter.UpdateHttpToHttpsRedirectSetting(false)
 		}
 	}
@@ -130,7 +129,7 @@ func HandleACMEPreferredCA(w http.ResponseWriter, r *http.Request) {
 		acme.IsSupportedCA(ca)
 		//Set the new config
 		sysdb.Write("acmepref", "prefca", ca)
-		log.Println("Updating prefered ACME CA to " + ca)
+		SystemWideLogger.Println("Updating prefered ACME CA to " + ca)
 		utils.SendOK(w)
 	}
 

+ 5 - 6
cert.go

@@ -6,7 +6,6 @@ import (
 	"encoding/pem"
 	"fmt"
 	"io"
-	"log"
 	"net/http"
 	"os"
 	"path/filepath"
@@ -128,7 +127,7 @@ func handleListDomains(w http.ResponseWriter, r *http.Request) {
 		certBtyes, err := os.ReadFile(certFilepath)
 		if err != nil {
 			// Unable to load this file
-			log.Println("Unable to load certificate: " + certFilepath)
+			SystemWideLogger.PrintAndLog("TLS", "Unable to load certificate: "+certFilepath, err)
 			continue
 		} else {
 			// Cert loaded. Check its expiry time
@@ -182,11 +181,11 @@ func handleToggleTLSProxy(w http.ResponseWriter, r *http.Request) {
 	} else {
 		if newState == "true" {
 			sysdb.Write("settings", "usetls", true)
-			log.Println("Enabling TLS mode on reverse proxy")
+			SystemWideLogger.Println("Enabling TLS mode on reverse proxy")
 			dynamicProxyRouter.UpdateTLSSetting(true)
 		} else if newState == "false" {
 			sysdb.Write("settings", "usetls", false)
-			log.Println("Disabling TLS mode on reverse proxy")
+			SystemWideLogger.Println("Disabling TLS mode on reverse proxy")
 			dynamicProxyRouter.UpdateTLSSetting(false)
 		} else {
 			utils.SendErrorResponse(w, "invalid state given. Only support true or false")
@@ -213,11 +212,11 @@ func handleSetTlsRequireLatest(w http.ResponseWriter, r *http.Request) {
 	} else {
 		if newState == "true" {
 			sysdb.Write("settings", "forceLatestTLS", true)
-			log.Println("Updating minimum TLS version to v1.2 or above")
+			SystemWideLogger.Println("Updating minimum TLS version to v1.2 or above")
 			dynamicProxyRouter.UpdateTLSVersion(true)
 		} else if newState == "false" {
 			sysdb.Write("settings", "forceLatestTLS", false)
-			log.Println("Updating minimum TLS version to v1.0 or above")
+			SystemWideLogger.Println("Updating minimum TLS version to v1.0 or above")
 			dynamicProxyRouter.UpdateTLSVersion(false)
 		} else {
 			utils.SendErrorResponse(w, "invalid state given")

+ 7 - 8
config.go

@@ -5,7 +5,6 @@ import (
 	"encoding/json"
 	"fmt"
 	"io"
-	"log"
 	"net/http"
 	"os"
 	"path/filepath"
@@ -62,11 +61,11 @@ func SaveReverseProxyEndpointToFile(proxyEndpoint *dynamicproxy.ProxyEndpoint) e
 func RemoveReverseProxyConfigFile(rootname string) error {
 	filename := getFilenameFromRootName(rootname)
 	removePendingFile := strings.ReplaceAll(filepath.Join("./conf/proxy/", filename), "\\", "/")
-	log.Println("Config Removed: ", removePendingFile)
+	SystemWideLogger.Println("Config Removed: ", removePendingFile)
 	if utils.FileExists(removePendingFile) {
 		err := os.Remove(removePendingFile)
 		if err != nil {
-			log.Println(err.Error())
+			SystemWideLogger.PrintAndLog("Proxy", "Unabel to remove config file", err)
 			return err
 		}
 	}
@@ -194,14 +193,14 @@ func ExportConfigAsZip(w http.ResponseWriter, r *http.Request) {
 		//Also zip in the sysdb
 		zipFile, err := zipWriter.Create("sys.db")
 		if err != nil {
-			log.Println("[Backup] Unable to zip sysdb: " + err.Error())
+			SystemWideLogger.PrintAndLog("Backup", "Unable to zip sysdb", err)
 			return
 		}
 
 		// Open the file on disk
 		file, err := os.Open("sys.db")
 		if err != nil {
-			log.Println("[Backup] Unable to open sysdb: " + err.Error())
+			SystemWideLogger.PrintAndLog("Backup", "Unable to open sysdb", err)
 			return
 		}
 		defer file.Close()
@@ -209,7 +208,7 @@ func ExportConfigAsZip(w http.ResponseWriter, r *http.Request) {
 		// Copy the file contents to the zip file
 		_, err = io.Copy(zipFile, file)
 		if err != nil {
-			log.Println(err)
+			SystemWideLogger.Println(err)
 			return
 		}
 
@@ -314,12 +313,12 @@ func ImportConfigFromZip(w http.ResponseWriter, r *http.Request) {
 
 	// Send a success response
 	w.WriteHeader(http.StatusOK)
-	log.Println("Configuration restored")
+	SystemWideLogger.Println("Configuration restored")
 	fmt.Fprintln(w, "Configuration restored")
 
 	if restoreDatabase {
 		go func() {
-			log.Println("Database altered. Restarting in 3 seconds...")
+			SystemWideLogger.Println("Database altered. Restarting in 3 seconds...")
 			time.Sleep(3 * time.Second)
 			os.Exit(0)
 		}()

+ 12 - 0
log/zr_2023-10.log

@@ -0,0 +1,12 @@
+2023-10-27 11:18:05.094437|info             [INFO]
+2023-10-27 11:20:33.331844|info             [INFO]Serving inbound port 8080
+2023-10-27 11:36:29.816434|info             [INFO]Starting ACME handler
+2023-10-27 11:36:29.827264|info             [INFO]Serving inbound port 8080
+2023-10-27 11:36:29.827264|info             [INFO]TLS mode enabled. Serving proxxy request with TLS
+2023-10-27 11:36:29.827264|info             [INFO]Force latest TLS mode disabled. Minimum TLS version is set to v1.0
+2023-10-27 11:36:29.827779|info             [INFO]Force HTTPS mode disabled
+2023-10-27 11:36:30.148036|info             [INFO]Dynamic Reverse Proxy service started
+2023-10-27 11:36:30.334689|info             [INFO]Assigned temporary port:33212
+2023-10-27 11:36:30.335345|info             [INFO]Zoraxy started. Visit control panel at http://localhost:8000
+2023-10-27 11:36:59.911265|info             [INFO]mDNS Startup scan completed
+2023-10-27 11:37:12.252197|info             [INFO]Uptime Monitor background service started

+ 10 - 4
main.go

@@ -20,6 +20,7 @@ import (
 	"imuslab.com/zoraxy/mod/email"
 	"imuslab.com/zoraxy/mod/ganserv"
 	"imuslab.com/zoraxy/mod/geodb"
+	"imuslab.com/zoraxy/mod/info/logger"
 	"imuslab.com/zoraxy/mod/mdns"
 	"imuslab.com/zoraxy/mod/netstat"
 	"imuslab.com/zoraxy/mod/pathrule"
@@ -44,6 +45,7 @@ var acmeAutoRenewInterval = flag.Int("autorenew", 86400, "ACME auto TLS/SSL cert
 var enableHighSpeedGeoIPLookup = flag.Bool("fastgeoip", false, "Enable high speed geoip lookup, require 1GB extra memory (Not recommend for low end devices)")
 var staticWebServerRoot = flag.String("webroot", "./www", "Static web server root folder. Only allow chnage in start paramters")
 var allowWebFileManager = flag.Bool("webfm", true, "Enable web file manager for static web server root folder")
+var logOutputToFile = flag.Bool("log", true, "Log terminal output to file")
 
 var (
 	name        = "Zoraxy"
@@ -80,8 +82,9 @@ var (
 	staticWebServer    *webserv.WebServer      //Static web server for hosting simple stuffs
 
 	//Helper modules
-	EmailSender    *email.Sender        //Email sender that handle email sending
-	AnalyticLoader *analytic.DataLoader //Data loader for Zoraxy Analytic
+	EmailSender      *email.Sender        //Email sender that handle email sending
+	AnalyticLoader   *analytic.DataLoader //Data loader for Zoraxy Analytic
+	SystemWideLogger *logger.Logger       //Logger for Zoraxy
 )
 
 // Kill signal handler. Do something before the system the core terminate.
@@ -116,6 +119,9 @@ func ShutdownSeq() {
 	fmt.Println("- Cleaning up tmp files")
 	os.RemoveAll("./tmp")
 
+	fmt.Println("- Closing system wide logger")
+	SystemWideLogger.Close()
+
 	//Close database, final
 	fmt.Println("- Stopping system database")
 	sysdb.Close()
@@ -151,7 +157,7 @@ func main() {
 	}
 	uuidBytes, err := os.ReadFile(uuidRecord)
 	if err != nil {
-		log.Println("Unable to read system uuid from file system")
+		SystemWideLogger.PrintAndLog("ZeroTier", "Unable to read system uuid from file system", nil)
 		panic(err)
 	}
 	nodeUUID = string(uuidBytes)
@@ -173,7 +179,7 @@ func main() {
 	//Start the finalize sequences
 	finalSequence()
 
-	log.Println("Zoraxy started. Visit control panel at http://localhost" + handler.Port)
+	SystemWideLogger.Println("Zoraxy started. Visit control panel at http://localhost" + handler.Port)
 	err = http.ListenAndServe(handler.Port, nil)
 
 	if err != nil {

+ 103 - 0
mod/info/logger/logger.go

@@ -0,0 +1,103 @@
+package logger
+
+import (
+	"fmt"
+	"log"
+	"os"
+	"path/filepath"
+	"strconv"
+	"time"
+)
+
+/*
+	Zoraxy Logger
+
+	This script is designed to make a managed log for the Zoraxy
+	and replace the ton of log.Println in the system core
+*/
+
+type Logger struct {
+	LogToFile      bool   //Set enable write to file
+	Prefix         string //Prefix for log files
+	LogFolder      string //Folder to store the log  file
+	CurrentLogFile string //Current writing filename
+	file           *os.File
+}
+
+func NewLogger(logFilePrefix string, logFolder string, logToFile bool) (*Logger, error) {
+	err := os.MkdirAll(logFolder, 0775)
+	if err != nil {
+		return nil, err
+	}
+
+	thisLogger := Logger{
+		LogToFile: logToFile,
+		Prefix:    logFilePrefix,
+		LogFolder: logFolder,
+	}
+
+	logFilePath := thisLogger.getLogFilepath()
+	f, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0755)
+	if err != nil {
+		return nil, err
+	}
+	thisLogger.CurrentLogFile = logFilePath
+	thisLogger.file = f
+	return &thisLogger, nil
+}
+
+func (l *Logger) getLogFilepath() string {
+	year, month, _ := time.Now().Date()
+	return filepath.Join(l.LogFolder, l.Prefix+"_"+strconv.Itoa(year)+"-"+strconv.Itoa(int(month))+".log")
+}
+
+// PrintAndLog will log the message to file and print the log to STDOUT
+func (l *Logger) PrintAndLog(title string, message string, originalError error) {
+	go func() {
+		l.Log(title, message, originalError)
+	}()
+	log.Println("[" + title + "] " + message)
+}
+
+// Println is a fast snap-in replacement for log.Println
+func (l *Logger) Println(v ...interface{}) {
+	//Convert the array of interfaces into string
+	message := fmt.Sprint(v...)
+	go func() {
+		l.Log("info", string(message), nil)
+	}()
+	log.Println("[INFO] " + string(message))
+}
+
+func (l *Logger) Log(title string, errorMessage string, originalError error) {
+	l.ValidateAndUpdateLogFilepath()
+	if l.LogToFile {
+		if originalError == nil {
+			l.file.WriteString(time.Now().Format("2006-01-02 15:04:05.000000") + "|" + fmt.Sprintf("%-16s", title) + " [INFO]" + errorMessage + "\n")
+		} else {
+			l.file.WriteString(time.Now().Format("2006-01-02 15:04:05.000000") + "|" + fmt.Sprintf("%-16s", title) + " [ERROR]" + errorMessage + " " + originalError.Error() + "\n")
+		}
+	}
+
+}
+
+// Validate if the logging target is still valid (detect any months change)
+func (l *Logger) ValidateAndUpdateLogFilepath() {
+	expectedCurrentLogFilepath := l.getLogFilepath()
+	if l.CurrentLogFile != expectedCurrentLogFilepath {
+		//Change of month. Update to a new log file
+		l.file.Close()
+		f, err := os.OpenFile(expectedCurrentLogFilepath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0755)
+		if err != nil {
+			log.Println("[Logger] Unable to create new log. Logging to file disabled.")
+			l.LogToFile = false
+			return
+		}
+		l.CurrentLogFile = expectedCurrentLogFilepath
+		l.file = f
+	}
+}
+
+func (l *Logger) Close() {
+	l.file.Close()
+}

+ 122 - 0
mod/info/logviewer/logviewer.go

@@ -0,0 +1,122 @@
+package logviewer
+
+import (
+	"encoding/json"
+	"errors"
+	"io/fs"
+	"net/http"
+	"os"
+	"path/filepath"
+	"strings"
+
+	"imuslab.com/zoraxy/mod/utils"
+)
+
+type ViewerOption struct {
+	RootFolder string //The root folder to scan for log
+	Extension  string //The extension the root files use, include the . in your ext (e.g. .log)
+}
+
+type Viewer struct {
+	option *ViewerOption
+}
+
+type LogFile struct {
+	Title    string
+	Filename string
+	Fullpath string
+	Filesize int64
+}
+
+func NewLogViewer(option *ViewerOption) *Viewer {
+	return &Viewer{option: option}
+}
+
+/*
+	Log Request Handlers
+*/
+//List all the log files in the log folder. Return in map[string]LogFile format
+func (v *Viewer) HandleListLog(w http.ResponseWriter, r *http.Request) {
+	logFiles := v.ListLogFiles(false)
+	js, _ := json.Marshal(logFiles)
+	utils.SendJSONResponse(w, string(js))
+}
+
+// Read log of a given catergory and filename
+// Require GET varaible: file and catergory
+func (v *Viewer) HandleReadLog(w http.ResponseWriter, r *http.Request) {
+	filename, err := utils.GetPara(r, "file")
+	if err != nil {
+		utils.SendErrorResponse(w, "invalid filename given")
+		return
+	}
+
+	catergory, err := utils.GetPara(r, "catergory")
+	if err != nil {
+		utils.SendErrorResponse(w, "invalid catergory given")
+		return
+	}
+
+	content, err := v.LoadLogFile(strings.TrimSpace(filepath.Base(catergory)), strings.TrimSpace(filepath.Base(filename)))
+	if err != nil {
+		utils.SendErrorResponse(w, err.Error())
+		return
+	}
+
+	utils.SendTextResponse(w, content)
+}
+
+/*
+	Log Access Functions
+*/
+
+func (v *Viewer) ListLogFiles(showFullpath bool) map[string][]*LogFile {
+	result := map[string][]*LogFile{}
+	filepath.WalkDir(v.option.RootFolder, func(path string, di fs.DirEntry, err error) error {
+		if filepath.Ext(path) == v.option.Extension {
+			catergory := filepath.Base(filepath.Dir(path))
+			logList, ok := result[catergory]
+			if !ok {
+				//this catergory hasn't been scanned before.
+				logList = []*LogFile{}
+			}
+
+			fullpath := filepath.ToSlash(path)
+			if !showFullpath {
+				fullpath = ""
+			}
+
+			st, err := os.Stat(path)
+			if err != nil {
+				return nil
+			}
+
+			logList = append(logList, &LogFile{
+				Title:    strings.TrimSuffix(filepath.Base(path), filepath.Ext(path)),
+				Filename: filepath.Base(path),
+				Fullpath: fullpath,
+				Filesize: st.Size(),
+			})
+
+			result[catergory] = logList
+		}
+
+		return nil
+	})
+	return result
+}
+
+func (v *Viewer) LoadLogFile(catergory string, filename string) (string, error) {
+	logFilepath := filepath.Join(v.option.RootFolder, catergory, filename)
+	if utils.FileExists(logFilepath) {
+		//Load it
+		content, err := os.ReadFile(logFilepath)
+		if err != nil {
+			return "", err
+		}
+
+		return string(content), nil
+	} else {
+		return "", errors.New("log file not found")
+	}
+}

+ 15 - 16
reverseproxy.go

@@ -2,7 +2,6 @@ package main
 
 import (
 	"encoding/json"
-	"log"
 	"net/http"
 	"path/filepath"
 	"sort"
@@ -25,33 +24,33 @@ func ReverseProxtInit() {
 	inboundPort := 80
 	if sysdb.KeyExists("settings", "inbound") {
 		sysdb.Read("settings", "inbound", &inboundPort)
-		log.Println("Serving inbound port ", inboundPort)
+		SystemWideLogger.Println("Serving inbound port ", inboundPort)
 	} else {
-		log.Println("Inbound port not set. Using default (80)")
+		SystemWideLogger.Println("Inbound port not set. Using default (80)")
 	}
 
 	useTls := false
 	sysdb.Read("settings", "usetls", &useTls)
 	if useTls {
-		log.Println("TLS mode enabled. Serving proxxy request with TLS")
+		SystemWideLogger.Println("TLS mode enabled. Serving proxxy request with TLS")
 	} else {
-		log.Println("TLS mode disabled. Serving proxy request with plain http")
+		SystemWideLogger.Println("TLS mode disabled. Serving proxy request with plain http")
 	}
 
 	forceLatestTLSVersion := false
 	sysdb.Read("settings", "forceLatestTLS", &forceLatestTLSVersion)
 	if forceLatestTLSVersion {
-		log.Println("Force latest TLS mode enabled. Minimum TLS LS version is set to v1.2")
+		SystemWideLogger.Println("Force latest TLS mode enabled. Minimum TLS LS version is set to v1.2")
 	} else {
-		log.Println("Force latest TLS mode disabled. Minimum TLS version is set to v1.0")
+		SystemWideLogger.Println("Force latest TLS mode disabled. Minimum TLS version is set to v1.0")
 	}
 
 	forceHttpsRedirect := false
 	sysdb.Read("settings", "redirect", &forceHttpsRedirect)
 	if forceHttpsRedirect {
-		log.Println("Force HTTPS mode enabled")
+		SystemWideLogger.Println("Force HTTPS mode enabled")
 	} else {
-		log.Println("Force HTTPS mode disabled")
+		SystemWideLogger.Println("Force HTTPS mode disabled")
 	}
 
 	dprouter, err := dynamicproxy.NewDynamicProxy(dynamicproxy.RouterOption{
@@ -67,7 +66,7 @@ func ReverseProxtInit() {
 		WebDirectory:       *staticWebServerRoot,
 	})
 	if err != nil {
-		log.Println(err.Error())
+		SystemWideLogger.PrintAndLog("Proxy", "Unable to create dynamic proxy router", err)
 		return
 	}
 
@@ -78,7 +77,7 @@ func ReverseProxtInit() {
 	for _, conf := range confs {
 		record, err := LoadReverseProxyConfig(conf)
 		if err != nil {
-			log.Println("Failed to load "+filepath.Base(conf), err.Error())
+			SystemWideLogger.PrintAndLog("Proxy", "Failed to load config file: "+filepath.Base(conf), err)
 			return
 		}
 
@@ -110,7 +109,7 @@ func ReverseProxtInit() {
 				BasicAuthExceptionRules: record.BasicAuthExceptionRules,
 			})
 		} else {
-			log.Println("Unsupported endpoint type: " + record.ProxyType + ". Skipping " + filepath.Base(conf))
+			SystemWideLogger.PrintAndLog("Proxy", "Unsupported endpoint type: "+record.ProxyType+". Skipping "+filepath.Base(conf), nil)
 		}
 	}
 
@@ -119,7 +118,7 @@ func ReverseProxtInit() {
 	//reverse proxy server in front of this service
 	time.Sleep(300 * time.Millisecond)
 	dynamicProxyRouter.StartProxyService()
-	log.Println("Dynamic Reverse Proxy service started")
+	SystemWideLogger.Println("Dynamic Reverse Proxy service started")
 
 	//Add all proxy services to uptime monitor
 	//Create a uptime monitor service
@@ -130,7 +129,7 @@ func ReverseProxtInit() {
 			Interval:        300, //5 minutes
 			MaxRecordsStore: 288, //1 day
 		})
-		log.Println("Uptime Monitor background service started")
+		SystemWideLogger.Println("Uptime Monitor background service started")
 	}()
 
 }
@@ -763,11 +762,11 @@ func HandleUpdateHttpsRedirect(w http.ResponseWriter, r *http.Request) {
 		}
 		if useRedirect == "true" {
 			sysdb.Write("settings", "redirect", true)
-			log.Println("Updating force HTTPS redirection to true")
+			SystemWideLogger.Println("Updating force HTTPS redirection to true")
 			dynamicProxyRouter.UpdateHttpToHttpsRedirectSetting(true)
 		} else if useRedirect == "false" {
 			sysdb.Write("settings", "redirect", false)
-			log.Println("Updating force HTTPS redirection to false")
+			SystemWideLogger.Println("Updating force HTTPS redirection to false")
 			dynamicProxyRouter.UpdateHttpToHttpsRedirectSetting(false)
 		}
 

+ 13 - 5
start.go

@@ -14,6 +14,7 @@ import (
 	"imuslab.com/zoraxy/mod/dynamicproxy/redirection"
 	"imuslab.com/zoraxy/mod/ganserv"
 	"imuslab.com/zoraxy/mod/geodb"
+	"imuslab.com/zoraxy/mod/info/logger"
 	"imuslab.com/zoraxy/mod/mdns"
 	"imuslab.com/zoraxy/mod/netstat"
 	"imuslab.com/zoraxy/mod/pathrule"
@@ -93,10 +94,17 @@ func startupSequence() {
 		panic(err)
 	}
 
+	//Create a system wide logger
+	l, err := logger.NewLogger("zr", "./log", *logOutputToFile)
+	if err == nil {
+		SystemWideLogger = l
+	} else {
+		panic(err)
+	}
 	//Create a netstat buffer
 	netstatBuffers, err = netstat.NewNetStatBuffer(300)
 	if err != nil {
-		log.Println("Failed to load network statistic info")
+		SystemWideLogger.PrintAndLog("Network", "Failed to load network statistic info", err)
 		panic(err)
 	}
 
@@ -134,13 +142,13 @@ func startupSequence() {
 			BuildVersion: version,
 		}, "")
 		if err != nil {
-			log.Println("Unable to startup mDNS service. Disabling mDNS services")
+			SystemWideLogger.Println("Unable to startup mDNS service. Disabling mDNS services")
 		} else {
 			//Start initial scanning
 			go func() {
 				hosts := mdnsScanner.Scan(30, "")
 				previousmdnsScanResults = hosts
-				log.Println("mDNS Startup scan completed")
+				SystemWideLogger.Println("mDNS Startup scan completed")
 			}()
 
 			//Create a ticker to update mDNS results every 5 minutes
@@ -154,7 +162,7 @@ func startupSequence() {
 					case <-ticker.C:
 						hosts := mdnsScanner.Scan(30, "")
 						previousmdnsScanResults = hosts
-						log.Println("mDNS scan result updated")
+						SystemWideLogger.Println("mDNS scan result updated")
 					}
 				}
 			}()
@@ -171,7 +179,7 @@ func startupSequence() {
 	if usingZtAuthToken == "" {
 		usingZtAuthToken, err = ganserv.TryLoadorAskUserForAuthkey()
 		if err != nil {
-			log.Println("Failed to load ZeroTier controller API authtoken")
+			SystemWideLogger.Println("Failed to load ZeroTier controller API authtoken")
 		}
 	}
 	ganManager = ganserv.NewNetworkManager(&ganserv.NetworkManagerOptions{

+ 1 - 2
wrappers.go

@@ -19,7 +19,6 @@ package main
 import (
 	"encoding/json"
 	"fmt"
-	"log"
 	"net/http"
 	"strings"
 	"time"
@@ -263,7 +262,7 @@ func HandleWakeOnLan(w http.ResponseWriter, r *http.Request) {
 			return
 		}
 
-		log.Println("[WoL] Sending Wake on LAN magic packet to " + wake)
+		SystemWideLogger.PrintAndLog("WoL", "Sending Wake on LAN magic packet to "+wake, nil)
 		err := wakeonlan.WakeTarget(wake)
 		if err != nil {
 			utils.SendErrorResponse(w, err.Error())