aboutsummaryrefslogtreecommitdiff
path: root/vendor/gopkg.in/clog.v1
diff options
context:
space:
mode:
authorUnknwon <u@gogs.io>2018-04-25 22:13:16 -0400
committerUnknwon <u@gogs.io>2018-04-25 22:13:16 -0400
commitd572381a37020f8a3d9c1e01bc37f8cfc48aaccb (patch)
tree8a0acba1f0b67ff4ba7a920c037970d15018919f /vendor/gopkg.in/clog.v1
parent9127001f119843b787e604a0ab732e5ad7f4cb43 (diff)
vendor: update gopkg.in/clog.v1
Diffstat (limited to 'vendor/gopkg.in/clog.v1')
-rw-r--r--vendor/gopkg.in/clog.v1/README.md18
-rw-r--r--vendor/gopkg.in/clog.v1/clog.go9
-rw-r--r--vendor/gopkg.in/clog.v1/console.go2
-rw-r--r--vendor/gopkg.in/clog.v1/discord.go218
-rw-r--r--vendor/gopkg.in/clog.v1/file.go5
-rw-r--r--vendor/gopkg.in/clog.v1/slack.go7
6 files changed, 247 insertions, 12 deletions
diff --git a/vendor/gopkg.in/clog.v1/README.md b/vendor/gopkg.in/clog.v1/README.md
index e66c0abc..c87d21ba 100644
--- a/vendor/gopkg.in/clog.v1/README.md
+++ b/vendor/gopkg.in/clog.v1/README.md
@@ -28,7 +28,7 @@ Please apply `-u` flag to update in the future.
## Getting Started
-Clog currently has three builtin logger adapters: `console`, `file` and `slack`.
+Clog currently has three builtin logger adapters: `console`, `file`, `slack` and `discord`.
It is extremely easy to create one with all default settings. Generally, you would want to create new logger inside `init` or `main` function.
@@ -140,6 +140,22 @@ Slack logger is also supported in a simple way:
This logger also works for [Discord Slack](https://discordapp.com/developers/docs/resources/webhook#execute-slackcompatible-webhook) endpoint.
+## Discord
+
+Discord logger is supported in rich format via [Embed Object](https://discordapp.com/developers/docs/resources/channel#embed-object):
+
+```go
+...
+ err := log.New(log.DISCORD, log.DiscordConfig{
+ Level: log.INFO,
+ BufferSize: 100,
+ URL: "https://url-to-discord-webhook",
+ })
+...
+```
+
+This logger also retries automatically if hits rate limit after `retry_after`.
+
## Credits
- Avatar is a modified version based on [egonelbre/gophers' scientist](https://github.com/egonelbre/gophers/blob/master/vector/science/scientist.svg).
diff --git a/vendor/gopkg.in/clog.v1/clog.go b/vendor/gopkg.in/clog.v1/clog.go
index 5236cae6..eb9325c1 100644
--- a/vendor/gopkg.in/clog.v1/clog.go
+++ b/vendor/gopkg.in/clog.v1/clog.go
@@ -24,7 +24,7 @@ import (
)
const (
- _VERSION = "1.1.1"
+ _VERSION = "1.2.0"
)
// Version returns current version of the package.
@@ -38,6 +38,13 @@ type (
)
const (
+ CONSOLE MODE = "console"
+ FILE MODE = "file"
+ SLACK MODE = "slack"
+ DISCORD MODE = "discord"
+)
+
+const (
TRACE LEVEL = iota
INFO
WARN
diff --git a/vendor/gopkg.in/clog.v1/console.go b/vendor/gopkg.in/clog.v1/console.go
index 0f9b7333..df81b775 100644
--- a/vendor/gopkg.in/clog.v1/console.go
+++ b/vendor/gopkg.in/clog.v1/console.go
@@ -20,8 +20,6 @@ import (
"github.com/fatih/color"
)
-const CONSOLE MODE = "console"
-
// Console color set for different levels.
var consoleColors = []func(a ...interface{}) string{
color.New(color.FgBlue).SprintFunc(), // Trace
diff --git a/vendor/gopkg.in/clog.v1/discord.go b/vendor/gopkg.in/clog.v1/discord.go
new file mode 100644
index 00000000..abc7521f
--- /dev/null
+++ b/vendor/gopkg.in/clog.v1/discord.go
@@ -0,0 +1,218 @@
+// Copyright 2018 Unknwon
+//
+// Licensed under the Apache License, Version 2.0 (the "License"): you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package clog
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "time"
+)
+
+type (
+ discordEmbed struct {
+ Title string `json:"title"`
+ Description string `json:"description"`
+ Timestamp string `json:"timestamp"`
+ Color int `json:"color"`
+ }
+
+ discordPayload struct {
+ Username string `json:"username,omitempty"`
+ Embeds []*discordEmbed `json:"embeds"`
+ }
+)
+
+var (
+ discordTitles = []string{
+ "Tracing",
+ "Information",
+ "Warning",
+ "Error",
+ "Fatal",
+ }
+
+ discordColors = []int{
+ 0, // Trace
+ 3843043, // Info
+ 16761600, // Warn
+ 13041721, // Error
+ 9440319, // Fatal
+ }
+)
+
+type DiscordConfig struct {
+ // Minimum level of messages to be processed.
+ Level LEVEL
+ // Buffer size defines how many messages can be queued before hangs.
+ BufferSize int64
+ // Discord webhook URL.
+ URL string
+ // Username to be shown for the message.
+ // Leave empty to use default as set in the Discord.
+ Username string
+}
+
+type discord struct {
+ Adapter
+
+ url string
+ username string
+}
+
+func newDiscord() Logger {
+ return &discord{
+ Adapter: Adapter{
+ quitChan: make(chan struct{}),
+ },
+ }
+}
+
+func (d *discord) Level() LEVEL { return d.level }
+
+func (d *discord) Init(v interface{}) error {
+ cfg, ok := v.(DiscordConfig)
+ if !ok {
+ return ErrConfigObject{"DiscordConfig", v}
+ }
+
+ if !isValidLevel(cfg.Level) {
+ return ErrInvalidLevel{}
+ }
+ d.level = cfg.Level
+
+ if len(cfg.URL) == 0 {
+ return errors.New("URL cannot be empty")
+ }
+ d.url = cfg.URL
+ d.username = cfg.Username
+
+ d.msgChan = make(chan *Message, cfg.BufferSize)
+ return nil
+}
+
+func (d *discord) ExchangeChans(errorChan chan<- error) chan *Message {
+ d.errorChan = errorChan
+ return d.msgChan
+}
+
+func buildDiscordPayload(username string, msg *Message) (string, error) {
+ payload := discordPayload{
+ Username: username,
+ Embeds: []*discordEmbed{
+ {
+ Title: discordTitles[msg.Level],
+ Description: msg.Body[8:],
+ Timestamp: time.Now().Format(time.RFC3339),
+ Color: discordColors[msg.Level],
+ },
+ },
+ }
+ p, err := json.Marshal(&payload)
+ if err != nil {
+ return "", err
+ }
+ return string(p), nil
+}
+
+type rateLimitMsg struct {
+ RetryAfter int64 `json:"retry_after"`
+}
+
+func (d *discord) postMessage(r io.Reader) (int64, error) {
+ resp, err := http.Post(d.url, "application/json", r)
+ if err != nil {
+ return -1, fmt.Errorf("HTTP Post: %v", err)
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode == 429 {
+ rlMsg := &rateLimitMsg{}
+ if err = json.NewDecoder(resp.Body).Decode(&rlMsg); err != nil {
+ return -1, fmt.Errorf("decode rate limit message: %v", err)
+ }
+
+ return rlMsg.RetryAfter, nil
+ } else if resp.StatusCode/100 != 2 {
+ data, _ := ioutil.ReadAll(resp.Body)
+ return -1, fmt.Errorf("%s", data)
+ }
+
+ return -1, nil
+}
+
+func (d *discord) write(msg *Message) {
+ payload, err := buildDiscordPayload(d.username, msg)
+ if err != nil {
+ d.errorChan <- fmt.Errorf("discord: builddiscordPayload: %v", err)
+ return
+ }
+
+ const RETRY_TIMES = 3
+ // Due to discord limit, try at most x times with respect to "retry_after" parameter.
+ for i := 1; i <= 3; i++ {
+ retryAfter, err := d.postMessage(bytes.NewReader([]byte(payload)))
+ if err != nil {
+ d.errorChan <- fmt.Errorf("discord: postMessage: %v", err)
+ return
+ }
+
+ if retryAfter > 0 {
+ time.Sleep(time.Duration(retryAfter) * time.Millisecond)
+ continue
+ }
+
+ return
+ }
+
+ d.errorChan <- fmt.Errorf("discord: failed to send message after %d retries", RETRY_TIMES)
+}
+
+func (d *discord) Start() {
+LOOP:
+ for {
+ select {
+ case msg := <-d.msgChan:
+ d.write(msg)
+ case <-d.quitChan:
+ break LOOP
+ }
+ }
+
+ for {
+ if len(d.msgChan) == 0 {
+ break
+ }
+
+ d.write(<-d.msgChan)
+ }
+ d.quitChan <- struct{}{} // Notify the cleanup is done.
+}
+
+func (d *discord) Destroy() {
+ d.quitChan <- struct{}{}
+ <-d.quitChan
+
+ close(d.msgChan)
+ close(d.quitChan)
+}
+
+func init() {
+ Register(DISCORD, newDiscord)
+}
diff --git a/vendor/gopkg.in/clog.v1/file.go b/vendor/gopkg.in/clog.v1/file.go
index a0157d40..6b490f9c 100644
--- a/vendor/gopkg.in/clog.v1/file.go
+++ b/vendor/gopkg.in/clog.v1/file.go
@@ -27,9 +27,8 @@ import (
)
const (
- FILE MODE = "file"
- SIMPLE_DATE_FORMAT = "2006-01-02"
- LOG_PREFIX_LENGTH = len("2017/02/06 21:20:08 ")
+ SIMPLE_DATE_FORMAT = "2006-01-02"
+ LOG_PREFIX_LENGTH = len("2017/02/06 21:20:08 ")
)
// FileRotationConfig represents rotation related configurations for file mode logger.
diff --git a/vendor/gopkg.in/clog.v1/slack.go b/vendor/gopkg.in/clog.v1/slack.go
index 5ce65577..d6c5de18 100644
--- a/vendor/gopkg.in/clog.v1/slack.go
+++ b/vendor/gopkg.in/clog.v1/slack.go
@@ -32,10 +32,6 @@ type slackPayload struct {
Attachments []slackAttachment `json:"attachments"`
}
-const (
- SLACK = "slack"
-)
-
var slackColors = []string{
"", // Trace
"#3aa3e3", // Info
@@ -113,13 +109,14 @@ func buildSlackPayload(msg *Message) (string, error) {
func (s *slack) write(msg *Message) {
payload, err := buildSlackPayload(msg)
if err != nil {
- s.errorChan <- fmt.Errorf("slack.buildSlackPayload: %v", err)
+ s.errorChan <- fmt.Errorf("slack: buildSlackPayload: %v", err)
return
}
resp, err := http.Post(s.url, "application/json", bytes.NewReader([]byte(payload)))
if err != nil {
s.errorChan <- fmt.Errorf("slack: %v", err)
+ return
}
defer resp.Body.Close()