mirror of
https://github.com/evilsocket/opensnitch.git
synced 2025-03-04 08:34:40 +01:00
262 lines
5 KiB
Go
262 lines
5 KiB
Go
package log
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type Handler func(format string, args ...interface{})
|
|
|
|
// https://misc.flogisoft.com/bash/tip_colors_and_formatting
|
|
const (
|
|
BOLD = "\033[1m"
|
|
DIM = "\033[2m"
|
|
|
|
RED = "\033[31m"
|
|
GREEN = "\033[32m"
|
|
BLUE = "\033[34m"
|
|
YELLOW = "\033[33m"
|
|
|
|
FG_BLACK = "\033[30m"
|
|
FG_WHITE = "\033[97m"
|
|
|
|
BG_PURPLE = "\033[45m"
|
|
BG_RED = "\033[41m"
|
|
BG_GREEN = "\033[42m"
|
|
BG_YELLOW = "\033[43m"
|
|
BG_DGRAY = "\033[100m"
|
|
BG_LBLUE = "\033[104m"
|
|
|
|
RESET = "\033[0m"
|
|
)
|
|
|
|
// log level constants
|
|
const (
|
|
DEBUG = iota
|
|
INFO
|
|
IMPORTANT
|
|
WARNING
|
|
ERROR
|
|
FATAL
|
|
|
|
TRACE = -1
|
|
)
|
|
|
|
//
|
|
var (
|
|
WithColors = true
|
|
Output = os.Stdout
|
|
StdoutFile = "/dev/stdout"
|
|
DateFormat = "2006-01-02 15:04:05"
|
|
MinLevel = int(INFO)
|
|
LogUTC = true
|
|
LogMicro = false
|
|
|
|
mutex = &sync.RWMutex{}
|
|
labels = map[int]string{
|
|
TRACE: "TRC",
|
|
DEBUG: "DBG",
|
|
INFO: "INF",
|
|
IMPORTANT: "IMP",
|
|
WARNING: "WAR",
|
|
ERROR: "ERR",
|
|
FATAL: "!!!",
|
|
}
|
|
colors = map[int]string{
|
|
TRACE: FG_WHITE + BG_PURPLE,
|
|
DEBUG: DIM + FG_BLACK + BG_DGRAY,
|
|
INFO: FG_WHITE + BG_GREEN,
|
|
IMPORTANT: FG_WHITE + BG_LBLUE,
|
|
WARNING: FG_WHITE + BG_YELLOW,
|
|
ERROR: FG_WHITE + BG_RED,
|
|
FATAL: FG_WHITE + BG_RED + BOLD,
|
|
}
|
|
)
|
|
|
|
// Wrap wraps a text with effects
|
|
func Wrap(s, effect string) string {
|
|
if WithColors == true {
|
|
s = effect + s + RESET
|
|
}
|
|
return s
|
|
}
|
|
|
|
// Dim dims a text
|
|
func Dim(s string) string {
|
|
return Wrap(s, DIM)
|
|
}
|
|
|
|
// Bold bolds a text
|
|
func Bold(s string) string {
|
|
return Wrap(s, BOLD)
|
|
}
|
|
|
|
// Red reds the text
|
|
func Red(s string) string {
|
|
return Wrap(s, RED)
|
|
}
|
|
|
|
// Green greens the text
|
|
func Green(s string) string {
|
|
return Wrap(s, GREEN)
|
|
}
|
|
|
|
// Blue blues the text
|
|
func Blue(s string) string {
|
|
return Wrap(s, BLUE)
|
|
}
|
|
|
|
// Yellow yellows the text
|
|
func Yellow(s string) string {
|
|
return Wrap(s, YELLOW)
|
|
}
|
|
|
|
// Raw prints out a text without colors
|
|
func Raw(format string, args ...interface{}) {
|
|
mutex.RLock()
|
|
defer mutex.RUnlock()
|
|
fmt.Fprintf(Output, format, args...)
|
|
}
|
|
|
|
// SetLogLevel sets the log level
|
|
func SetLogLevel(newLevel int) {
|
|
mutex.Lock()
|
|
defer mutex.Unlock()
|
|
MinLevel = newLevel
|
|
}
|
|
|
|
// GetLogLevel returns the current log level configured.
|
|
func GetLogLevel() int {
|
|
mutex.RLock()
|
|
defer mutex.RUnlock()
|
|
|
|
return MinLevel
|
|
}
|
|
|
|
// SetLogUTC configures UTC timestamps
|
|
func SetLogUTC(newLogUTC bool) {
|
|
mutex.Lock()
|
|
defer mutex.Unlock()
|
|
LogUTC = newLogUTC
|
|
}
|
|
|
|
// GetLogUTC returns the current config.
|
|
func GetLogUTC() bool {
|
|
mutex.RLock()
|
|
defer mutex.RUnlock()
|
|
|
|
return LogUTC
|
|
}
|
|
|
|
// SetLogMicro configures microsecond timestamps
|
|
func SetLogMicro(newLogMicro bool) {
|
|
mutex.Lock()
|
|
defer mutex.Unlock()
|
|
LogMicro = newLogMicro
|
|
}
|
|
|
|
// GetLogMicro returns the current config.
|
|
func GetLogMicro() bool {
|
|
mutex.Lock()
|
|
defer mutex.Unlock()
|
|
|
|
return LogMicro
|
|
}
|
|
|
|
// Log prints out a text with the given color and format
|
|
func Log(level int, format string, args ...interface{}) {
|
|
mutex.RLock()
|
|
defer mutex.RUnlock()
|
|
if level >= MinLevel {
|
|
label := labels[level]
|
|
color := colors[level]
|
|
datefmt := DateFormat
|
|
|
|
if LogMicro {
|
|
datefmt = DateFormat + ".000000"
|
|
}
|
|
when := time.Now().UTC().Format(datefmt)
|
|
if LogUTC == false {
|
|
when = time.Now().Local().Format(datefmt)
|
|
}
|
|
|
|
what := fmt.Sprintf(format, args...)
|
|
if strings.HasSuffix(what, "\n") == false {
|
|
what += "\n"
|
|
}
|
|
|
|
l := Dim("[%s]")
|
|
r := Wrap(" %s ", color) + " %s"
|
|
|
|
fmt.Fprintf(Output, l+" "+r, when, label, what)
|
|
}
|
|
}
|
|
|
|
func setDefaultLogOutput() {
|
|
mutex.Lock()
|
|
Output = os.Stdout
|
|
mutex.Unlock()
|
|
}
|
|
|
|
// OpenFile opens a file to print out the logs
|
|
func OpenFile(logFile string) (err error) {
|
|
if logFile == StdoutFile {
|
|
setDefaultLogOutput()
|
|
return
|
|
}
|
|
|
|
if Output, err = os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err != nil {
|
|
Error("Error opening log: %s %s", logFile, err)
|
|
//fallback to stdout
|
|
setDefaultLogOutput()
|
|
}
|
|
Important("Start writing logs to %s", logFile)
|
|
|
|
return err
|
|
}
|
|
|
|
// Close closes the current output file descriptor
|
|
func Close() {
|
|
if Output != os.Stdout {
|
|
Output.Close()
|
|
}
|
|
}
|
|
|
|
// Trace is the log level for tracing purposes
|
|
func Trace(format string, args ...interface{}) {
|
|
Log(TRACE, format, args...)
|
|
}
|
|
|
|
// Debug is the log level for debugging purposes
|
|
func Debug(format string, args ...interface{}) {
|
|
Log(DEBUG, format, args...)
|
|
}
|
|
|
|
// Info is the log level for informative messages
|
|
func Info(format string, args ...interface{}) {
|
|
Log(INFO, format, args...)
|
|
}
|
|
|
|
// Important is the log level for things that must pay attention
|
|
func Important(format string, args ...interface{}) {
|
|
Log(IMPORTANT, format, args...)
|
|
}
|
|
|
|
// Warning is the log level for non-critical errors
|
|
func Warning(format string, args ...interface{}) {
|
|
Log(WARNING, format, args...)
|
|
}
|
|
|
|
// Error is the log level for errors that should be corrected
|
|
func Error(format string, args ...interface{}) {
|
|
Log(ERROR, format, args...)
|
|
}
|
|
|
|
// Fatal is the log level for errors that must be corrected before continue
|
|
func Fatal(format string, args ...interface{}) {
|
|
Log(FATAL, format, args...)
|
|
os.Exit(1)
|
|
}
|