hook

package module
v1.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 18, 2023 License: MIT Imports: 7 Imported by: 0

README

discordbotrus

GitHub Build Coverage Go Report Card GoDoc

Logrus hook for Discord using Discord application.

Install

go get github.com/outdead/discordbotrus

See Changelog for release details.

Requirements

Go 1.19 or higher

Usage

package main

import (
	"io/ioutil"
	"log"
	"os"

	"github.com/outdead/discordbotrus"
	"github.com/sirupsen/logrus"
)

func main() {
	cfg := hook.NewDefaultConfig(os.Getenv("LDH_TOKEN"), os.Getenv("LDH_CHANNEL"))
	hooker, err := hook.New(cfg)
	if err != nil {
		log.Fatalf("expected nil got error: %s", err)
	}

	defer func() {
		if err := hooker.Close(); err != nil {
			log.Fatalf("expected nil got error: %s", err)
		}
	}()

	logger := &logrus.Logger{
		Out: ioutil.Discard, 
		Formatter: new(logrus.JSONFormatter), 
		Hooks: make(logrus.LevelHooks), 
		Level: logrus.InfoLevel,
	}
	logger.AddHook(hooker)

	logger.Info("My spoon is too big")
}
With an existing discordgo session

If you wish to initialize a Discord Hook with an already initialized discordgo session, you can use the SetSession option:

package main

import (
	"io/ioutil"
	"log"
	"os"

	"github.com/bwmarrin/discordgo"
	"github.com/outdead/discordbotrus"
	"github.com/sirupsen/logrus"
)

func main() {
	token := os.Getenv("LDH_TOKEN")
	channelID := os.Getenv("LDH_CHANNEL")

	session, err := discordgo.New("Bot " + token)
	if err != nil {
		log.Fatalf("expected nil got error: %s", err)
	}

	// In this case, you can use the session without opening a web socket.
	// But to establish a stable connection, it is better to do this.
	if err := session.Open(); err != nil {
		log.Fatalf("open discord session error: %s", err)
	}

	defer func() {
		if err != session.Close() {
			log.Fatalf("expected nil got error: %s", err)
		}
	}()

	hooker, err := hook.New(
		&hook.Config{ChannelID: channelID},
		hook.SetSession(session),
	)
	if err != nil {
		log.Fatalf("expected nil got error: %s", err)
	}

	logger := &logrus.Logger{
		Out:       ioutil.Discard,
		Formatter: new(logrus.JSONFormatter),
		Hooks:     make(logrus.LevelHooks),
		Level:     logrus.InfoLevel,
	}
	logger.AddHook(hooker)

	logger.Info("My spoon is too big")
}

Config

In most cases, the package will not exist on its own, it will be part of an application. For ease of configuration, yaml and json tags are affixed to Config. You can use configuration files similar to this:

disabled: false # it is possible to disable the hook from the configuration file.
token: "" # required to create own connection to discord bot.
channel_id: "" # required.
format: "json" # supported formats: text, json, embed
min_level: "info"
levels:
- "error"
- "warning"
- "info"
- "trace"

If only min_level is specified, then the hook will fire for all levels above the specified one. If only the levels list is specified, then the hook will work only for all listed levels. The parameters min_level and levels are used together and the intersection between them is calcalated. If both of them are specified, then the levels below min_level are cut off from all the listed levels

Tests

To run tests you need to add the environment variables LDH_TOKEN and LDH_CHANNEL.

License

MIT License, see LICENSE

Documentation

Index

Constants

View Source
const (
	// DiscordMaxMessageLen max discord message length.
	DiscordMaxMessageLen = 2000

	// DefaultTimeLayout default time layout to Formatter implementations.
	DefaultTimeLayout = "2006-01-02 15:04:05"
)
View Source
const (
	ColorGreen  = 0x0008000
	ColorYellow = 0xffaa00
	ColorRed    = 0xff0000
)

Colors for log levels.

View Source
const EmbedFormatterCode = "embed"

EmbedFormatterCode formatter code to identify from config.

View Source
const JSONFormatterCode = "json"

JSONFormatterCode formatter code to identify from config.

View Source
const TextFormatterCode = "text"

TextFormatterCode formatter code to identify from config.

Variables

View Source
var (
	// ErrEmptyToken is returned when discord bot token is empty with enabled hook.
	ErrEmptyToken = errors.New("discord bot token is empty")

	// ErrEmptyChannelID is returned when discord channel id is empty with enabled hook.
	ErrEmptyChannelID = errors.New("discord channel id is empty")

	// ErrMessageTooLong is returned when message that has been sent to discord longer
	// than 2000 characters.
	ErrMessageTooLong = errors.New("discord message too long")
)
View Source
var DefaultEmbedFormatter = &EmbedFormatter{
	Inline:          true,
	TimestampFormat: DefaultTimeLayout,
}

DefaultEmbedFormatter used as default EmbedFormatter.

View Source
var DefaultJSONFormatter = &JSONFormatter{
	JSONFormatter: logrus.JSONFormatter{
		TimestampFormat: DefaultTimeLayout,
	},
	Quoted: true,
}

DefaultJSONFormatter used as default JSONFormatter.

View Source
var DefaultTextFormatter = &TextFormatter{
	TextFormatter: logrus.TextFormatter{
		TimestampFormat:  DefaultTimeLayout,
		QuoteEmptyFields: true,
	},
	Quoted: true,
}

DefaultTextFormatter used as default TextFormatter.

Functions

func LevelColor

func LevelColor(l logrus.Level) int

LevelColor returns the respective color for the logrus level.

func ParseLevels

func ParseLevels(lvs []string, minLvl string) ([]logrus.Level, error)

ParseLevels parses logging levels from the config.

Types

type Config

type Config struct {
	// Disabled can disable hook form configuration file.
	Disabled bool `json:"disabled" yaml:"disabled"`

	// Token is bot token from discord developers applications.
	Token string `json:"token" yaml:"token"`

	// ChannelID is id of discord channel to log hooks.
	ChannelID string `json:"channel_id" yaml:"channel_id"`

	// Format specifies formatter to discord message.
	// Supported formats: text, json, embed.
	Format string `json:"format" yaml:"format"`

	// MinLevel is the minimum priority level to enable logging.
	MinLevel string `json:"min_level" yaml:"min_level"`

	// Levels is a list of levels to enable logging. Intersects with MinLevel.
	Levels []string `json:"levels" yaml:"levels"`
}

Config handles discord bot connection configuration and logrus levels.

func NewDefaultConfig

func NewDefaultConfig(token string, channelID string) *Config

NewDefaultConfig returns default configuration for hook.

func (*Config) Validate

func (cfg *Config) Validate() error

Validate checks config for required fields.

type EmbedFormatter

type EmbedFormatter struct {
	// TimestampFormat sets the format used for marshaling timestamps.
	TimestampFormat string

	// The keys sorting function, when uninitialized it uses sort.Strings.
	SortingFunc func([]string)

	// Inline causes fields to be displayed one per line
	// as opposed to being inline.
	Inline bool

	// DisableTimestamp allows disabling automatic timestamps in output.
	DisableTimestamp bool

	// The fields are sorted by default for a consistent output. For applications
	// that log extremely frequently and don't use the JSON formatter this may not
	// be desired.
	DisableSorting bool
}

EmbedFormatter formats logs into parsable json.

func (*EmbedFormatter) Embed

func (f *EmbedFormatter) Embed(entry *logrus.Entry) *discordgo.MessageEmbed

Embed creates discord embed message from logrus entry.

func (*EmbedFormatter) Format

func (f *EmbedFormatter) Format(entry *logrus.Entry) ([]byte, error)

Format renders a single log entry.

type Hook

type Hook struct {
	// contains filtered or unexported fields
}

Hook implements logrus.Hook and delivers logs to discord channel.

func New

func New(cfg *Config, options ...Option) (*Hook, error)

New creates new logrus hook for discord.

func (*Hook) Close

func (hook *Hook) Close() error

Close implements io.Closer. Closes connection to discord if hook is owner of it.

func (*Hook) Fire

func (hook *Hook) Fire(entry *logrus.Entry) error

Fire implements logrus.Hook.

func (*Hook) Levels

func (hook *Hook) Levels() []logrus.Level

Levels implements logrus.Hook.

type JSONFormatter

type JSONFormatter struct {
	logrus.JSONFormatter

	// Quoted will quote string to discord tag json.
	Quoted bool
}

JSONFormatter formats logs into parsable json.

func (*JSONFormatter) Format

func (f *JSONFormatter) Format(entry *logrus.Entry) ([]byte, error)

Format renders a single log entry.

type Option

type Option func(client *Hook)

Option can be used to a create a customized connection.

func SetFormatter

func SetFormatter(formatter logrus.Formatter) Option

SetFormatter sets custom formatter to Hook.

func SetLevels

func SetLevels(levels []logrus.Level) Option

SetLevels sets logrus levels to Hook.

func SetSession

func SetSession(session *discordgo.Session) Option

SetSession sets discordgo session to Hook.

type TextFormatter

type TextFormatter struct {
	logrus.TextFormatter

	// Quoted will quote string to discord tag text.
	Quoted bool
}

TextFormatter formats logs into text.

func (*TextFormatter) Format

func (f *TextFormatter) Format(entry *logrus.Entry) ([]byte, error)

Format renders a single log entry.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL