rework on logger + fix the program exit + rename file if errors in json parsing
This commit is contained in:
parent
8b0af491c0
commit
4d5f685000
4
main.go
4
main.go
@ -77,8 +77,8 @@ func GetOutboxPath(iniFile *ini.File) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var logger log.Logger
|
logger := log.NewLogfmtLogger(os.Stdout)
|
||||||
logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
|
logger = level.NewFilter(logger, level.AllowInfo())
|
||||||
logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller, "service", "mailsrv")
|
logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller, "service", "mailsrv")
|
||||||
|
|
||||||
iniFile, err := LoadIni()
|
iniFile, err := LoadIni()
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
cfg "mailsrv/config"
|
cfg "mailsrv/config"
|
||||||
"mailsrv/mail"
|
"mailsrv/mail"
|
||||||
"mailsrv/runtime"
|
"mailsrv/runtime"
|
||||||
@ -19,6 +20,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
TickerInterval time.Duration = 10 * time.Second
|
TickerInterval time.Duration = 10 * time.Second
|
||||||
JSONSuffix string = ".json"
|
JSONSuffix string = ".json"
|
||||||
|
ErrorSuffix string = ".err"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Sender struct {
|
type Sender struct {
|
||||||
@ -41,23 +43,25 @@ func NewSender(logger log.Logger, config cfg.SMTPConfig, outboxPath string) Send
|
|||||||
|
|
||||||
func (s Sender) SendMail(email mail.Email) error {
|
func (s Sender) SendMail(email mail.Email) error {
|
||||||
auth := smtp.PlainAuth("", s.smtpConfig.User, s.smtpConfig.Password, s.smtpConfig.Url)
|
auth := smtp.PlainAuth("", s.smtpConfig.User, s.smtpConfig.Password, s.smtpConfig.Url)
|
||||||
s.logger.Log("action", "authentication succeed")
|
level.Debug(s.logger).Log("msg", "SMTP authentication succeed")
|
||||||
|
|
||||||
if err := smtp.SendMail(s.smtpConfig.GetFullUrl(), auth, email.Sender, email.Receivers, email.Generate()); err != nil {
|
if err := smtp.SendMail(s.smtpConfig.GetFullUrl(), auth, email.Sender, email.Receivers, email.Generate()); err != nil {
|
||||||
level.Error(s.logger).Log("msg", "error while sending email", "err", err)
|
level.Error(s.logger).Log("msg", "error while sending email", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.logger.Log("msg", "mail send successfully")
|
level.Debug(s.logger).Log("msg", "mail send successfully")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// watchOutbox reads the `outbox` directory every `TickInterval` and put JSON format e-mail in the queue
|
// watchOutbox reads the `outbox` directory every `TickInterval` and put JSON format e-mail in the queue
|
||||||
func (s Sender) watchOutbox() {
|
func (s Sender) watchOutbox() {
|
||||||
|
s.logger.Log("msg", "start watching outbox directory", "outbox", s.outboxPath)
|
||||||
ticker := time.NewTicker(TickerInterval)
|
ticker := time.NewTicker(TickerInterval)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for _ = range ticker.C {
|
for _ = range ticker.C {
|
||||||
s.logger.Log("action", "retrieving json e-mail format...", "path", s.outboxPath)
|
level.Debug(s.logger).Log("action", "retrieving json e-mail format...", "path", s.outboxPath)
|
||||||
|
|
||||||
files, err := os.ReadDir(s.outboxPath)
|
files, err := os.ReadDir(s.outboxPath)
|
||||||
if err != nil && !os.IsExist(err) {
|
if err != nil && !os.IsExist(err) {
|
||||||
@ -71,7 +75,7 @@ func (s Sender) watchOutbox() {
|
|||||||
s.queue.Add(path.Join(s.outboxPath, filename))
|
s.queue.Add(path.Join(s.outboxPath, filename))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
level.Warn(s.logger).Log("msg", "incorrect suffix", "filename", filename)
|
level.Debug(s.logger).Log("msg", "incorrect suffix", "filename", filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -87,20 +91,31 @@ func (s Sender) processNextEmail() bool {
|
|||||||
|
|
||||||
path, ok := item.(string)
|
path, ok := item.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
level.Error(s.logger).Log("msg", "unable to cast queue item into mail.Email")
|
level.Error(s.logger).Log("msg", "unable to cast queue item into mail.Email", "item", item)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
email, err := mail.FromJSON(path)
|
email, err := mail.FromJSON(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
level.Error(s.logger).Log("msg", "unable to parse JSON email", "err", err)
|
level.Error(s.logger).Log("msg", "unable to parse JSON email", "path", path, "err", err)
|
||||||
|
// if JSON parsing failed the `path` is renamed with an error suffix to avoid enqueued it again
|
||||||
|
newPath := fmt.Sprintf("%s%s", path, ErrorSuffix)
|
||||||
|
if err := os.Rename(path, newPath); err != nil {
|
||||||
|
level.Error(s.logger).Log("msg", "unable to rename bad JSON email path", "path", path, "newPath", newPath)
|
||||||
|
s.queue.Shutdown()
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// whatever the return, the email will be not enqueued again
|
||||||
s.SendMail(email)
|
s.SendMail(email)
|
||||||
|
|
||||||
if err := os.Remove(path); err != nil {
|
if err := os.Remove(path); err != nil {
|
||||||
|
// this is a fatal error, can't send same e-mail indefinitely
|
||||||
|
if !os.IsExist(err) {
|
||||||
level.Error(s.logger).Log("msg", "unable to remove the JSON email", "path", path, "err", err)
|
level.Error(s.logger).Log("msg", "unable to remove the JSON email", "path", path, "err", err)
|
||||||
|
s.queue.Shutdown()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -128,10 +143,14 @@ func (s Sender) Run() {
|
|||||||
s.watchOutbox()
|
s.watchOutbox()
|
||||||
queueCh := s.run()
|
queueCh := s.run()
|
||||||
|
|
||||||
<-sigCh
|
select {
|
||||||
|
case <-sigCh:
|
||||||
s.logger.Log("msg", "stop signal received, stopping e-mail queue...")
|
s.logger.Log("msg", "stop signal received, stopping e-mail queue...")
|
||||||
s.queue.Shutdown()
|
s.queue.Shutdown()
|
||||||
|
case <-queueCh:
|
||||||
|
s.logger.Log("msg", "e-mail queue stopped successfully")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
<-queueCh
|
|
||||||
s.logger.Log("msg", "sender service stopped successfully")
|
s.logger.Log("msg", "sender service stopped successfully")
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user