-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdislog.go
145 lines (124 loc) · 3.7 KB
/
dislog.go
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package dislog
import (
"context"
"errors"
"fmt"
"strconv"
"sync"
"time"
"github.com/disgoorg/disgo/discord"
"github.com/sirupsen/logrus"
)
const MaxEmbeds = 10
var (
TimeFormatter = "2006-01-02 15:04:05 Z07"
LogWait = 2 * time.Second
PanicLevelColor = 0xe300bd
FatalLevelColor = 0xff0011
ErrorLevelColor = 0xeb4034
WarnLevelColor = 0xff8c00
InfoLevelColor = 0xfcec00
DebugLevelColor = 0x0095ff
TraceLevelColor = 0xfffffe
LevelColors = map[logrus.Level]*int{
logrus.PanicLevel: &PanicLevelColor,
logrus.FatalLevel: &FatalLevelColor,
logrus.ErrorLevel: &ErrorLevelColor,
logrus.WarnLevel: &WarnLevelColor,
logrus.InfoLevel: &InfoLevelColor,
logrus.DebugLevel: &DebugLevelColor,
logrus.TraceLevel: &TraceLevelColor,
}
PanicLevelAndAbove = []logrus.Level{logrus.PanicLevel}
FatalLevelAndAbove = []logrus.Level{logrus.PanicLevel, logrus.FatalLevel}
ErrorLevelAndAbove = []logrus.Level{logrus.PanicLevel, logrus.FatalLevel, logrus.ErrorLevel}
WarnLevelAndAbove = []logrus.Level{logrus.PanicLevel, logrus.FatalLevel, logrus.ErrorLevel, logrus.WarnLevel}
InfoLevelAndAbove = []logrus.Level{logrus.PanicLevel, logrus.FatalLevel, logrus.ErrorLevel, logrus.WarnLevel, logrus.InfoLevel}
DebugLevelAndAbove = []logrus.Level{logrus.PanicLevel, logrus.FatalLevel, logrus.ErrorLevel, logrus.WarnLevel, logrus.InfoLevel, logrus.DebugLevel}
TraceLevelAndAbove = []logrus.Level{logrus.PanicLevel, logrus.FatalLevel, logrus.ErrorLevel, logrus.WarnLevel, logrus.InfoLevel, logrus.DebugLevel, logrus.TraceLevel}
_ logrus.Hook = (*DisLog)(nil)
)
func New(opts ...ConfigOpt) (*DisLog, error) {
config := DefaultConfig()
config.Apply(opts)
if config.WebhookID == 0 || config.WebhookToken == "" {
return nil, errors.New("webhook ID & token or a webhook client are required")
}
return &DisLog{
config: *config,
}, nil
}
type DisLog struct {
config Config
queued bool
queue []discord.Embed
queueMu sync.Mutex
}
func (l *DisLog) Levels() []logrus.Level {
return l.config.LogLevels
}
func (l *DisLog) Close(ctx context.Context) {
l.sendEmbeds()
l.config.WebhookClient.Close(ctx)
}
func (l *DisLog) queueEmbed(embed discord.Embed, forceSend bool) error {
l.queueMu.Lock()
defer l.queueMu.Unlock()
l.queue = append(l.queue, embed)
if len(l.queue) >= MaxEmbeds || forceSend {
go l.sendEmbeds()
} else {
l.queueEmbeds()
}
return nil
}
func (l *DisLog) sendEmbeds() {
l.queueMu.Lock()
defer l.queueMu.Unlock()
if len(l.queue) == 0 {
return
}
message := discord.NewWebhookMessageCreateBuilder()
for i := 0; i < len(l.queue); i++ {
if i >= MaxEmbeds {
// queue again as we have logs to send
l.queueEmbeds()
break
}
message.AddEmbeds(l.queue[i])
l.queue = append(l.queue[:i], l.queue[i+1:]...)
i--
}
if len(message.Embeds) == 0 {
return
}
_, err := l.config.WebhookClient.CreateMessage(message.Build())
if err != nil {
fmt.Printf("error while sending logs: %s\n", err)
}
}
func (l *DisLog) queueEmbeds() {
if l.queued {
return
}
go func() {
l.queued = true
time.Sleep(LogWait)
l.sendEmbeds()
l.queued = false
}()
}
func (l *DisLog) Fire(entry *logrus.Entry) error {
eb := discord.NewEmbedBuilder().
SetColor(*LevelColors[entry.Level]).
SetDescription(entry.Message).
AddField("LogLevel", entry.Level.String(), true).
AddField("Time", entry.Time.Format(TimeFormatter), true)
if entry.HasCaller() {
eb.SetDescription("in file: " + entry.Caller.File + " from func: " + entry.Caller.Function + " in line: " + strconv.Itoa(entry.Caller.Line) + "\n" + entry.Message)
}
for key, value := range entry.Data {
eb.AddField(key, fmt.Sprint(value), true)
}
return l.queueEmbed(eb.Build(), entry.Level == logrus.FatalLevel || entry.Level == logrus.PanicLevel)
}