mirror of
https://github.com/gogs/gogs.git
synced 2026-03-03 18:51:06 +01:00
vendor: update gopkg.in/clog.v1
This commit is contained in:
18
vendor/gopkg.in/clog.v1/README.md
generated
vendored
18
vendor/gopkg.in/clog.v1/README.md
generated
vendored
@@ -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).
|
||||
|
||||
9
vendor/gopkg.in/clog.v1/clog.go
generated
vendored
9
vendor/gopkg.in/clog.v1/clog.go
generated
vendored
@@ -24,7 +24,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
_VERSION = "1.1.1"
|
||||
_VERSION = "1.2.0"
|
||||
)
|
||||
|
||||
// Version returns current version of the package.
|
||||
@@ -37,6 +37,13 @@ type (
|
||||
LEVEL int
|
||||
)
|
||||
|
||||
const (
|
||||
CONSOLE MODE = "console"
|
||||
FILE MODE = "file"
|
||||
SLACK MODE = "slack"
|
||||
DISCORD MODE = "discord"
|
||||
)
|
||||
|
||||
const (
|
||||
TRACE LEVEL = iota
|
||||
INFO
|
||||
|
||||
2
vendor/gopkg.in/clog.v1/console.go
generated
vendored
2
vendor/gopkg.in/clog.v1/console.go
generated
vendored
@@ -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
|
||||
|
||||
218
vendor/gopkg.in/clog.v1/discord.go
generated
vendored
Normal file
218
vendor/gopkg.in/clog.v1/discord.go
generated
vendored
Normal file
@@ -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)
|
||||
}
|
||||
5
vendor/gopkg.in/clog.v1/file.go
generated
vendored
5
vendor/gopkg.in/clog.v1/file.go
generated
vendored
@@ -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.
|
||||
|
||||
7
vendor/gopkg.in/clog.v1/slack.go
generated
vendored
7
vendor/gopkg.in/clog.v1/slack.go
generated
vendored
@@ -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()
|
||||
|
||||
|
||||
6
vendor/vendor.json
vendored
6
vendor/vendor.json
vendored
@@ -567,10 +567,10 @@
|
||||
"revisionTime": "2015-09-24T05:17:56Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "AbDfvggt92trYSRhGRqXW5uQ4aU=",
|
||||
"checksumSHA1": "aDNmMYhbmT5lPFTsBPUh4ZZ5pLA=",
|
||||
"path": "gopkg.in/clog.v1",
|
||||
"revision": "8492a6faa632c31ba82f562b53b4a6e5eacf2732",
|
||||
"revisionTime": "2017-05-26T21:48:39Z"
|
||||
"revision": "3bc2eaba5fa35df0338549cc1180dc45f6fc2a16",
|
||||
"revisionTime": "2018-04-24T23:11:46Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "LIu3jihd3edOyIsJJK3V6vx2UZg=",
|
||||
|
||||
Reference in New Issue
Block a user