logger: Initial new logger

This commit is contained in:
Daniel Oaks 2017-03-06 13:05:33 +10:00
parent 3058161f62
commit ba0f291e20
3 changed files with 110 additions and 67 deletions

106
irc/logger.go Normal file
View File

@ -0,0 +1,106 @@
// Copyright (c) 2017 Daniel Oaks <daniel@danieloaks.net>
// released under the MIT license
package irc
import (
"bufio"
"fmt"
"os"
"time"
)
// LogLevel represents the level to log messages at.
type LogLevel int
const (
// LogDebug represents debug messages.
LogDebug LogLevel = iota
// LogInfo represents informational messages.
LogInfo
// LogWarn represents warnings.
LogWarn
// LogError represents errors.
LogError
)
// ClientLogger is a logger dedicated to a single client. This is a convenience class that
// automagically adds the client nick to logged messages.
type ClientLogger struct {
client *Client
}
// NewClientLogger returns a new ClientLogger.
func NewClientLogger(client *Client) ClientLogger {
logger := ClientLogger{
client: client,
}
return logger
}
// Log logs the given message with the given details.
func (logger *ClientLogger) Log(level LogLevel, logType, object, message string) {
object = fmt.Sprintf("%s : %s", logger.client.nick, object)
logger.client.server.logger.Log(level, logType, object, message)
}
// Logger is the main interface used to log debug/info/error messages.
type Logger struct {
loggers []SingleLogger
}
// NewLogger returns a new Logger.
func NewLogger(config LogConfig) (*Logger, error) {
return nil, fmt.Errorf("Not implemented")
}
// Log logs the given message with the given details.
func (logger *Logger) Log(level LogLevel, logType, object, message string) {
for _, singleLogger := range logger.loggers {
singleLogger.Log(level, logType, object, message)
}
}
// SingleLogger represents a single logger instance.
type SingleLogger struct {
MethodSTDERR bool
MethodFile struct {
Enabled bool
Filename string
File os.File
Writer bufio.Writer
}
Level LogLevel
Types map[string]bool
ExcludedTypes map[string]bool
}
// Log logs the given message with the given details.
func (logger *SingleLogger) Log(level LogLevel, logType, object, message string) {
// no logging enabled
if !(logger.MethodSTDERR || logger.MethodFile.Enabled) {
return
}
// ensure we're logging to the given level
if level < logger.Level {
return
}
// ensure we're capturing this logType
capturing := (logger.Types["*"] || logger.Types[logType]) && !logger.ExcludedTypes["*"] && !logger.ExcludedTypes[logType]
if !capturing {
return
}
// assemble full line
fullString := fmt.Sprintf("%s : %s : %s : %s", time.Now().UTC().Format("2006-01-02T15:04:05.999Z"), logType, object, message)
// output
if logger.MethodSTDERR {
fmt.Fprintln(os.Stderr, fullString)
}
if logger.MethodFile.Enabled {
logger.MethodFile.Writer.WriteString(fullString + "\n")
}
}

View File

@ -1,64 +0,0 @@
// Copyright (c) 2012-2014 Jeremy Latt
// released under the MIT license
package irc
import (
"io"
"log"
"os"
)
type Logging struct {
debug *log.Logger
info *log.Logger
warn *log.Logger
error *log.Logger
}
var (
levels = map[string]uint8{
"debug": 4,
"info": 3,
"warn": 2,
"error": 1,
}
devNull io.Writer
)
func init() {
var err error
devNull, err = os.Open(os.DevNull)
if err != nil {
log.Fatal(err)
}
}
func NewLogger(on bool) *log.Logger {
return log.New(output(on), "", log.LstdFlags)
}
func output(on bool) io.Writer {
if on {
return os.Stdout
}
return devNull
}
func (logging *Logging) SetLevel(level string) {
logging.debug = NewLogger(levels[level] >= levels["debug"])
logging.info = NewLogger(levels[level] >= levels["info"])
logging.warn = NewLogger(levels[level] >= levels["warn"])
logging.error = NewLogger(levels[level] >= levels["error"])
}
func NewLogging(level string) *Logging {
logging := &Logging{}
logging.SetLevel(level)
return logging
}
var (
// Log is the default logger.
Log = NewLogging("warn")
)

View File

@ -80,18 +80,18 @@ type ListenerEvent struct {
// Server is the main Oragono server.
type Server struct {
accountAuthenticationEnabled bool
accountRegistration *AccountRegistration
accounts map[string]*ClientAccount
accountAuthenticationEnabled bool
channels ChannelNameMap
checkIdent bool
clients *ClientLookupSet
commands chan Command
configFilename string
connectionThrottle *ConnectionThrottle
connectionThrottleMutex sync.Mutex // used when affecting the connection limiter, to make sure rehashing doesn't make things go out-of-whack
connectionLimits *ConnectionLimits
connectionLimitsMutex sync.Mutex // used when affecting the connection limiter, to make sure rehashing doesn't make things go out-of-whack
connectionThrottle *ConnectionThrottle
connectionThrottleMutex sync.Mutex // used when affecting the connection limiter, to make sure rehashing doesn't make things go out-of-whack
ctime time.Time
currentOpers map[*Client]bool
dlines *DLineManager
@ -102,6 +102,7 @@ type Server struct {
listenerEventActMutex sync.Mutex
listeners map[string]ListenerInterface
listenerUpdateMutex sync.Mutex
logger *Logger
monitoring map[string][]Client
motdLines []string
name string