This repository has been archived by the owner on Dec 15, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
live.go
124 lines (116 loc) · 3.61 KB
/
live.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
package main
import (
"os"
"os/signal"
"github.com/bwmarrin/discordgo"
influxdb2 "github.com/influxdata/influxdb-client-go/v2"
"github.com/influxdata/influxdb-client-go/v2/api"
"github.com/influxdata/influxdb-client-go/v2/api/write"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"go.uber.org/zap"
)
var live = cobra.Command{
Use: "live",
Short: "Continually export live stats",
Long: "Exports live event statistics from the channels the Discord Bot is in.",
Args: cobra.NoArgs,
PreRun: func(_ *cobra.Command, _ []string) {
initDiscord()
},
Run: runLive,
}
func init() {
addInfluxFlags(live.Flags())
}
func runLive(c *cobra.Command, _ []string) {
influx := newInfluxContextFromFlags(c.Flags())
defer influx.close()
defer func() { _ = discord.Close() }()
log.Info("Starting Discord-InfluxDB live exporter")
defer log.Info("Stopping")
discord.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) {
log := log.With(
zap.String("guild_id", m.GuildID),
zap.String("channel_id", m.ChannelID),
zap.String("message_id", m.Message.ID))
timestamp := messageTimestamp(m.Message.ID)
influx.writeAPI.WritePoint(write.NewPointWithMeasurement(metricMessages).
SetTime(timestamp).
AddTag(labelGuild, m.GuildID).
AddTag(labelChannel, m.ChannelID).
AddField(fieldCount, 1))
influx.writeAPI.WritePoint(write.NewPointWithMeasurement(metricUserMessages).
SetTime(timestamp).
AddTag(labelGuild, m.GuildID).
AddTag(labelUser, m.Author.String()).
AddField(fieldCount, 1))
log.Debug("MessageCreate")
})
discord.AddHandler(func(s *discordgo.Session, m *discordgo.MessageReactionAdd) {
log := log.With(
zap.String("guild_id", m.GuildID),
zap.String("channel_id", m.ChannelID),
zap.String("message_id", m.MessageID),
zap.String("emoji", m.Emoji.Name))
influx.writeAPI.WritePoint(write.NewPointWithMeasurement(metricReactions).
SetTime(messageTimestamp(m.MessageID)).
AddTag(labelGuild, m.GuildID).
AddTag(labelEmoji, m.Emoji.Name).
AddField(fieldCount, 1))
log.Debug("MessageReactionAdd")
})
discord.AddHandler(func(s *discordgo.Session, m *discordgo.MessageReactionRemove) {
log := log.With(
zap.String("guild_id", m.GuildID),
zap.String("channel_id", m.ChannelID),
zap.String("message_id", m.MessageID),
zap.String("emoji", m.Emoji.Name))
timestamp := messageTimestamp(m.MessageID)
influx.writeAPI.WritePoint(write.NewPointWithMeasurement(metricReactions).
SetTime(timestamp).
AddTag(labelGuild, m.GuildID).
AddTag(labelEmoji, m.Emoji.Name).
AddField(fieldCount, -1))
log.Debug("MessageReactionRemove")
})
discord.Identify.Intents = discordgo.IntentsGuildMessages | discordgo.IntentsGuildMessageReactions
if err := discord.Open(); err != nil {
log.Fatal("Failed to connect to Discord", zap.Error(err))
}
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
<-interrupt
}
type influxContext struct {
client influxdb2.Client
writeAPI api.WriteAPI
}
func newInfluxContextFromFlags(f *pflag.FlagSet) *influxContext {
influxURL, err := f.GetString(flagInfluxURL)
if err != nil {
panic(err.Error())
}
if influxURL == "" {
log.Fatal("Missing InfluxDB URL")
}
apiToken := readInfluxToken()
influx := influxdb2.NewClient(influxURL, apiToken)
influxOrg, err := f.GetString(flagInfluxOrg)
if err != nil {
panic(err.Error())
}
influxBucket, err := f.GetString(flagInfluxBucket)
if err != nil {
panic(err.Error())
}
writeAPI := influx.WriteAPI(influxOrg, influxBucket)
return &influxContext{
client: influx,
writeAPI: writeAPI,
}
}
func (i *influxContext) close() {
i.writeAPI.Flush()
i.client.Close()
}