go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

vanilla.go (4797B)


      1 package logging
      2 
      3 import (
      4 	"context"
      5 	"fmt"
      6 	"io"
      7 	"os"
      8 	"path"
      9 	"runtime"
     10 )
     11 
     12 var (
     13 	// LogWriter is used as io.Writer the Vanilla Logger implementation.
     14 	LogWriter = os.Stderr
     15 )
     16 
     17 // Vanilla is a basic single-line structured output logger for terminal output.
     18 type Vanilla struct {
     19 	domain string
     20 	levelFilter int
     21 }
     22 
     23 // NewVanilla creates a new Vanilla logger.
     24 func NewVanilla() Vanilla {
     25 	return Vanilla{
     26 		domain: "main",
     27 		levelFilter: LogLevel,
     28 	}
     29 }
     30 
     31 // WithDomain sets the logging domain. It is prepended to the caller file/line information.
     32 func(v Vanilla) WithDomain(domain string) Vanilla {
     33 	v.domain = domain
     34 	return v
     35 }
     36 
     37 // WithLevel overrides the globally set loglevel for the logger instance.
     38 func(v Vanilla) WithLevel(level int) Vanilla {
     39 	v.levelFilter = level
     40 	return v
     41 }
     42 
     43 // Printf logs to the global writer.
     44 func(v Vanilla) Printf(level int, msg string, args ...any) {
     45 	v.Writef(LogWriter, level, msg, args...)
     46 }
     47 
     48 // compile log line from inputs and send to given writer.
     49 func(v Vanilla) writef(w io.Writer, file string, line int, level int, msg string, args ...any) {
     50 	if level > v.levelFilter {
     51 		return
     52 	}
     53 	argsStr := argsToString(args)
     54 	if len(msg) > 0 {
     55 		fmt.Fprintf(w, "[%s] %s:%s:%v %s\t%s\n", AsString(level), v.domain, file, line, msg, argsStr)
     56 	} else {
     57 		fmt.Fprintf(w, "[%s] %s:%s:%v %s\n", AsString(level), v.domain, file, line, argsStr)
     58 	}
     59 }
     60 
     61 // Writef logs to the given writer.
     62 func(v Vanilla) Writef(w io.Writer, level int, msg string, args ...any) {
     63 	file, line := getCaller(2)
     64 	v.writef(w, file, line, level, msg, args)
     65 }
     66 
     67 // WriteCtxf logs with context to the given writer.
     68 func(v Vanilla) WriteCtxf(ctx context.Context, w io.Writer, level int, msg string, args ...any) {
     69 	file, line := getCaller(2)
     70 	v.writef(w, file, line, level, msg, args...)
     71 }
     72 
     73 // get caller information and pass on to writef
     74 func(v Vanilla) printf(level int, msg string, args ...any) {
     75 	file, line := getCaller(3)
     76 	v.writef(LogWriter, file, line, level, msg, args...)
     77 }
     78 
     79 // get caller information and pass on to writef
     80 func(v Vanilla) printCtxf(ctx context.Context, level int, msg string, args ...any) {
     81 	file, line := getCaller(3)
     82 	v.writef(LogWriter, file, line, level, msg, args...)
     83 }
     84 
     85 // PrintCtxf logs with context to the global writer.
     86 func(v Vanilla) PrintCtxf(ctx context.Context, level int, msg string, args ...any) {
     87 	v.printf(level, msg, args...)
     88 }
     89 
     90 // Tracef logs a line with level TRACE to the global writer.
     91 func(v Vanilla) Tracef(msg string, args ...any) {
     92 	v.printf(LVL_TRACE, msg, args...)
     93 }
     94 
     95 // Debugf logs a line with level DEBUG to the global writer.
     96 func(v Vanilla) Debugf(msg string, args ...any) {
     97 	v.printf(LVL_DEBUG, msg, args...)
     98 }
     99 
    100 // Infof logs a line with level INFO to the global writer.
    101 func(v Vanilla) Infof(msg string, args ...any) {
    102 	v.printf(LVL_INFO, msg, args...)
    103 }
    104 
    105 // Warnf logs a line with level WARN to the global writer.
    106 func(v Vanilla) Warnf(msg string, args ...any) {
    107 	v.printf(LVL_WARN, msg, args...)
    108 }
    109 
    110 // Errorf logs a line with level ERROR to the global writer.
    111 func(v Vanilla) Errorf(msg string, args ...any) {
    112 	v.printf(LVL_ERROR, msg, args...)
    113 }
    114 
    115 // TraceCtxf logs a line with context with level TRACE to the global writer.
    116 func(v Vanilla) TraceCtxf(ctx context.Context, msg string, args ...any) {
    117 	v.printCtxf(ctx, LVL_TRACE, msg, args...)
    118 }
    119 
    120 // DebugCtxf logs a line with context with level DEBUG to the global writer.
    121 func(v Vanilla) DebugCtxf(ctx context.Context, msg string, args ...any) {
    122 	v.printCtxf(ctx, LVL_DEBUG, msg, args...)
    123 }
    124 
    125 // InfoCtxf logs a line with context with level INFO to the global writer.
    126 func(v Vanilla) InfoCtxf(ctx context.Context, msg string, args ...any) {
    127 	v.printCtxf(ctx, LVL_INFO, msg, args...)
    128 }
    129 
    130 // WarnCtxf logs a line with context with level WARN to the global writer.
    131 func(v Vanilla) WarnCtxf(ctx context.Context, msg string, args ...any) {
    132 	v.printCtxf(ctx, LVL_WARN, msg, args...)
    133 }
    134 
    135 // ErrorCtxf logs a line with context with level ERROR to the global writer.
    136 func(v Vanilla) ErrorCtxf(ctx context.Context, msg string, args ...any) {
    137 	v.printCtxf(ctx, LVL_ERROR, msg, args...)
    138 }
    139 
    140 // return file basename and line for caller information.
    141 func getCaller(depth int) (string, int) {
    142 	var file string
    143 	var line int
    144 	_, file, line,_ = runtime.Caller(depth)
    145 	baseFile := path.Base(file)
    146 	return baseFile, line
    147 }
    148 
    149 // string representation of the given structured log args.
    150 func argsToString(args []any) string {
    151 	var s string
    152 	c := len(args)
    153 	var i int
    154 	for i = 0; i < c; i += 2 {
    155 		if len(s) > 0 {
    156 			s += ", "
    157 		}
    158 
    159 		if i + 1 < c {
    160 			var argByte []byte
    161 			var ok bool
    162 			argByte, ok = args[i+1].([]byte)
    163 			if ok {
    164 				s += fmt.Sprintf("%s=%x", args[i], argByte)
    165 			} else {
    166 				s += fmt.Sprintf("%s=%v", args[i], args[i+1])
    167 			}
    168 		} else {
    169 			s += fmt.Sprintf("%s=??", args[i])
    170 		}
    171 	}
    172 	return s
    173 }