Content inside fengaldar
(The raw file follows this syntax highlighted file.)

package fengaldar

import (
	"fmt"
	"strings"
)

type LogContext map[string]string

func (lc LogContext) String() string {
	var s strings.Builder
	s.WriteString(" \u250f\n")
	for k, v := range lc {
		s.WriteString(fmt.Sprintf(" \u2503 %q: %q\n", k, v))
	}
	s.WriteString(" \u2517")
	return s.String()
}

func (lc LogContext) JSON() string {
	var s strings.Builder
	s.WriteString("{")
	first := true
	for k, v := range lc {
		if !first {
			s.WriteString(",")
		}
		s.WriteString(fmt.Sprintf("%q:%q", k, v))
		first = false
	}
	s.WriteString("}")
	return s.String()
}

type Logger interface {
	Println(...interface{})
	Log(string, LogContext) // TODO - severity... LogFatal... LogDebug... or maybe Fatal... Debug... with 'Log' being Info
	/*
		Debug - debug or trace information.
		Info - routine information, such as ongoing status or performance.
		Notice - normal but significant events, such as start up, shut down, or configuration.
		Warning - events that might cause problems.
		Error - events that are likely to cause problems.
		Critical - events that cause more severe problems or brief outages.
		Alert - a person must take an action immediately.
		Emergency - one or more systems are unusable.
	*/
}

func NewLogger() Logger { return &simpleLogger{} }

type simpleLogger struct{}

func (sl simpleLogger) Println(ss ...interface{})   { fmt.Println(ss...) }
func (sl simpleLogger) Log(s string, lc LogContext) { fmt.Println(s); fmt.Println(lc) }

func NewJSONLogger() Logger { return &jsonLogger{} }

type jsonLogger struct{}

func (jl jsonLogger) Println(ss ...interface{}) {
	var jss strings.Builder
	for i, s := range ss {
		if i > 0 {
			jss.WriteString("\n")
		}
		jss.WriteString(s.(string))
	}
	fmt.Printf(`{"message":%q}
`, jss.String())
}
func (jl jsonLogger) Log(s string, lc LogContext) {
	fmt.Printf(`{"message":%q, "additionalContext":%q}
`, s, lc.JSON())
}


The raw file follows...


package fengaldar

import (
	"fmt"
	"strings"
)

type LogContext map[string]string

func (lc LogContext) String() string {
	var s strings.Builder
	s.WriteString(" \u250f\n")
	for k, v := range lc {
		s.WriteString(fmt.Sprintf(" \u2503 %q: %q\n", k, v))
	}
	s.WriteString(" \u2517")
	return s.String()
}

func (lc LogContext) JSON() string {
	var s strings.Builder
	s.WriteString("{")
	first := true
	for k, v := range lc {
		if !first {
			s.WriteString(",")
		}
		s.WriteString(fmt.Sprintf("%q:%q", k, v))
		first = false
	}
	s.WriteString("}")
	return s.String()
}

type Logger interface {
	Println(...interface{})
	Log(string, LogContext) // TODO - severity... LogFatal... LogDebug... or maybe Fatal... Debug... with 'Log' being Info
	/*
		Debug - debug or trace information.
		Info - routine information, such as ongoing status or performance.
		Notice - normal but significant events, such as start up, shut down, or configuration.
		Warning - events that might cause problems.
		Error - events that are likely to cause problems.
		Critical - events that cause more severe problems or brief outages.
		Alert - a person must take an action immediately.
		Emergency - one or more systems are unusable.
	*/
}

func NewLogger() Logger { return &simpleLogger{} }

type simpleLogger struct{}

func (sl simpleLogger) Println(ss ...interface{})   { fmt.Println(ss...) }
func (sl simpleLogger) Log(s string, lc LogContext) { fmt.Println(s); fmt.Println(lc) }

func NewJSONLogger() Logger { return &jsonLogger{} }

type jsonLogger struct{}

func (jl jsonLogger) Println(ss ...interface{}) {
	var jss strings.Builder
	for i, s := range ss {
		if i > 0 {
			jss.WriteString("\n")
		}
		jss.WriteString(s.(string))
	}
	fmt.Printf(`{"message":%q}
`, jss.String())
}
func (jl jsonLogger) Log(s string, lc LogContext) {
	fmt.Printf(`{"message":%q, "additionalContext":%q}
`, s, lc.JSON())
}