From e1e2da2e340fa40c19aa1833aaa76b66ec9bf1ce Mon Sep 17 00:00:00 2001
From: Jonas Leder <jonas@jonasled.de>
Date: Sat, 25 Jan 2025 12:49:59 +0100
Subject: [PATCH] initialize mqtt server

---
 .env.example           |  1 +
 .gitignore             |  1 +
 go.mod                 | 15 +++++++++++++++
 go.sum                 | 33 +++++++++++++++++++++++++++++++++
 log/lumberjack-hook.go | 32 ++++++++++++++++++++++++++++++++
 log/main.go            | 41 +++++++++++++++++++++++++++++++++++++++++
 main.go                | 17 +++++++++++++++++
 mqttserver/main.go     | 31 +++++++++++++++++++++++++++++++
 8 files changed, 171 insertions(+)
 create mode 100644 .env.example
 create mode 100644 .gitignore
 create mode 100644 go.sum
 create mode 100644 log/lumberjack-hook.go
 create mode 100644 log/main.go
 create mode 100644 main.go
 create mode 100644 mqttserver/main.go

diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..ea933cf
--- /dev/null
+++ b/.env.example
@@ -0,0 +1 @@
+MQTT_SERVER_ENABLED=true
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2eea525
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.env
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 307e93a..1a750e3 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,18 @@
 module jonasled.dev/jonasled/ems-esp-logger
 
 go 1.23.4
+
+require (
+	github.com/joho/godotenv v1.5.1
+	github.com/sirupsen/logrus v1.9.3
+	github.com/wind-c/comqtt/v2 v2.6.0
+	gopkg.in/natefinch/lumberjack.v2 v2.2.1
+)
+
+require (
+	github.com/gorilla/websocket v1.5.1 // indirect
+	github.com/rs/xid v1.5.0 // indirect
+	golang.org/x/net v0.27.0 // indirect
+	golang.org/x/sys v0.22.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..31ffe23
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,33 @@
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
+github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
+github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
+github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
+github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
+github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
+github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
+github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/wind-c/comqtt/v2 v2.6.0 h1:huLdOwYDrwMTrEwH7+mSs1GftHZ/tDqJw8nOz3iX7kc=
+github.com/wind-c/comqtt/v2 v2.6.0/go.mod h1:6O4VilBrTQ/cNIcmIgNdMLCK9DTiLRxkal00t0DLN64=
+golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
+golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
+golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/log/lumberjack-hook.go b/log/lumberjack-hook.go
new file mode 100644
index 0000000..067c552
--- /dev/null
+++ b/log/lumberjack-hook.go
@@ -0,0 +1,32 @@
+package log
+
+import (
+	"fmt"
+
+	"github.com/sirupsen/logrus"
+	"gopkg.in/natefinch/lumberjack.v2"
+)
+
+type LumberjackHook struct {
+	Logger *lumberjack.Logger
+}
+
+func (hook *LumberjackHook) Fire(entry *logrus.Entry) error {
+
+	// Write to the lumberjack.Logger (log file with rotation)
+	_, err := hook.Logger.Write(hook.Format(entry))
+	return err
+}
+
+// Implement the logrus.Hook interface method Levels
+func (hook *LumberjackHook) Levels() []logrus.Level {
+	return logrus.AllLevels
+}
+func (hook *LumberjackHook) Format(entry *logrus.Entry) []byte {
+	// Format the timestamp with timezone offset
+	timestamp := entry.Time.Format("2006-01-02T15:04:05-07:00")
+
+	// Format the log message
+	logMessage := fmt.Sprintf("%s[%s] %s\n", entry.Level.String(), timestamp, entry.Message)
+	return []byte(logMessage)
+}
diff --git a/log/main.go b/log/main.go
new file mode 100644
index 0000000..9034945
--- /dev/null
+++ b/log/main.go
@@ -0,0 +1,41 @@
+package log
+
+import (
+	"os"
+
+	"github.com/sirupsen/logrus"
+	"gopkg.in/natefinch/lumberjack.v2"
+)
+
+var Log = logrus.New()
+
+func Init() {
+	Log.SetOutput(os.Stdout)
+	Log.AddHook(&LumberjackHook{
+		Logger: &lumberjack.Logger{
+			Filename:   os.Getenv("LOG_FOLDER") + "/application.log",
+			MaxSize:    10,   // Max size in MB
+			MaxBackups: 3,    // Max number of old log files to keep
+			MaxAge:     28,   // Max age in days to keep a log file
+			Compress:   true, // Compress old log files
+		}})
+
+	if os.Getenv("LOG_LEVEL") == "" {
+		Log.SetLevel(logrus.InfoLevel)
+	} else {
+		switch os.Getenv("LOG_LEVEL") {
+		case "ERROR":
+			Log.SetLevel(logrus.ErrorLevel)
+		case "WARN":
+			Log.SetLevel(logrus.WarnLevel)
+		case "INFO":
+			Log.SetLevel(logrus.InfoLevel)
+		case "DEBUG":
+			Log.SetLevel(logrus.DebugLevel)
+		}
+	}
+	Log.SetFormatter(&logrus.TextFormatter{
+		FullTimestamp: true,
+	})
+	Log.Infof("Logger initialized with %s log level", Log.Level)
+}
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..1609ca9
--- /dev/null
+++ b/main.go
@@ -0,0 +1,17 @@
+package main
+
+import (
+	"os"
+
+	_ "github.com/joho/godotenv/autoload"
+	"jonasled.dev/jonasled/ems-esp-logger/log"
+	"jonasled.dev/jonasled/ems-esp-logger/mqttserver"
+)
+
+func main() {
+	if os.Getenv("MQTT_SERVER_ENABLED") == "true" {
+		log.Log.Info("Starting embedded MQTT server")
+		mqttserver.Start()
+	}
+
+}
diff --git a/mqttserver/main.go b/mqttserver/main.go
new file mode 100644
index 0000000..c7ff0e2
--- /dev/null
+++ b/mqttserver/main.go
@@ -0,0 +1,31 @@
+package mqttserver
+
+import (
+	"os"
+
+	"github.com/wind-c/comqtt/v2/mqtt"
+	"github.com/wind-c/comqtt/v2/mqtt/hooks/auth"
+	"github.com/wind-c/comqtt/v2/mqtt/listeners"
+	"jonasled.dev/jonasled/ems-esp-logger/log"
+)
+
+func Start() {
+	server := mqtt.New(nil)
+
+	_ = server.AddHook(new(auth.AllowHook), nil)
+
+	if os.Getenv("MQTT_LISTEN") == "" {
+		log.Log.Fatal("please set MQTT_LISTEN")
+	}
+
+	tcp := listeners.NewTCP("t1", os.Getenv("MQTT_LISTEN"), nil)
+	err := server.AddListener(tcp)
+	if err != nil {
+		log.Log.Fatal("Failed creating TCP listener on ", os.Getenv("MQTT_LISTEN"), err.Error())
+	}
+
+	err = server.Serve()
+	if err != nil {
+		log.Log.Fatal("Failed starting MQTT server: ", err.Error())
+	}
+}
-- 
GitLab