mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-20 12:42:34 +02:00
105 lines
2.2 KiB
Go
105 lines
2.2 KiB
Go
package notif
|
|
|
|
import (
|
|
"github.com/rs/zerolog"
|
|
E "github.com/yusing/go-proxy/internal/error"
|
|
"github.com/yusing/go-proxy/internal/logging"
|
|
"github.com/yusing/go-proxy/internal/task"
|
|
F "github.com/yusing/go-proxy/internal/utils/functional"
|
|
)
|
|
|
|
type (
|
|
Dispatcher struct {
|
|
task *task.Task
|
|
logCh chan *LogMessage
|
|
providers F.Set[Provider]
|
|
}
|
|
LogMessage struct {
|
|
Level zerolog.Level
|
|
Title string
|
|
Extras map[string]any
|
|
Color Color
|
|
}
|
|
)
|
|
|
|
var dispatcher *Dispatcher
|
|
|
|
const dispatchErr = "notification dispatch error"
|
|
|
|
func StartNotifDispatcher(parent task.Parent) *Dispatcher {
|
|
dispatcher = &Dispatcher{
|
|
task: parent.Subtask("notification"),
|
|
logCh: make(chan *LogMessage),
|
|
providers: F.NewSet[Provider](),
|
|
}
|
|
go dispatcher.start()
|
|
return dispatcher
|
|
}
|
|
|
|
func Notify(msg *LogMessage) {
|
|
if dispatcher == nil {
|
|
return
|
|
}
|
|
select {
|
|
case <-dispatcher.task.Context().Done():
|
|
return
|
|
default:
|
|
dispatcher.logCh <- msg
|
|
}
|
|
}
|
|
|
|
func (disp *Dispatcher) RegisterProvider(cfg *NotificationConfig) {
|
|
disp.providers.Add(cfg.Provider)
|
|
}
|
|
|
|
func (disp *Dispatcher) start() {
|
|
defer func() {
|
|
dispatcher = nil
|
|
disp.providers.Clear()
|
|
close(disp.logCh)
|
|
disp.task.Finish(nil)
|
|
}()
|
|
|
|
for {
|
|
select {
|
|
case <-disp.task.Context().Done():
|
|
return
|
|
case msg, ok := <-disp.logCh:
|
|
if !ok {
|
|
return
|
|
}
|
|
go disp.dispatch(msg)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (disp *Dispatcher) dispatch(msg *LogMessage) {
|
|
task := disp.task.Subtask("dispatcher")
|
|
defer task.Finish("notif dispatched")
|
|
|
|
errs := E.NewBuilder(dispatchErr)
|
|
disp.providers.RangeAllParallel(func(p Provider) {
|
|
if err := notifyProvider(task.Context(), p, msg); err != nil {
|
|
errs.Add(E.PrependSubject(p.GetName(), err))
|
|
}
|
|
})
|
|
if errs.HasError() {
|
|
E.LogError(errs.About(), errs.Error())
|
|
} else {
|
|
logging.Debug().Str("title", msg.Title).Msgf("dispatched notif")
|
|
}
|
|
}
|
|
|
|
// Run implements zerolog.Hook.
|
|
// func (disp *Dispatcher) Run(e *zerolog.Event, level zerolog.Level, message string) {
|
|
// if strings.HasPrefix(message, dispatchErr) { // prevent recursion
|
|
// return
|
|
// }
|
|
// switch level {
|
|
// case zerolog.WarnLevel, zerolog.ErrorLevel, zerolog.FatalLevel, zerolog.PanicLevel:
|
|
// disp.logCh <- &LogMessage{
|
|
// Level: level,
|
|
// Message: message,
|
|
// }
|
|
// }
|
|
// }
|