mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-25 21:39:25 +01:00
logger: Move to separate package, make *much* nicer
This commit is contained in:
parent
ef9acf53f8
commit
439331cfb8
@ -264,7 +264,7 @@ func (channel *Channel) Join(client *Client, key string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
client.server.logger.Log(LogDebug, "join", fmt.Sprintf("%s joined channel %s", client.nick, channel.name))
|
client.server.logger.Debug("join", fmt.Sprintf("%s joined channel %s", client.nick, channel.name))
|
||||||
|
|
||||||
for member := range channel.members {
|
for member := range channel.members {
|
||||||
if member.capabilities[ExtendedJoin] {
|
if member.capabilities[ExtendedJoin] {
|
||||||
@ -306,7 +306,7 @@ func (channel *Channel) Part(client *Client, message string) {
|
|||||||
}
|
}
|
||||||
channel.Quit(client)
|
channel.Quit(client)
|
||||||
|
|
||||||
client.server.logger.Log(LogDebug, "part", fmt.Sprintf("%s left channel %s", client.nick, channel.name))
|
client.server.logger.Debug("part", fmt.Sprintf("%s left channel %s", client.nick, channel.name))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) GetTopic(client *Client) {
|
func (channel *Channel) GetTopic(client *Client) {
|
||||||
|
@ -170,7 +170,7 @@ func (client *Client) run() {
|
|||||||
|
|
||||||
maxlenTags, maxlenRest := client.maxlens()
|
maxlenTags, maxlenRest := client.maxlens()
|
||||||
|
|
||||||
client.server.logger.Log(LogDebug, "userinput ", client.nick, "<- ", line)
|
client.server.logger.Debug("userinput ", client.nick, "<- ", line)
|
||||||
|
|
||||||
msg, err = ircmsg.ParseLineMaxLen(line, maxlenTags, maxlenRest)
|
msg, err = ircmsg.ParseLineMaxLen(line, maxlenTags, maxlenRest)
|
||||||
if err == ircmsg.ErrorLineIsEmpty {
|
if err == ircmsg.ErrorLineIsEmpty {
|
||||||
@ -404,7 +404,7 @@ func (client *Client) AllNickmasks() []string {
|
|||||||
// SetNickname sets the very first nickname for the client.
|
// SetNickname sets the very first nickname for the client.
|
||||||
func (client *Client) SetNickname(nickname string) error {
|
func (client *Client) SetNickname(nickname string) error {
|
||||||
if client.HasNick() {
|
if client.HasNick() {
|
||||||
client.server.logger.Log(LogError, "nick", fmt.Sprintf("%s nickname already set, something is wrong with server consistency", client.nickMaskString))
|
client.server.logger.Error("nick", fmt.Sprintf("%s nickname already set, something is wrong with server consistency", client.nickMaskString))
|
||||||
return ErrNickAlreadySet
|
return ErrNickAlreadySet
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,7 +421,7 @@ func (client *Client) ChangeNickname(nickname string) error {
|
|||||||
origNickMask := client.nickMaskString
|
origNickMask := client.nickMaskString
|
||||||
err := client.server.clients.Replace(client.nick, nickname, client)
|
err := client.server.clients.Replace(client.nick, nickname, client)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
client.server.logger.Log(LogDebug, "nick", fmt.Sprintf("%s changed nickname to %s", client.nick, nickname))
|
client.server.logger.Debug("nick", fmt.Sprintf("%s changed nickname to %s", client.nick, nickname))
|
||||||
client.server.whoWas.Append(client)
|
client.server.whoWas.Append(client)
|
||||||
client.nick = nickname
|
client.nick = nickname
|
||||||
client.updateNickMask()
|
client.updateNickMask()
|
||||||
@ -446,7 +446,7 @@ func (client *Client) destroy() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
client.server.logger.Log(LogDebug, "quit", fmt.Sprintf("%s is no longer on the server", client.nick))
|
client.server.logger.Debug("quit", fmt.Sprintf("%s is no longer on the server", client.nick))
|
||||||
|
|
||||||
// send quit/error message to client if they haven't been sent already
|
// send quit/error message to client if they haven't been sent already
|
||||||
client.Quit("Connection closed")
|
client.Quit("Connection closed")
|
||||||
@ -595,7 +595,7 @@ func (client *Client) Send(tags *map[string]ircmsg.TagValue, prefix string, comm
|
|||||||
line = line[:len(line)-3] + "\r\n"
|
line = line[:len(line)-3] + "\r\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
client.server.logger.Log(LogDebug, "useroutput", client.nick, " ->", strings.TrimRight(line, "\r\n"))
|
client.server.logger.Debug("useroutput", client.nick, " ->", strings.TrimRight(line, "\r\n"))
|
||||||
|
|
||||||
client.socket.Write(line)
|
client.socket.Write(line)
|
||||||
return nil
|
return nil
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/DanielOaks/oragono/irc/custime"
|
"github.com/DanielOaks/oragono/irc/custime"
|
||||||
|
"github.com/DanielOaks/oragono/irc/logger"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -119,13 +120,14 @@ type ConnectionThrottleConfig struct {
|
|||||||
|
|
||||||
type LoggingConfig struct {
|
type LoggingConfig struct {
|
||||||
Method string
|
Method string
|
||||||
Methods map[string]bool
|
MethodStderr bool
|
||||||
|
MethodFile bool
|
||||||
Filename string
|
Filename string
|
||||||
TypeString string `yaml:"type"`
|
TypeString string `yaml:"type"`
|
||||||
Types map[string]bool `yaml:"real-types"`
|
Types []string `yaml:"real-types"`
|
||||||
ExcludedTypes map[string]bool `yaml:"real-excluded-types"`
|
ExcludedTypes []string `yaml:"real-excluded-types"`
|
||||||
LevelString string `yaml:"level"`
|
LevelString string `yaml:"level"`
|
||||||
Level LogLevel `yaml:"level-real"`
|
Level logger.Level `yaml:"level-real"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type LineLenConfig struct {
|
type LineLenConfig struct {
|
||||||
@ -389,26 +391,26 @@ func LoadConfig(filename string) (config *Config, err error) {
|
|||||||
var newLogConfigs []LoggingConfig
|
var newLogConfigs []LoggingConfig
|
||||||
for _, logConfig := range config.Logging {
|
for _, logConfig := range config.Logging {
|
||||||
// methods
|
// methods
|
||||||
logConfig.Methods = make(map[string]bool)
|
methods := make(map[string]bool)
|
||||||
for _, method := range strings.Split(logConfig.Method, " ") {
|
for _, method := range strings.Split(logConfig.Method, " ") {
|
||||||
if len(method) > 0 {
|
if len(method) > 0 {
|
||||||
logConfig.Methods[strings.ToLower(method)] = true
|
methods[strings.ToLower(method)] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if logConfig.Methods["file"] && logConfig.Filename == "" {
|
if methods["file"] && logConfig.Filename == "" {
|
||||||
return nil, errors.New("Logging configuration specifies 'file' method but 'filename' is empty")
|
return nil, errors.New("Logging configuration specifies 'file' method but 'filename' is empty")
|
||||||
}
|
}
|
||||||
|
logConfig.MethodFile = methods["file"]
|
||||||
|
logConfig.MethodStderr = methods["stderr"]
|
||||||
|
|
||||||
// levels
|
// levels
|
||||||
level, exists := logLevelNames[strings.ToLower(logConfig.LevelString)]
|
level, exists := logger.LogLevelNames[strings.ToLower(logConfig.LevelString)]
|
||||||
if !exists {
|
if !exists {
|
||||||
return nil, fmt.Errorf("Could not translate log leve [%s]", logConfig.LevelString)
|
return nil, fmt.Errorf("Could not translate log leve [%s]", logConfig.LevelString)
|
||||||
}
|
}
|
||||||
logConfig.Level = level
|
logConfig.Level = level
|
||||||
|
|
||||||
// types
|
// types
|
||||||
logConfig.Types = make(map[string]bool)
|
|
||||||
logConfig.ExcludedTypes = make(map[string]bool)
|
|
||||||
for _, typeStr := range strings.Split(logConfig.TypeString, " ") {
|
for _, typeStr := range strings.Split(logConfig.TypeString, " ") {
|
||||||
if len(typeStr) == 0 {
|
if len(typeStr) == 0 {
|
||||||
continue
|
continue
|
||||||
@ -418,9 +420,9 @@ func LoadConfig(filename string) (config *Config, err error) {
|
|||||||
}
|
}
|
||||||
if typeStr[0] == '-' {
|
if typeStr[0] == '-' {
|
||||||
typeStr = typeStr[1:]
|
typeStr = typeStr[1:]
|
||||||
logConfig.ExcludedTypes[typeStr] = true
|
logConfig.ExcludedTypes = append(logConfig.ExcludedTypes, typeStr)
|
||||||
} else {
|
} else {
|
||||||
logConfig.Types[typeStr] = true
|
logConfig.Types = append(logConfig.Types, typeStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(logConfig.Types) < 1 {
|
if len(logConfig.Types) < 1 {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) 2017 Daniel Oaks <daniel@danieloaks.net>
|
// Copyright (c) 2017 Daniel Oaks <daniel@danieloaks.net>
|
||||||
// released under the MIT license
|
// released under the MIT license
|
||||||
|
|
||||||
package irc
|
package logger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
@ -17,62 +17,84 @@ import (
|
|||||||
"github.com/mgutz/ansi"
|
"github.com/mgutz/ansi"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LogLevel represents the level to log messages at.
|
// Level represents the level to log messages at.
|
||||||
type LogLevel int
|
type Level int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// LogDebug represents debug messages.
|
// LogDebug represents debug messages.
|
||||||
LogDebug LogLevel = iota
|
LogDebug Level = iota
|
||||||
// LogInfo represents informational messages.
|
// LogInfo represents informational messages.
|
||||||
LogInfo
|
LogInfo
|
||||||
// LogWarn represents warnings.
|
// LogWarning represents warnings.
|
||||||
LogWarn
|
LogWarning
|
||||||
// LogError represents errors.
|
// LogError represents errors.
|
||||||
LogError
|
LogError
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logLevelNames = map[string]LogLevel{
|
LogLevelNames = map[string]Level{
|
||||||
"debug": LogDebug,
|
"debug": LogDebug,
|
||||||
"info": LogInfo,
|
"info": LogInfo,
|
||||||
"warn": LogWarn,
|
"warn": LogWarning,
|
||||||
"warning": LogWarn,
|
"warning": LogWarning,
|
||||||
"warnings": LogWarn,
|
"warnings": LogWarning,
|
||||||
"error": LogError,
|
"error": LogError,
|
||||||
"errors": LogError,
|
"errors": LogError,
|
||||||
}
|
}
|
||||||
logLevelDisplayNames = map[LogLevel]string{
|
LogLevelDisplayNames = map[Level]string{
|
||||||
LogDebug: "debug",
|
LogDebug: "debug",
|
||||||
LogInfo: "info",
|
LogInfo: "info",
|
||||||
LogWarn: "warning",
|
LogWarning: "warning",
|
||||||
LogError: "error",
|
LogError: "error",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Logger is the main interface used to log debug/info/error messages.
|
// Manager is the main interface used to log debug/info/error messages.
|
||||||
type Logger struct {
|
type Manager struct {
|
||||||
loggers []SingleLogger
|
loggers []singleLogger
|
||||||
stderrWriteLock sync.Mutex
|
stderrWriteLock sync.Mutex
|
||||||
DumpingRawInOut bool
|
DumpingRawInOut bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLogger returns a new Logger.
|
// Config represents the configuration of a single logger.
|
||||||
func NewLogger(config []LoggingConfig) (*Logger, error) {
|
type Config struct {
|
||||||
var logger Logger
|
// logging methods
|
||||||
|
MethodStderr bool
|
||||||
|
MethodFile bool
|
||||||
|
Filename string
|
||||||
|
// logging level
|
||||||
|
Level Level
|
||||||
|
// logging types
|
||||||
|
Types []string
|
||||||
|
ExcludedTypes []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewManager returns a new log manager.
|
||||||
|
func NewManager(config ...Config) (*Manager, error) {
|
||||||
|
var logger Manager
|
||||||
|
|
||||||
for _, logConfig := range config {
|
for _, logConfig := range config {
|
||||||
sLogger := SingleLogger{
|
typeMap := make(map[string]bool)
|
||||||
MethodSTDERR: logConfig.Methods["stderr"],
|
for _, name := range logConfig.Types {
|
||||||
|
typeMap[name] = true
|
||||||
|
}
|
||||||
|
excludedTypeMap := make(map[string]bool)
|
||||||
|
for _, name := range logConfig.ExcludedTypes {
|
||||||
|
excludedTypeMap[name] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
sLogger := singleLogger{
|
||||||
|
MethodSTDERR: logConfig.MethodStderr,
|
||||||
MethodFile: fileMethod{
|
MethodFile: fileMethod{
|
||||||
Enabled: logConfig.Methods["file"],
|
Enabled: logConfig.MethodFile,
|
||||||
Filename: logConfig.Filename,
|
Filename: logConfig.Filename,
|
||||||
},
|
},
|
||||||
Level: logConfig.Level,
|
Level: logConfig.Level,
|
||||||
Types: logConfig.Types,
|
Types: typeMap,
|
||||||
ExcludedTypes: logConfig.ExcludedTypes,
|
ExcludedTypes: excludedTypeMap,
|
||||||
stderrWriteLock: &logger.stderrWriteLock,
|
stderrWriteLock: &logger.stderrWriteLock,
|
||||||
}
|
}
|
||||||
if logConfig.Types["userinput"] || logConfig.Types["useroutput"] || (logConfig.Types["*"] && !(logConfig.ExcludedTypes["userinput"] && logConfig.ExcludedTypes["useroutput"])) {
|
if typeMap["userinput"] || typeMap["useroutput"] || (typeMap["*"] && !(excludedTypeMap["userinput"] && excludedTypeMap["useroutput"])) {
|
||||||
logger.DumpingRawInOut = true
|
logger.DumpingRawInOut = true
|
||||||
}
|
}
|
||||||
if sLogger.MethodFile.Enabled {
|
if sLogger.MethodFile.Enabled {
|
||||||
@ -91,12 +113,47 @@ func NewLogger(config []LoggingConfig) (*Logger, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Log logs the given message with the given details.
|
// Log logs the given message with the given details.
|
||||||
func (logger *Logger) Log(level LogLevel, logType string, messageParts ...string) {
|
func (logger *Manager) Log(level Level, logType string, messageParts ...string) {
|
||||||
for _, singleLogger := range logger.loggers {
|
for _, singleLogger := range logger.loggers {
|
||||||
singleLogger.Log(level, logType, messageParts...)
|
singleLogger.Log(level, logType, messageParts...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Debug logs the given message as a debug message.
|
||||||
|
func (logger *Manager) Debug(logType string, messageParts ...string) {
|
||||||
|
for _, singleLogger := range logger.loggers {
|
||||||
|
singleLogger.Log(LogDebug, logType, messageParts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info logs the given message as an info message.
|
||||||
|
func (logger *Manager) Info(logType string, messageParts ...string) {
|
||||||
|
for _, singleLogger := range logger.loggers {
|
||||||
|
singleLogger.Log(LogInfo, logType, messageParts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warning logs the given message as a warning message.
|
||||||
|
func (logger *Manager) Warning(logType string, messageParts ...string) {
|
||||||
|
for _, singleLogger := range logger.loggers {
|
||||||
|
singleLogger.Log(LogWarning, logType, messageParts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error logs the given message as an error message.
|
||||||
|
func (logger *Manager) Error(logType string, messageParts ...string) {
|
||||||
|
for _, singleLogger := range logger.loggers {
|
||||||
|
singleLogger.Log(LogError, logType, messageParts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fatal logs the given message as an error message, then exits.
|
||||||
|
func (logger *Manager) Fatal(logType string, messageParts ...string) {
|
||||||
|
logger.Error(logType, messageParts...)
|
||||||
|
logger.Error("FATAL", "Fatal error encountered, application exiting")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
type fileMethod struct {
|
type fileMethod struct {
|
||||||
Enabled bool
|
Enabled bool
|
||||||
Filename string
|
Filename string
|
||||||
@ -104,18 +161,18 @@ type fileMethod struct {
|
|||||||
Writer *bufio.Writer
|
Writer *bufio.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
// SingleLogger represents a single logger instance.
|
// singleLogger represents a single logger instance.
|
||||||
type SingleLogger struct {
|
type singleLogger struct {
|
||||||
stderrWriteLock *sync.Mutex
|
stderrWriteLock *sync.Mutex
|
||||||
MethodSTDERR bool
|
MethodSTDERR bool
|
||||||
MethodFile fileMethod
|
MethodFile fileMethod
|
||||||
Level LogLevel
|
Level Level
|
||||||
Types map[string]bool
|
Types map[string]bool
|
||||||
ExcludedTypes map[string]bool
|
ExcludedTypes map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log logs the given message with the given details.
|
// Log logs the given message with the given details.
|
||||||
func (logger *SingleLogger) Log(level LogLevel, logType string, messageParts ...string) {
|
func (logger *singleLogger) Log(level Level, logType string, messageParts ...string) {
|
||||||
// no logging enabled
|
// no logging enabled
|
||||||
if !(logger.MethodSTDERR || logger.MethodFile.Enabled) {
|
if !(logger.MethodSTDERR || logger.MethodFile.Enabled) {
|
||||||
return
|
return
|
||||||
@ -142,10 +199,10 @@ func (logger *SingleLogger) Log(level LogLevel, logType string, messageParts ...
|
|||||||
debug := ansi.ColorFunc("78")
|
debug := ansi.ColorFunc("78")
|
||||||
section := ansi.ColorFunc("229")
|
section := ansi.ColorFunc("229")
|
||||||
|
|
||||||
levelDisplay := logLevelDisplayNames[level]
|
levelDisplay := LogLevelDisplayNames[level]
|
||||||
if level == LogError {
|
if level == LogError {
|
||||||
levelDisplay = alert(levelDisplay)
|
levelDisplay = alert(levelDisplay)
|
||||||
} else if level == LogWarn {
|
} else if level == LogWarning {
|
||||||
levelDisplay = warn(levelDisplay)
|
levelDisplay = warn(levelDisplay)
|
||||||
} else if level == LogInfo {
|
} else if level == LogInfo {
|
||||||
levelDisplay = info(levelDisplay)
|
levelDisplay = info(levelDisplay)
|
||||||
@ -155,7 +212,7 @@ func (logger *SingleLogger) Log(level LogLevel, logType string, messageParts ...
|
|||||||
|
|
||||||
sep := grey(":")
|
sep := grey(":")
|
||||||
fullStringFormatted := fmt.Sprintf("%s %s %s %s %s %s ", timeGrey(time.Now().UTC().Format("2006-01-02T15:04:05Z")), sep, levelDisplay, sep, section(logType), sep)
|
fullStringFormatted := fmt.Sprintf("%s %s %s %s %s %s ", timeGrey(time.Now().UTC().Format("2006-01-02T15:04:05Z")), sep, levelDisplay, sep, section(logType), sep)
|
||||||
fullStringRaw := fmt.Sprintf("%s : %s : %s : ", time.Now().UTC().Format("2006-01-02T15:04:05Z"), logLevelDisplayNames[level], section(logType))
|
fullStringRaw := fmt.Sprintf("%s : %s : %s : ", time.Now().UTC().Format("2006-01-02T15:04:05Z"), LogLevelDisplayNames[level], section(logType))
|
||||||
for i, p := range messageParts {
|
for i, p := range messageParts {
|
||||||
fullStringFormatted += p
|
fullStringFormatted += p
|
||||||
fullStringRaw += p
|
fullStringRaw += p
|
@ -24,6 +24,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/DanielOaks/girc-go/ircmsg"
|
"github.com/DanielOaks/girc-go/ircmsg"
|
||||||
|
"github.com/DanielOaks/oragono/irc/logger"
|
||||||
"github.com/tidwall/buntdb"
|
"github.com/tidwall/buntdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -102,7 +103,7 @@ type Server struct {
|
|||||||
listenerEventActMutex sync.Mutex
|
listenerEventActMutex sync.Mutex
|
||||||
listeners map[string]ListenerInterface
|
listeners map[string]ListenerInterface
|
||||||
listenerUpdateMutex sync.Mutex
|
listenerUpdateMutex sync.Mutex
|
||||||
logger *Logger
|
logger *logger.Manager
|
||||||
monitoring map[string][]Client
|
monitoring map[string][]Client
|
||||||
motdLines []string
|
motdLines []string
|
||||||
name string
|
name string
|
||||||
@ -137,7 +138,7 @@ type clientConn struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewServer returns a new Oragono server.
|
// NewServer returns a new Oragono server.
|
||||||
func NewServer(configFilename string, config *Config, logger *Logger) (*Server, error) {
|
func NewServer(configFilename string, config *Config, logger *logger.Manager) (*Server, error) {
|
||||||
casefoldedName, err := Casefold(config.Server.Name)
|
casefoldedName, err := Casefold(config.Server.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Server name isn't valid [%s]: %s", config.Server.Name, err.Error())
|
return nil, fmt.Errorf("Server name isn't valid [%s]: %s", config.Server.Name, err.Error())
|
||||||
@ -226,7 +227,7 @@ func NewServer(configFilename string, config *Config, logger *Logger) (*Server,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// open data store
|
// open data store
|
||||||
server.logger.Log(LogDebug, "startup", "Opening datastore")
|
server.logger.Debug("startup", "Opening datastore")
|
||||||
db, err := buntdb.Open(config.Datastore.Path)
|
db, err := buntdb.Open(config.Datastore.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to open datastore: %s", err.Error())
|
return nil, fmt.Errorf("Failed to open datastore: %s", err.Error())
|
||||||
@ -237,7 +238,7 @@ func NewServer(configFilename string, config *Config, logger *Logger) (*Server,
|
|||||||
err = server.store.View(func(tx *buntdb.Tx) error {
|
err = server.store.View(func(tx *buntdb.Tx) error {
|
||||||
version, _ := tx.Get(keySchemaVersion)
|
version, _ := tx.Get(keySchemaVersion)
|
||||||
if version != latestDbSchema {
|
if version != latestDbSchema {
|
||||||
logger.Log(LogError, "startup", "server", fmt.Sprintf("Database must be updated. Expected schema v%s, got v%s.", latestDbSchema, version))
|
logger.Error("startup", "server", fmt.Sprintf("Database must be updated. Expected schema v%s, got v%s.", latestDbSchema, version))
|
||||||
return errDbOutOfDate
|
return errDbOutOfDate
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -249,12 +250,12 @@ func NewServer(configFilename string, config *Config, logger *Logger) (*Server,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load *lines
|
// load *lines
|
||||||
server.logger.Log(LogDebug, "startup", "Loading D/Klines")
|
server.logger.Debug("startup", "Loading D/Klines")
|
||||||
server.loadDLines()
|
server.loadDLines()
|
||||||
server.loadKLines()
|
server.loadKLines()
|
||||||
|
|
||||||
// load password manager
|
// load password manager
|
||||||
server.logger.Log(LogDebug, "startup", "Loading passwords")
|
server.logger.Debug("startup", "Loading passwords")
|
||||||
err = server.store.View(func(tx *buntdb.Tx) error {
|
err = server.store.View(func(tx *buntdb.Tx) error {
|
||||||
saltString, err := tx.Get(keySalt)
|
saltString, err := tx.Get(keySalt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -274,7 +275,7 @@ func NewServer(configFilename string, config *Config, logger *Logger) (*Server,
|
|||||||
return nil, fmt.Errorf("Could not load salt: %s", err.Error())
|
return nil, fmt.Errorf("Could not load salt: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
server.logger.Log(LogDebug, "startup", "Loading MOTD")
|
server.logger.Debug("startup", "Loading MOTD")
|
||||||
if config.Server.MOTD != "" {
|
if config.Server.MOTD != "" {
|
||||||
file, err := os.Open(config.Server.MOTD)
|
file, err := os.Open(config.Server.MOTD)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -320,7 +321,7 @@ func NewServer(configFilename string, config *Config, logger *Logger) (*Server,
|
|||||||
|
|
||||||
// start API if enabled
|
// start API if enabled
|
||||||
if server.restAPI.Enabled {
|
if server.restAPI.Enabled {
|
||||||
logger.Log(LogInfo, "startup", "server", fmt.Sprintf("%s rest API started on %s.", server.name, server.restAPI.Listen))
|
logger.Info("startup", "server", fmt.Sprintf("%s rest API started on %s.", server.name, server.restAPI.Listen))
|
||||||
server.startRestAPI()
|
server.startRestAPI()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,7 +390,7 @@ func (server *Server) Shutdown() {
|
|||||||
server.clients.ByNickMutex.RUnlock()
|
server.clients.ByNickMutex.RUnlock()
|
||||||
|
|
||||||
if err := server.store.Close(); err != nil {
|
if err := server.store.Close(); err != nil {
|
||||||
server.logger.Log(LogError, "shutdown", fmt.Sprintln("Could not close datastore:", err))
|
server.logger.Error("shutdown", fmt.Sprintln("Could not close datastore:", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,10 +407,10 @@ func (server *Server) Run() {
|
|||||||
done = true
|
done = true
|
||||||
|
|
||||||
case <-server.rehashSignal:
|
case <-server.rehashSignal:
|
||||||
server.logger.Log(LogInfo, "rehash", "Rehashing due to SIGHUP")
|
server.logger.Info("rehash", "Rehashing due to SIGHUP")
|
||||||
err := server.rehash()
|
err := server.rehash()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
server.logger.Log(LogError, "rehash", fmt.Sprintln("Failed to rehash:", err.Error()))
|
server.logger.Error("rehash", fmt.Sprintln("Failed to rehash:", err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
case conn := <-server.newConns:
|
case conn := <-server.newConns:
|
||||||
@ -461,7 +462,7 @@ func (server *Server) Run() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
server.logger.Log(LogDebug, "localconnect-ip", fmt.Sprintf("Client connecting from %v", ipaddr))
|
server.logger.Debug("localconnect-ip", fmt.Sprintf("Client connecting from %v", ipaddr))
|
||||||
|
|
||||||
go NewClient(server, conn.Conn, conn.IsTLS)
|
go NewClient(server, conn.Conn, conn.IsTLS)
|
||||||
continue
|
continue
|
||||||
@ -510,7 +511,7 @@ func (server *Server) createListener(addr string, tlsMap map[string]*tls.Config)
|
|||||||
server.listeners[addr] = li
|
server.listeners[addr] = li
|
||||||
|
|
||||||
// start listening
|
// start listening
|
||||||
server.logger.Log(LogInfo, "listeners", fmt.Sprintf("listening on %s using %s.", addr, tlsString))
|
server.logger.Info("listeners", fmt.Sprintf("listening on %s using %s.", addr, tlsString))
|
||||||
|
|
||||||
// setup accept goroutine
|
// setup accept goroutine
|
||||||
go func() {
|
go func() {
|
||||||
@ -562,7 +563,7 @@ func (server *Server) createListener(addr string, tlsMap map[string]*tls.Config)
|
|||||||
server.listenerUpdateMutex.Unlock()
|
server.listenerUpdateMutex.Unlock()
|
||||||
|
|
||||||
// print notice
|
// print notice
|
||||||
server.logger.Log(LogInfo, "listeners", fmt.Sprintf("updated listener %s using %s.", addr, tlsString))
|
server.logger.Info("listeners", fmt.Sprintf("updated listener %s using %s.", addr, tlsString))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// no events waiting for us, fall-through and continue
|
// no events waiting for us, fall-through and continue
|
||||||
@ -578,7 +579,7 @@ func (server *Server) createListener(addr string, tlsMap map[string]*tls.Config)
|
|||||||
func (server *Server) wslisten(addr string, tlsMap map[string]*TLSListenConfig) {
|
func (server *Server) wslisten(addr string, tlsMap map[string]*TLSListenConfig) {
|
||||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != "GET" {
|
if r.Method != "GET" {
|
||||||
server.logger.Log(LogError, "ws", addr, fmt.Sprintf("%s method not allowed", r.Method))
|
server.logger.Error("ws", addr, fmt.Sprintf("%s method not allowed", r.Method))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,7 +592,7 @@ func (server *Server) wslisten(addr string, tlsMap map[string]*TLSListenConfig)
|
|||||||
|
|
||||||
ws, err := upgrader.Upgrade(w, r, nil)
|
ws, err := upgrader.Upgrade(w, r, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
server.logger.Log(LogError, "ws", addr, fmt.Sprintf("%s websocket upgrade error: %s", server.name, err))
|
server.logger.Error("ws", addr, fmt.Sprintf("%s websocket upgrade error: %s", server.name, err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,7 +610,7 @@ func (server *Server) wslisten(addr string, tlsMap map[string]*TLSListenConfig)
|
|||||||
if listenTLS {
|
if listenTLS {
|
||||||
tlsString = "TLS"
|
tlsString = "TLS"
|
||||||
}
|
}
|
||||||
server.logger.Log(LogInfo, "listeners", fmt.Sprintf("websocket listening on %s using %s.", addr, tlsString))
|
server.logger.Info("listeners", fmt.Sprintf("websocket listening on %s using %s.", addr, tlsString))
|
||||||
|
|
||||||
if listenTLS {
|
if listenTLS {
|
||||||
err = http.ListenAndServeTLS(addr, config.Cert, config.Key, nil)
|
err = http.ListenAndServeTLS(addr, config.Cert, config.Key, nil)
|
||||||
@ -617,7 +618,7 @@ func (server *Server) wslisten(addr string, tlsMap map[string]*TLSListenConfig)
|
|||||||
err = http.ListenAndServe(addr, nil)
|
err = http.ListenAndServe(addr, nil)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
server.logger.Log(LogError, "listeners", fmt.Sprintf("listenAndServe error [%s]: %s", tlsString, err))
|
server.logger.Error("listeners", fmt.Sprintf("listenAndServe error [%s]: %s", tlsString, err))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@ -651,7 +652,7 @@ func (server *Server) tryRegister(c *Client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// continue registration
|
// continue registration
|
||||||
server.logger.Log(LogDebug, "localconnect", fmt.Sprintf("Client registered [%s]", c.nick))
|
server.logger.Debug("localconnect", fmt.Sprintf("Client registered [%s]", c.nick))
|
||||||
c.Register()
|
c.Register()
|
||||||
|
|
||||||
// send welcome text
|
// send welcome text
|
||||||
@ -1241,13 +1242,13 @@ func operHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
|||||||
|
|
||||||
// rehash reloads the config and applies the changes from the config file.
|
// rehash reloads the config and applies the changes from the config file.
|
||||||
func (server *Server) rehash() error {
|
func (server *Server) rehash() error {
|
||||||
server.logger.Log(LogDebug, "rehash", "Starting rehash")
|
server.logger.Debug("rehash", "Starting rehash")
|
||||||
|
|
||||||
// only let one REHASH go on at a time
|
// only let one REHASH go on at a time
|
||||||
server.rehashMutex.Lock()
|
server.rehashMutex.Lock()
|
||||||
defer server.rehashMutex.Unlock()
|
defer server.rehashMutex.Unlock()
|
||||||
|
|
||||||
server.logger.Log(LogDebug, "rehash", "Got rehash lock")
|
server.logger.Debug("rehash", "Got rehash lock")
|
||||||
|
|
||||||
config, err := LoadConfig(server.configFilename)
|
config, err := LoadConfig(server.configFilename)
|
||||||
|
|
||||||
@ -1326,7 +1327,7 @@ func (server *Server) rehash() error {
|
|||||||
// STS
|
// STS
|
||||||
stsValue := config.Server.STS.Value()
|
stsValue := config.Server.STS.Value()
|
||||||
var stsDisabled bool
|
var stsDisabled bool
|
||||||
server.logger.Log(LogDebug, "rehash", "STS Vals", CapValues[STS], stsValue, fmt.Sprintf("server[%v] config[%v]", server.stsEnabled, config.Server.STS.Enabled))
|
server.logger.Debug("rehash", "STS Vals", CapValues[STS], stsValue, fmt.Sprintf("server[%v] config[%v]", server.stsEnabled, config.Server.STS.Enabled))
|
||||||
if config.Server.STS.Enabled && !server.stsEnabled {
|
if config.Server.STS.Enabled && !server.stsEnabled {
|
||||||
// enabling STS
|
// enabling STS
|
||||||
SupportedCapabilities[STS] = true
|
SupportedCapabilities[STS] = true
|
||||||
@ -1351,7 +1352,7 @@ func (server *Server) rehash() error {
|
|||||||
|
|
||||||
// updated caps get DEL'd and then NEW'd
|
// updated caps get DEL'd and then NEW'd
|
||||||
// so, we can just add updated ones to both removed and added lists here and they'll be correctly handled
|
// so, we can just add updated ones to both removed and added lists here and they'll be correctly handled
|
||||||
server.logger.Log(LogDebug, "rehash", "Updated Caps", updatedCaps.String(Cap301), strconv.Itoa(len(updatedCaps)))
|
server.logger.Debug("rehash", "Updated Caps", updatedCaps.String(Cap301), strconv.Itoa(len(updatedCaps)))
|
||||||
if len(updatedCaps) > 0 {
|
if len(updatedCaps) > 0 {
|
||||||
for capab := range updatedCaps {
|
for capab := range updatedCaps {
|
||||||
addedCaps[capab] = true
|
addedCaps[capab] = true
|
||||||
@ -1470,13 +1471,13 @@ func (server *Server) rehash() error {
|
|||||||
|
|
||||||
// REHASH
|
// REHASH
|
||||||
func rehashHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
func rehashHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||||
server.logger.Log(LogInfo, "rehash", fmt.Sprintf("REHASH command used by %s", client.nick))
|
server.logger.Info("rehash", fmt.Sprintf("REHASH command used by %s", client.nick))
|
||||||
err := server.rehash()
|
err := server.rehash()
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
client.Send(nil, server.name, RPL_REHASHING, client.nick, "ircd.yaml", "Rehashing")
|
client.Send(nil, server.name, RPL_REHASHING, client.nick, "ircd.yaml", "Rehashing")
|
||||||
} else {
|
} else {
|
||||||
server.logger.Log(LogError, "rehash", fmt.Sprintln("Failed to rehash:", err.Error()))
|
server.logger.Error("rehash", fmt.Sprintln("Failed to rehash:", err.Error()))
|
||||||
client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, "REHASH", err.Error())
|
client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, "REHASH", err.Error())
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
24
oragono.go
24
oragono.go
@ -13,6 +13,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/DanielOaks/oragono/irc"
|
"github.com/DanielOaks/oragono/irc"
|
||||||
|
"github.com/DanielOaks/oragono/irc/logger"
|
||||||
"github.com/DanielOaks/oragono/mkcerts"
|
"github.com/DanielOaks/oragono/mkcerts"
|
||||||
"github.com/docopt/docopt-go"
|
"github.com/docopt/docopt-go"
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
@ -43,7 +44,20 @@ Options:
|
|||||||
log.Fatal("Config file did not load successfully:", err.Error())
|
log.Fatal("Config file did not load successfully:", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
logger, err := irc.NewLogger(config.Logging)
|
// assemble separate log configs
|
||||||
|
var logConfigs []logger.Config
|
||||||
|
for _, lConfig := range config.Logging {
|
||||||
|
logConfigs = append(logConfigs, logger.Config{
|
||||||
|
MethodStderr: lConfig.MethodStderr,
|
||||||
|
MethodFile: lConfig.MethodFile,
|
||||||
|
Filename: lConfig.Filename,
|
||||||
|
Level: lConfig.Level,
|
||||||
|
Types: lConfig.Types,
|
||||||
|
ExcludedTypes: lConfig.ExcludedTypes,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
logger, err := logger.NewManager(logConfigs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Logger did not load successfully:", err.Error())
|
log.Fatal("Logger did not load successfully:", err.Error())
|
||||||
}
|
}
|
||||||
@ -91,16 +105,16 @@ Options:
|
|||||||
} else if arguments["run"].(bool) {
|
} else if arguments["run"].(bool) {
|
||||||
rand.Seed(time.Now().UTC().UnixNano())
|
rand.Seed(time.Now().UTC().UnixNano())
|
||||||
if !arguments["--quiet"].(bool) {
|
if !arguments["--quiet"].(bool) {
|
||||||
logger.Log(irc.LogInfo, "startup", fmt.Sprintf("Oragono v%s starting", irc.SemVer))
|
logger.Info("startup", fmt.Sprintf("Oragono v%s starting", irc.SemVer))
|
||||||
}
|
}
|
||||||
server, err := irc.NewServer(configfile, config, logger)
|
server, err := irc.NewServer(configfile, config, logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Log(irc.LogError, "startup", fmt.Sprintf("Could not load server: %s", err.Error()))
|
logger.Error("startup", fmt.Sprintf("Could not load server: %s", err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !arguments["--quiet"].(bool) {
|
if !arguments["--quiet"].(bool) {
|
||||||
logger.Log(irc.LogInfo, "startup", "Server running")
|
logger.Info("startup", "Server running")
|
||||||
defer logger.Log(irc.LogInfo, "shutdown", fmt.Sprintf("Oragono v%s exiting", irc.SemVer))
|
defer logger.Info("shutdown", fmt.Sprintf("Oragono v%s exiting", irc.SemVer))
|
||||||
}
|
}
|
||||||
server.Run()
|
server.Run()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user