diff --git a/.env.example b/.env.example new file mode 100644 index 0000000000000000000000000000000000000000..ea933cf760e88bcb0dce449444621aa83f1ae05a --- /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 0000000000000000000000000000000000000000..2eea525d885d5148108f6f3a9a8613863f783d36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env \ No newline at end of file diff --git a/go.mod b/go.mod index 307e93a359d46cf13c5a41fbdc99fee040ca7331..1a750e3ce9163666930b8eba50a2076189144aa6 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 0000000000000000000000000000000000000000..31ffe23a8cd12b95a4a722cfad4df8ff9a022cd8 --- /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 0000000000000000000000000000000000000000..067c5524cd74cccdd3b1c9dc84529b67c9e928db --- /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 0000000000000000000000000000000000000000..9034945da62854c232c5b44fd04f8b0caaddc25b --- /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 0000000000000000000000000000000000000000..1609ca92af4fbfd90345e4aa8145b79b21e655f7 --- /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 0000000000000000000000000000000000000000..c7ff0e2724677d5b986ab5c850e526897f0e8251 --- /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()) + } +}