import libricochet-go log as stand alone repo
This commit is contained in:
parent
773ebe5a64
commit
83b42d7e9b
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) <year> <copyright holders>
|
||||
Copyright (c) <2020> <Open Privacy Research Society>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
25
README.md
25
README.md
|
@ -1,3 +1,26 @@
|
|||
# log
|
||||
|
||||
Simple configurable logging tool
|
||||
A simple log primative Open Privacy uses
|
||||
|
||||
## Examples:
|
||||
|
||||
log.AddEverythingFromPattern("connectivity")
|
||||
log.SetLevel(log.LevelDebug)
|
||||
log.ExcludeFromPattern("connection/connection")
|
||||
log.ExcludeFromPattern("outbound/3dhauthchannel")
|
||||
|
||||
log.Debugf("Creating the thing with param %v\n", param)
|
||||
log.Infoln("Doing thing X")
|
||||
log.Warnf("This might be bad: %v\n", err)
|
||||
log.Errorf("Failed to do thing: %v\n", err)
|
||||
|
||||
### Making log go to a file
|
||||
|
||||
```
|
||||
if runtime.GOOS == "windows" {
|
||||
filelogger, err := log.NewFile(log.LevelInfo, "cwtch_log.txt")
|
||||
if err == nil {
|
||||
log.SetStd(filelogger)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
@ -0,0 +1,219 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
golog "log"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Level indicates the level a log should be classified at
|
||||
type Level int
|
||||
|
||||
// The possible levels a log can have
|
||||
const (
|
||||
LevelDebug Level = iota + 1
|
||||
LevelInfo
|
||||
LevelWarn
|
||||
LevelError
|
||||
)
|
||||
|
||||
var levelString = map[Level]string{LevelDebug: "[DBUG]", LevelInfo: "[INFO]", LevelWarn: "[WARN]", LevelError: "[ERR ]"}
|
||||
|
||||
// Logger is a go Logger wrapper that adds log levels and pattern filtering
|
||||
// It allows high level 'log level' filtering broadly
|
||||
// It allows allows two addition levels of filtering:
|
||||
// everythingFrom which allows inclusion of packages/patterns along with general logging
|
||||
// nothingExcept which allows focusing on just listed areas
|
||||
type Logger struct {
|
||||
logger *golog.Logger
|
||||
level Level
|
||||
nothingExceptPatterns []string
|
||||
everythingFromPatterns []string
|
||||
excludeFromPatterns []string
|
||||
}
|
||||
|
||||
// New returns a new Logger with a filter set to the supplied level
|
||||
func New(level Level) *Logger {
|
||||
return &Logger{logger: golog.New(os.Stderr, "", golog.Ldate|golog.Ltime), level: level, everythingFromPatterns: make([]string, 0), nothingExceptPatterns: make([]string, 0)}
|
||||
}
|
||||
|
||||
// NewFile returns a new Logger that logs to the supplied file with a filter set to the supplied level
|
||||
func NewFile(level Level, filename string) (*Logger, error) {
|
||||
logfile, err := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Logger{logger: golog.New(logfile, "", golog.Ldate|golog.Ltime), level: level, everythingFromPatterns: make([]string, 0), nothingExceptPatterns: make([]string, 0)}, nil
|
||||
}
|
||||
|
||||
var std = New(LevelWarn)
|
||||
|
||||
// SetStd sets the default logger all other functions use
|
||||
func SetStd(logger *Logger) {
|
||||
std = logger
|
||||
}
|
||||
|
||||
// filter
|
||||
func (l *Logger) filter(level Level) bool {
|
||||
|
||||
_, file, _, ok := runtime.Caller(3)
|
||||
if !ok {
|
||||
file = "???"
|
||||
}
|
||||
|
||||
for _, pattern := range l.excludeFromPatterns {
|
||||
if strings.Contains(file, pattern) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
for _, pattern := range l.everythingFromPatterns {
|
||||
if strings.Contains(file, pattern) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
for _, pattern := range l.nothingExceptPatterns {
|
||||
if strings.Contains(file, pattern) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if len(l.nothingExceptPatterns) > 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return l.aboveLevel(level)
|
||||
}
|
||||
|
||||
func (l *Logger) aboveLevel(level Level) bool {
|
||||
return level >= l.level
|
||||
}
|
||||
|
||||
// SetLevel adjusts the output filter by logging level
|
||||
func (l *Logger) SetLevel(level Level) {
|
||||
l.level = level
|
||||
}
|
||||
|
||||
// AddNothingExceptFilter enables strong filtering showing logs only for things on the approved list, adding this pattern to the list
|
||||
func (l *Logger) AddNothingExceptFilter(pattern string) {
|
||||
l.nothingExceptPatterns = append(l.nothingExceptPatterns, pattern)
|
||||
}
|
||||
|
||||
// AddEverythingFromPattern adds a pattern to skip log level filtering, guaranteeing all logs matching the pattern are seen
|
||||
func (l *Logger) AddEverythingFromPattern(pattern string) {
|
||||
l.everythingFromPatterns = append(l.everythingFromPatterns, pattern)
|
||||
}
|
||||
|
||||
// ExcludeFromPattern adds a pattern to exclude logs from
|
||||
func (l *Logger) ExcludeFromPattern(pattern string) {
|
||||
l.excludeFromPatterns = append(l.excludeFromPatterns, pattern)
|
||||
}
|
||||
|
||||
func (l *Logger) header(level Level) string {
|
||||
_, file, _, ok := runtime.Caller(3)
|
||||
if !ok {
|
||||
file = "???"
|
||||
} else {
|
||||
short := file
|
||||
count := 0
|
||||
for i := len(file) - 1; i > 0; i-- {
|
||||
if file[i] == '/' {
|
||||
short = file[i+1:]
|
||||
count++
|
||||
if count == 2 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
file = short
|
||||
}
|
||||
return file + " " + levelString[level] + " "
|
||||
}
|
||||
|
||||
// Printf outputs the format and variables, assuming it passes the filter levels
|
||||
func (l *Logger) Printf(level Level, format string, v ...interface{}) {
|
||||
if l.filter(level) {
|
||||
l.logger.Output(3, l.header(level)+fmt.Sprintf(format, v...))
|
||||
}
|
||||
}
|
||||
|
||||
// Println outputs the variables assuming the filter levels are passed
|
||||
func (l *Logger) Println(level Level, v ...interface{}) {
|
||||
if l.filter(level) {
|
||||
l.logger.Output(3, l.header(level)+fmt.Sprintln(v...))
|
||||
}
|
||||
}
|
||||
|
||||
// SetLevel changes the filtering level of the system logger
|
||||
func SetLevel(level Level) {
|
||||
std.SetLevel(level)
|
||||
}
|
||||
|
||||
// AddNothingExceptFilter enables strong filtering showing logs only for things on the approved list, adding this pattern to the list
|
||||
func AddNothingExceptFilter(pattern string) {
|
||||
std.AddNothingExceptFilter(pattern)
|
||||
}
|
||||
|
||||
// AddEverythingFromPattern adds a pattern to skip log level filtering, guaranteeing all logs matching the pattern are seen
|
||||
func AddEverythingFromPattern(pattern string) {
|
||||
std.AddEverythingFromPattern(pattern)
|
||||
}
|
||||
|
||||
// ExcludeFromPattern adds a pattern to exclude logs from
|
||||
func ExcludeFromPattern(pattern string) {
|
||||
std.ExcludeFromPattern(pattern)
|
||||
}
|
||||
|
||||
// Printf outputs the format with variables assuming it passes the filter level
|
||||
func Printf(level Level, format string, v ...interface{}) {
|
||||
std.Printf(level, format, v...)
|
||||
}
|
||||
|
||||
// Println outputs the varibles assuming they pass the filter level
|
||||
func Println(level Level, v ...interface{}) {
|
||||
std.Println(level, v...)
|
||||
}
|
||||
|
||||
// Debugf outputs the format and variables at the Debug level
|
||||
func Debugf(format string, v ...interface{}) {
|
||||
std.Printf(LevelDebug, format, v...)
|
||||
}
|
||||
|
||||
// Infof outputs the format and variables at the Info level
|
||||
func Infof(format string, v ...interface{}) {
|
||||
std.Printf(LevelInfo, format, v...)
|
||||
}
|
||||
|
||||
// Warnf outputs the format and variables at the Warning level
|
||||
func Warnf(format string, v ...interface{}) {
|
||||
std.Printf(LevelWarn, format, v...)
|
||||
}
|
||||
|
||||
// Errorf outputs the format and variables at the Error level
|
||||
func Errorf(format string, v ...interface{}) {
|
||||
std.Printf(LevelError, format, v...)
|
||||
}
|
||||
|
||||
// Debugln outputs the variables at the Debug level
|
||||
func Debugln(v ...interface{}) {
|
||||
std.Println(LevelDebug, v...)
|
||||
}
|
||||
|
||||
// Infoln outputs the variables at the Info level
|
||||
func Infoln(v ...interface{}) {
|
||||
std.Println(LevelInfo, v...)
|
||||
}
|
||||
|
||||
// Warnln outputs the variables at the Warn level
|
||||
func Warnln(v ...interface{}) {
|
||||
std.Println(LevelWarn, v...)
|
||||
}
|
||||
|
||||
// Errorln outputs the variables at the Error level
|
||||
func Errorln(v ...interface{}) {
|
||||
std.Println(LevelError, v...)
|
||||
}
|
Loading…
Reference in New Issue