go-vise

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

vanilla.go (4678B)


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