-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathhook.go
More file actions
118 lines (105 loc) · 2.33 KB
/
hook.go
File metadata and controls
118 lines (105 loc) · 2.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package zaptelegram
import (
"context"
"errors"
"time"
"go.uber.org/zap/zapcore"
)
const (
defaultLevel = zapcore.WarnLevel
defaultAsyncOpt = true
defaultQueueOpt = false
)
var AllLevels = [6]zapcore.Level{
zapcore.DebugLevel,
zapcore.InfoLevel,
zapcore.WarnLevel,
zapcore.ErrorLevel,
zapcore.FatalLevel,
zapcore.PanicLevel,
}
var (
TokenError = errors.New("token not defined")
ChatIDsError = errors.New("chat ids not defined")
AsyncOptError = errors.New("async option not worked with queue option")
)
type TelegramHook struct {
telegramClient *telegramClient
levels []zapcore.Level
async bool
queue bool
intervalQueue time.Duration
entriesChan chan zapcore.Entry
}
func NewTelegramHook(token string, chatIDs []int, opts ...Option) (*TelegramHook, error) {
if token == "" {
return &TelegramHook{}, TokenError
} else if len(chatIDs) == 0 {
return &TelegramHook{}, ChatIDsError
}
c := newTelegramClient(token, chatIDs)
h := &TelegramHook{
telegramClient: c,
levels: []zapcore.Level{defaultLevel},
async: defaultAsyncOpt,
queue: defaultQueueOpt,
}
for _, opt := range opts {
if err := opt(h); err != nil {
return nil, err
}
}
return h, nil
}
func (h TelegramHook) GetHook() func(zapcore.Entry) error {
return func(e zapcore.Entry) error {
if !h.isActualLevel(e.Level) {
return nil
} else if h.async {
go func() {
_ = h.telegramClient.sendMessage(e)
}()
return nil
} else if h.queue {
h.entriesChan <- e
return nil
} else if err := h.telegramClient.sendMessage(e); err != nil {
return err
}
return nil
}
}
func (h TelegramHook) isActualLevel(l zapcore.Level) bool {
for _, level := range h.levels {
if level == l {
return true
}
}
return false
}
func (h TelegramHook) consumeEntriesQueue(ctx context.Context) error {
ticker := time.NewTicker(h.intervalQueue)
defer ticker.Stop()
for {
select {
case <-ticker.C:
h.handleNewEntries()
case <-ctx.Done():
h.handleNewEntries()
return ctx.Err()
}
}
}
func (h TelegramHook) handleNewEntries() {
for len(h.entriesChan) > 0 {
_ = h.telegramClient.sendMessage(<-h.entriesChan)
}
}
func getLevelThreshold(l zapcore.Level) []zapcore.Level {
for i := range AllLevels {
if AllLevels[i] == l {
return AllLevels[i:]
}
}
return []zapcore.Level{}
}