Skip to content
This repository was archived by the owner on Oct 28, 2022. It is now read-only.

Commit 0ad689d

Browse files
committed
add ability to log errors, warnings and fatals to slack
1 parent 12f3fa6 commit 0ad689d

3 files changed

Lines changed: 90 additions & 0 deletions

File tree

.env.example

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,8 @@ BACKUP_S3_ACCESS_KEY_ID=
2727
BACKUP_S3_SECRET_ACCESS_KEY=
2828
BACKUP_S3_BUCKET=rtcv-backups
2929
BACKUP_S3_USE_SSL=true
30+
31+
# On errors, warnings and fatals, log them to a slack channel
32+
# The SLACK_ENVIRONMENT is added to the message to show from wich envourment the error came from
33+
SLACK_ENVIRONMENT=development
34+
SLACK_WEBHOOK_URL=

helpers/slack/slack.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package slack
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"fmt"
7+
"io/ioutil"
8+
"net/http"
9+
"os"
10+
"strings"
11+
12+
"github.com/apex/log"
13+
)
14+
15+
// SetupLogHandler changes the log handler to send errors, fatals and warns to slack
16+
func SetupLogHandler(webhookURL string) {
17+
messageEnv := os.Getenv("SLACK_ENVIRONMENT")
18+
originalHandler := log.Log.(*log.Logger).Handler.HandleLog
19+
var handler log.HandlerFunc = func(entry *log.Entry) error {
20+
handleLogEntry(entry, webhookURL, messageEnv)
21+
return originalHandler(entry)
22+
}
23+
log.SetHandler(handler)
24+
}
25+
26+
func handleLogEntry(entry *log.Entry, webhookURL string, messageEnv string) {
27+
// IMPORTANT:
28+
// Do not send error, fatal or warn logs in this method as it will cause a n+1 loop
29+
30+
switch entry.Level {
31+
case log.WarnLevel, log.FatalLevel, log.ErrorLevel:
32+
// Continue
33+
default:
34+
return
35+
}
36+
37+
text := fmt.Sprintf("*RTCV %s %s: %s*", messageEnv, entry.Level, strings.TrimSpace(entry.Message))
38+
39+
if len(entry.Fields) != 0 {
40+
text += "\n\nFields:"
41+
for key, value := range entry.Fields {
42+
text += fmt.Sprintf("\n%s: %+v", key, value)
43+
}
44+
}
45+
46+
type m = map[string]any
47+
body, err := json.Marshal(m{
48+
"text": "",
49+
"blocks": []m{{
50+
"type": "section",
51+
"text": m{"type": "mrkdwn", "text": text},
52+
}},
53+
})
54+
if err != nil {
55+
log.WithError(err).Info("Unable to marshal log entry meant for slack webhook")
56+
return
57+
}
58+
59+
req, err := http.NewRequest("POST", webhookURL, bytes.NewBuffer(body))
60+
if err != nil {
61+
log.WithError(err).Info("Unable create post request for slack webhook")
62+
return
63+
}
64+
req.Header.Set("Content-Type", "application/json")
65+
resp, err := http.DefaultClient.Do(req)
66+
if err != nil {
67+
log.WithError(err).Info("Unable to post to slack webhook")
68+
return
69+
}
70+
71+
if resp.StatusCode >= 400 {
72+
respBody, err := ioutil.ReadAll(resp.Body)
73+
if err != nil {
74+
log.WithError(err).Info(fmt.Sprintf("slack webhook returned status code \"%s\" with a unreadable message", resp.Status))
75+
} else {
76+
log.Info(fmt.Sprintf("slack webhook returned status code \"%s\" with message: %s", resp.Status, string(respBody)))
77+
}
78+
}
79+
}

main.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/script-development/RT-CV/db/mongo/backup"
2121
"github.com/script-development/RT-CV/helpers/random"
2222
"github.com/script-development/RT-CV/helpers/requestLogger"
23+
"github.com/script-development/RT-CV/helpers/slack"
2324
"github.com/script-development/RT-CV/mock"
2425
"github.com/script-development/RT-CV/models"
2526
"github.com/script-development/RT-CV/models/matcher"
@@ -80,6 +81,11 @@ func main() {
8081
log.Info("No .env file found")
8182
}
8283

84+
slackWebHookURL := strings.TrimSpace(os.Getenv("SLACK_WEBHOOK_URL"))
85+
if slackWebHookURL != "" {
86+
slack.SetupLogHandler(slackWebHookURL)
87+
}
88+
8389
// Initialize the database
8490
var dbConn db.Connection
8591
useTestingDB := strings.ToLower(os.Getenv("USE_TESTING_DB")) == "true"

0 commit comments

Comments
 (0)