
Echidna Library for Go

Table of Contents
1. Overview
import "github.com/bruceesmith/echidna"
Package echidna provides sub-packages for building robust Go daemons and CLIs
-
logger supports logging and tracing based on the standard library package log/slog.
-
observable is an implementation of the Gang of Four observer pattern, useful in event-driven programs such as GUIs.
-
program builds upon the Github packages knadh/koanf and urfave/cli/v3 to make it extremely simple to use the features of those two excellent packages in concert.
-
set defines goroutine-safe methods for manipulating a generic set data structure via the standard operations Add, Contains, Intersection, Members, String and Union.
-
stack defines goroutine-safe methods for manipulating a generic stack data structure via the standard operations IsEmpty, Peek, Pop, Push and Size.
-
terminator permits orderly stopping / shutdown of a group of goroutines via methods which mimic a sync.WaitGroup. There is a default [terminator.Terminator] accessible through top level functions (Add, Done, Wait and so on) that call the corresponding Terminator methods.
Refer to the documentation for the individual packages for more details.
Index
Variables
var (
// BuildDate is the timestamp for when this program was compiled
BuildDate string = `Filled in during the build`
)
2. logger
import "github.com/bruceesmith/echidna/logger"
Package logger supports logging and tracing based on the standard library package slog.
Debug, Error, Info and Warn operate like their package slog equivalents, with the level of logging modifiable using SetLevel.
A custom logging level (LevelTrace) can be supplied to SetLevel to enable tracing. Tracing can be unconditional when calling Trace, or only enabled for pre-defined identifiers when calling TraceID. Identifiers for TraceID are registered by calling SetTraceIDs.
By default, all debug, error, info and warn messages go to Stdout, and traces go to Stderr; these destinations can be changed by calling RedirectNormal and RedirectTrace respectively.
When used in cli applications, a cli.Flag representing a LogLevel can be provided using the LogLevelFlag type.
Index
func Debug(msg string, args ...any)
Debug emits a debug log
func Error(msg string, args ...any)
Error emits an error log
func Info(msg string, args ...any)
Info emits an info log
func Level() string
func RedirectStandard(w io.Writer)
RedirectStandard changes the destination for normal (non-trace) logs
func RedirectTrace(w io.Writer)
RedirectTrace changes the destination for normal (non-trace) logs
func SetFormat(f Format)
SetFormat changes the format of log entries
func SetLevel(l slog.Level)
SetLevel sets the default level of logging
func SetTraceIds(ids ...string)
SetTraceIds registers identifiers for future tracing
func Trace(msg string, args ...any)
Trace emits one JSON-formatted log entry if trace level logging is enabled
func TraceID(id string, msg string, args ...any)
TraceID emits one JSON-formatted log entry if tracing is enabled for the requested ID
func Warn(msg string, args ...any)
Warn emits a warning log
Format determines the format of each log entry
type Format string
const (
// LevelTrace can be set to enable tracing
LevelTrace slog.Level = -10
// Text format
Text Format = "text"
// JSON format
JSON Format = "json"
)
LogLevel is the level of logging
type LogLevel int
func (*LogLevel) Set
func (ll *LogLevel) Set(ls string) (err error)
Set is a convenience method for pflag.Value
func (*LogLevel) String
func (ll *LogLevel) String() (s string)
String is a convenience method for pflag.Value
func (*LogLevel) Type
func (ll *LogLevel) Type() string
Type is a conveniene method for pflag.Value
func (ll *LogLevel) UnmarshalJSON(jason []byte) (err error)
UnmarshalJSON is a convenience method for Kong
LogLevelFlag is useful for using a LogLevel as a command-line flag in CLI applications
type LogLevelFlag = cli.FlagBase[LogLevel, cli.NoConfig, logLevelValue]
Traces is the list of trace IDs enabled
type Traces []string
func (*Traces) Set
func (t *Traces) Set(ts string) (err error)
Set is a convenience method for pflag.Value
func (*Traces) String
func (t *Traces) String() (s string)
String is a convenience method for pflag.Value
func (*Traces) Type
func (t *Traces) Type() string
Type is a conveniene method for pflag.Value
3. observable
import "github.com/bruceesmith/echidna/observable"
Package observable is a simple generic implementation of the Observer design pattern.
Observables are identified by a string name which must be unique across an application. Calling the observable/Observe function both registers an observable by name and type, but also registers an observer by providing a notification function that is invoked when the value of the observable changes. Multiple observers can call observable/Observe to register for notifications concerning an existing observable; in this case, notification functions are called in the order in which they were registered.
To change the value of an observable, and to notify all observers by invoking their callback notification function, call the observable/Set function.
Index
func Observe[T any](name string, cb func(T)) error
Observe either registers a new observable, or adds another observer (notification function) to an existing observable
func Set[T any](name string, value T) error
Set notifies all observers that the value of an observable has changed by calling all registered notification functions
4. program
import "github.com/bruceesmith/echidna/program"
Package program builds upon the Github packages knadh/koanf and urfave/cli/v3 to make it extremely simple to use the features of those two excellent packages in concert.
Every program using program will expose a standard set of command-line flags (--json, --log, --trace, --verbose) in addition to the standard flags provided by urfave/cli/v3 (--help and --version).
If a configuration struct is provided to the Run() function, then a further command=line flag (--config) is added to provide the source(s) of values for fields in the struct.
Index
func Run(ctx context.Context, command *cli.Command, options ...Option)
Run is the primary external function of this library. It augments the cli.Command with default command-line flags, hooks in handling for processing a configuration, runs the appropriate Action, calls the terminator to wait for goroutine cleanup
Configuration is the interface for a configuration struct
type Configuration interface {
Validate() error
}
Option is a functional parameter for Run()
type Option func(params ...any) error
func NoJSON() Option
func NoLog() Option
func NoTrace() Option
func NoVerbose() Option
func WithConfiguration(config Configuration) Option
WithConfiguration is an Option helper to define a configuration structure that will be populated from the sources given on a --config command-line flag
5. set
import "github.com/bruceesmith/echidna/set"
Package set is based on public code from John Arundel, goroutine safety added. It defines goroutine-safe methods for manipulating a generic set data structure via the standard operations Add, Contains, Intersection, Members, String and Union
URL: https://bitfieldconsulting.com/posts/generic-set
Index
Set is a generics implementation of the set data type
type Set[E comparable] struct {
// contains filtered or unexported fields
}
func New[E comparable](vals ...E) *Set[E]
New creates a new Set
func (*Set[E]) Add
func (s *Set[E]) Add(vals ...E)
Add puts a new value into a Set
func (*Set[E]) Clear
func (s *Set[E]) Clear()
Clear removes all values from a Set
func (s *Set[E]) Contains(v E) bool
Contains checks if a value is in the Set
func (*Set[E]) Delete
func (s *Set[E]) Delete(vals ...E)
Delete remove values(s) from a Set
func (s *Set[E]) Difference(s2 *Set[E]) *Set[E]
Difference returns the set of values that are in s (set A) but not in s2 (set B) ... i.e. A - B
func (s *Set[E]) Disjoint(s2 *Set[E]) bool
Disjoint returns true if the intersection of s with another set s2 is empty
func (*Set[E]) Empty
func (s *Set[E]) Empty() bool
Empty returns true if the Set is empty
func (s *Set[E]) Intersection(s2 *Set[E]) *Set[E]
Intersection returns the logical intersection of 2 Sets
func (*Set[E]) Members
func (s *Set[E]) Members() []E
Members returns a slice of the values in a Set
func (*Set[E]) Size
func (s *Set[E]) Size() int
Size returns the number of values in a Set
func (*Set[E]) String
func (s *Set[E]) String() string
String returns a string representation of the Set members
func (*Set[E]) Union
func (s *Set[E]) Union(s2 *Set[E]) *Set[E]
Union returns the logical union of 2 Sets
6. stack
import "github.com/bruceesmith/echidna/stack"
Package stack defines goroutine-safe methods for manipulating a generic stack data structure via the standard operations IsEmpty, Peek, Pop, Pushand Size.
Index
Stack is a Go stack implementation using a linked list It is go-routine safe
type Stack[T any] struct {
// contains filtered or unexported fields
}
func (*Stack[T]) IsEmpty
func (s *Stack[T]) IsEmpty() bool
IsEmpty returns true if the stack has no elements
func (*Stack[T]) Peek
func (s *Stack[T]) Peek() (value T, ok bool)
Peek returns a copy of the top element off the stack
func (*Stack[T]) Pop
func (s *Stack[T]) Pop() (value T, ok bool)
Pop removes the top element and returns it
func (*Stack[T]) Push
func (s *Stack[T]) Push(v T)
Push adds an element to the top of the stack
func (*Stack[T]) Size
func (s *Stack[T]) Size() int
Size returns the number of elements on the stack
7. terminator
import "github.com/bruceesmith/echidna/terminator"
Package terminator permits orderly stopping / shutdown of a group of goroutines via methods which mimic stop of a sync.WaitGroup.There is a default Terminator accessible through top level functions (Add, Done, Wait and so on) that call the corresponding Terminator methods
Index
func Add(delta int)
Add adds delta to the count of goroutines in the group
func Done()
Done decrements the count of goroutines in the group by one
func SetDefault(t *Terminator)
SetDefault sets the default Terminator
func ShutDown() <-chan struct{}
ShutDown allows code to wait for a shut down signal
func ShuttingDown() bool
ShuttingDown returns true if shutdown is in progress
func Stop()
Stop signals that all goroutines in the group should safely exit
func Wait()
Wait blocks until every goroutines in the group has called Done()
Terminator manages groups of goroutines
type Terminator struct {
// contains filtered or unexported fields
}
func Default() *Terminator
Default returns the default Terminator.
func New() *Terminator
New returns a Terminator
func (*Terminator) Add
func (t *Terminator) Add(delta int)
Add adds delta to the count of goroutines in the group
func (*Terminator) Done
func (t *Terminator) Done()
Done decrements the count of goroutines in the group by one
func (*Terminator) ShutDown
func (t *Terminator) ShutDown() <-chan struct{}
ShutDown allows code to wait for a shut down signal
func (t *Terminator) ShuttingDown() bool
ShuttingDown returns true if shutdown is in Default().progress
func (*Terminator) Stop
func (t *Terminator) Stop()
Stop signals that all goroutines in the group should safely exit
func (*Terminator) Wait
func (t *Terminator) Wait()
Wait blocks until every goroutines in the group has called Done()
Generated by gomarkdoc