log

package
v0.0.0-...-660a5ed Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 23, 2022 License: MIT Imports: 15 Imported by: 5

Documentation

Overview

Package log will contain logic to implement loggers, which write messages to writers with modular configuration. Loggers are defined by the Logger interface, to provide both abstraction and extensibility of loggers.

This package covers the native features of the Logger interface, and its objects' configuration and API. Web solutions like the gRPC client and server are found in their designated packages.

The log package implements the following interfaces:

type Logger interface {
    io.Writer
    Printer

    SetOuts(outs ...io.Writer) Logger
    AddOuts(outs ...io.Writer) Logger
    Prefix(prefix string) Logger
    Sub(sub string) Logger
    Fields(fields map[string]interface{}) Logger
    IsSkipExit() bool
}

type Printer interface {
    Output(m *event.Event) (n int, err error)
    Log(m ...*event.Event)

    Print(v ...interface{})
    Println(v ...interface{})
    Printf(format string, v ...interface{})

    Panic(v ...interface{})
    Panicln(v ...interface{})
    Panicf(format string, v ...interface{})

    Fatal(v ...interface{})
    Fatalln(v ...interface{})
    Fatalf(format string, v ...interface{})

    Error(v ...interface{})
    Errorln(v ...interface{})
    Errorf(format string, v ...interface{})

    Warn(v ...interface{})
    Warnln(v ...interface{})
    Warnf(format string, v ...interface{})

    Info(v ...interface{})
    Infoln(v ...interface{})
    Infof(format string, v ...interface{})

    Debug(v ...interface{})
    Debugln(v ...interface{})
    Debugf(format string, v ...interface{})

    Trace(v ...interface{})
    Traceln(v ...interface{})
    Tracef(format string, v ...interface{})
}

type ChanneledLogger interface {
    Log(msg ...*event.Event)
    Close()
    Channels() (logCh chan *event.Event, done chan struct{})
}

The remaining interfaces found in this package (LoggerConfig interface, LogFormatter interface) are merely for configuring the logger, so these will be mostly useful for extensibility / new features

type LoggerConfig interface {
    Apply(lb *LoggerBuilder)
}

type LogFormatter interface {
    Format(log *LogMessage) (buf []byte, err error)
    LoggerConfig
}

Index

Constants

This section is empty.

Variables

LogFormatConfigs is a map of LoggerConfigs indexed by an int value. This is done in a map and not a list for manual ordering, spacing and manipulation of preset entries

View Source
var LogFormatters = map[int]LogFormatter{
	0:  text.New().Build(),
	1:  &protobuf.FmtPB{},
	2:  &json.FmtJSON{},
	3:  &csv.FmtCSV{},
	4:  &xml.FmtXML{},
	5:  &gob.FmtGob{},
	6:  &bson.FmtBSON{},
	7:  text.New().Time(text.LTRFC3339).Build(),
	8:  text.New().Time(text.LTRFC822Z).Build(),
	9:  text.New().Time(text.LTRubyDate).Build(),
	10: text.New().DoubleSpace().Build(),
	11: text.New().DoubleSpace().LevelFirst().Build(),
	12: text.New().LevelFirst().Build(),
	13: text.New().DoubleSpace().Color().Build(),
	14: text.New().DoubleSpace().LevelFirst().Color().Build(),
	15: text.New().LevelFirst().Color().Build(),
	16: text.New().Color().Build(),
	17: text.New().NoHeaders().NoTimestamp().NoLevel().Build(),
	18: text.New().NoHeaders().Build(),
	19: text.New().NoTimestamp().Build(),
	20: text.New().NoTimestamp().Color().Build(),
	21: text.New().NoTimestamp().Color().Upper().Build(),
	22: &json.FmtJSON{SkipNewline: true},
	23: &json.FmtJSON{SkipNewline: true, Indent: true},
	24: &json.FmtJSON{Indent: true},
}

LogFormatters is a map of LogFormatters indexed by an int value. This is done in a map and not a list for manual ordering, spacing and manipulation of preset entries

Functions

func Debug

func Debug(v ...interface{})

Debug function (similar to fmt.Print) will print a message using an fmt.Sprint(v...) pattern, while automatically applying LogLevel Debug.

func Debugf

func Debugf(format string, v ...interface{})

Debugf function (similar to fmt.Print) will print a message using an fmt.Sprintf(format, v...) pattern, while automatically applying LogLevel Debug.

func Debugln

func Debugln(v ...interface{})

Debugln function (similar to fmt.Print) will print a message using an fmt.Sprintln(v...) pattern, while automatically applying LogLevel Debug.

func Error

func Error(v ...interface{})

Error function (similar to fmt.Print) will print a message using an fmt.Sprint(v...) pattern, while automatically applying LogLevel Error.

func Errorf

func Errorf(format string, v ...interface{})

Errorf function (similar to fmt.Print) will print a message using an fmt.Sprintf(format, v...) pattern, while automatically applying LogLevel Error.

func Errorln

func Errorln(v ...interface{})

Errorln function (similar to fmt.Print) will print a message using an fmt.Sprintln(v...) pattern, while automatically applying LogLevel Error.

func Fatal

func Fatal(v ...interface{})

Fatal function (similar to fmt.Print) will print a message using an fmt.Sprint(v...) pattern, while automatically applying LogLevel Fatal.

This function will end calling `os.Exit(1)`, if the logger is not set to skip exit calls.

func Fatalf

func Fatalf(format string, v ...interface{})

Fatalf function (similar to fmt.Print) will print a message using an fmt.Sprintf(format, v...) pattern, while automatically applying LogLevel Fatal.

This function will end calling `os.Exit(1)`, if the logger is not set to skip exit calls.

func Fatalln

func Fatalln(v ...interface{})

Fatalln function (similar to fmt.Print) will print a message using an fmt.Sprintln(v...) pattern, while automatically applying LogLevel Fatal.

This function will end calling `os.Exit(1)`, if the logger is not set to skip exit calls.

func Info

func Info(v ...interface{})

Info function (similar to fmt.Print) will print a message using an fmt.Sprint(v...) pattern, while automatically applying LogLevel Info.

func Infof

func Infof(format string, v ...interface{})

Infof function (similar to fmt.Print) will print a message using an fmt.Sprintf(format, v...) pattern, while automatically applying LogLevel Info.

func Infoln

func Infoln(v ...interface{})

Infoln function (similar to fmt.Print) will print a message using an fmt.Sprintln(v...) pattern, while automatically applying LogLevel Info.

func Log

func Log(m ...*event.Event)

Log function will take in a pointer to a event.Event, and write it to the Logger's io.Writer without returning an error message.

While the resulting error message of running `Logger.Output()` is simply ignored, this is done as a blind-write for this Logger.

func Panic

func Panic(v ...interface{})

Panic function (similar to fmt.Print) will print a message using an fmt.Sprint(v...) pattern, while automatically applying LogLevel Panic.

This function will end calling `panic()` with the event.Event's message content, if the logger is not set to skip exit calls.

func Panicf

func Panicf(format string, v ...interface{})

Panicf function (similar to fmt.Print) will print a message using an fmt.Sprintf(format, v...) pattern, while automatically applying LogLevel Panic.

This function will end calling `panic()` with the event.Event's message content, if the logger is not set to skip exit calls.

func Panicln

func Panicln(v ...interface{})

Panicln function (similar to fmt.Print) will print a message using an fmt.Sprintln(v...) pattern, while automatically applying LogLevel Panic.

This function will end calling `panic()` with the event.Event's message content, if the logger is not set to skip exit calls.

func Print

func Print(v ...interface{})

Print function (similar to fmt.Print) will print a message using an fmt.Sprint(v...) pattern

It applies LogLevel Info

func Printf

func Printf(format string, v ...interface{})

Printf function (similar to fmt.Printf) will print a message using an fmt.Sprintf(format, v...) pattern

It applies LogLevel Info

func Println

func Println(v ...interface{})

Println function (similar to fmt.Println) will print a message using an fmt.Sprintln(v...) pattern

It applies LogLevel Info

func Trace

func Trace(v ...interface{})

Trace function (similar to fmt.Print) will print a message using an fmt.Sprint(v...) pattern, while automatically applying LogLevel Trace.

func Tracef

func Tracef(format string, v ...interface{})

Tracef function (similar to fmt.Print) will print a message using an fmt.Sprintf(format, v...) pattern, while automatically applying LogLevel Trace.

func Traceln

func Traceln(v ...interface{})

Traceln function (similar to fmt.Print) will print a message using an fmt.Sprintln(v...) pattern, while automatically applying LogLevel Trace.

func Warn

func Warn(v ...interface{})

Warn function (similar to fmt.Print) will print a message using an fmt.Sprint(v...) pattern, while automatically applying LogLevel Warn.

func Warnf

func Warnf(format string, v ...interface{})

Warnf function (similar to fmt.Print) will print a message using an fmt.Sprintf(format, v...) pattern, while automatically applying LogLevel Warn.

func Warnln

func Warnln(v ...interface{})

Warnln function (similar to fmt.Print) will print a message using an fmt.Sprintln(v...) pattern, while automatically applying LogLevel Warn.

Types

type LCDatabase

type LCDatabase struct {
	Out io.WriteCloser
	Fmt LogFormatter
}

LCDatabase struct defines the Logger Config object that adds a DBWriter as a Logger writer

func (*LCDatabase) Apply

func (c *LCDatabase) Apply(lb *LoggerBuilder)

Apply method will set the input LoggerBuilder's outputs and format to the LCDatabase object's.

type LCFilter

type LCFilter struct {
	// contains filtered or unexported fields
}

LCSkipExit stuct is a custom LoggerConfig to filter Logger writes as per the message's log level

func (LCFilter) Apply

func (c LCFilter) Apply(lb *LoggerBuilder)

Apply method will set the configured level filter to the input pointer to a LoggerBuilder

type LCOut

type LCOut struct {
	// contains filtered or unexported fields
}

LCOut struct is a custom LoggerConfig to define the output io.Writer to new Loggers

func (*LCOut) Apply

func (c *LCOut) Apply(lb *LoggerBuilder)

Apply method will set the configured output io.Writer to the input pointer to a LoggerBuilder

type LCPrefix

type LCPrefix struct {
	// contains filtered or unexported fields
}

LCPrefix struct is a custom LoggerConfig to define prefixes to new Loggers

func (*LCPrefix) Apply

func (c *LCPrefix) Apply(lb *LoggerBuilder)

Apply method will set the configured prefix string to the input pointer to a LoggerBuilder

type LCSkipExit

type LCSkipExit struct{}

LCSkipExit stuct is a custom LoggerConfig to define whether os.Exit(1) and panic() calls should be respected or skipped

func (LCSkipExit) Apply

func (c LCSkipExit) Apply(lb *LoggerBuilder)

Apply method will set the configured skipExit option to true, in the input pointer to a LoggerBuilder

Not setting this option will default to "false", or to respect os.Exit(1) and panic() calls

type LCSub

type LCSub struct {
	// contains filtered or unexported fields
}

LCSub struct is a custom LoggerConfig to define sub-prefixes to new Loggers

func (*LCSub) Apply

func (c *LCSub) Apply(lb *LoggerBuilder)

Apply method will set the configured sub-prefix string to the input pointer to a LoggerBuilder

type LogFormatter

type LogFormatter interface {
	Format(log *event.Event) (buf []byte, err error)
}

LogFormatter interface describes the behavior a Formatter should have.

The Format method is present to process the input event.Event into content to be written (and consumed)

var (
	FormatText                  LogFormatter = LogFormatters[0]  // placeholder for an initialized Text LogFormatter
	FormatProtobuf              LogFormatter = LogFormatters[1]  // placeholder for an initialized Protobuf LogFormatter
	FormatJSON                  LogFormatter = LogFormatters[2]  // placeholder for an initialized JSON LogFormatter
	FormatCSV                   LogFormatter = LogFormatters[3]  // placeholder for an initialized CSV LogFormatter
	FormatXML                   LogFormatter = LogFormatters[4]  // placeholder for an initialized XML LogFormatter
	FormatGob                   LogFormatter = LogFormatters[5]  // placeholder for an initialized Gob LogFormatter
	FormatBSON                  LogFormatter = LogFormatters[6]  // placeholder for an initialized JSON LogFormatter
	TextLongDate                LogFormatter = LogFormatters[7]  // placeholder for an initialized Text LogFormatter, with a RFC3339 date format
	TextShortDate               LogFormatter = LogFormatters[8]  // placeholder for an initialized Text LogFormatter, with a RFC822Z date format
	TextRubyDate                LogFormatter = LogFormatters[9]  // placeholder for an initialized Text LogFormatter, with a RubyDate date format
	TextDoubleSpace             LogFormatter = LogFormatters[10] // placeholder for an initialized Text LogFormatter, with double spaces
	TextLevelFirstSpaced        LogFormatter = LogFormatters[11] // placeholder for an initialized  LogFormatter, with level-first and double spaces
	TextLevelFirst              LogFormatter = LogFormatters[12] // placeholder for an initialized  LogFormatter, with level-first
	TextColorDoubleSpace        LogFormatter = LogFormatters[13] // placeholder for an initialized  LogFormatter, with color and double spaces
	TextColorLevelFirstSpaced   LogFormatter = LogFormatters[14] // placeholder for an initialized  LogFormatter, with color, level-first and double spaces
	TextColorLevelFirst         LogFormatter = LogFormatters[15] // placeholder for an initialized  LogFormatter, with color and level-first
	TextColor                   LogFormatter = LogFormatters[16] // placeholder for an initialized  LogFormatter, with color
	TextOnly                    LogFormatter = LogFormatters[17] // placeholder for an initialized  LogFormatter, with only the text content
	TextNoHeaders               LogFormatter = LogFormatters[18] // placeholder for an initialized  LogFormatter, without headers
	TextNoTimestamp             LogFormatter = LogFormatters[19] // placeholder for an initialized  LogFormatter, without timestamp
	TextColorNoTimestamp        LogFormatter = LogFormatters[20] // placeholder for an initialized  LogFormatter, without timestamp
	TextColorUpperNoTimestamp   LogFormatter = LogFormatters[21] // placeholder for an initialized  LogFormatter, without timestamp and uppercase headers
	FormatJSONSkipNewline       LogFormatter = LogFormatters[22] // placeholder for an initialized JSON LogFormatter, with a skip-newline config
	FormatJSONIndentSkipNewline LogFormatter = LogFormatters[23] // placeholder for an initialized JSON LogFormatter, with a skip-newline and indentation config
	FormatJSONIndent            LogFormatter = LogFormatters[24] // placeholder for an initialized JSON LogFormatter, with an indentation config
)

type Logger

type Logger interface {
	io.Writer
	Printer

	SetOuts(outs ...io.Writer) Logger
	AddOuts(outs ...io.Writer) Logger
	Prefix(prefix string) Logger
	Sub(sub string) Logger
	Fields(fields map[string]interface{}) Logger
	IsSkipExit() bool
}

Logger interface defines the general behavior of a Logger object

It lists all the methods that a Logger implements in order to print timestamped messages to an io.Writer, and additional configuration methods to enhance its behavior and application (such as `Prefix()` and `Fields()`; and `SetOuts()` or `AddOuts()`)

func MultiLogger

func MultiLogger(loggers ...Logger) Logger

MultiLogger function is a wrapper for multiple Logger

Similar to how io.MultiWriter() is implemented, this function generates a single Logger that targets a set of configured Logger.

As such, a single Logger can have multiple Loggers with different configurations and output files, while still registering the same log message.

func New

func New(confs ...LoggerConfig) Logger

New function allows creating a basic Logger (implementing the Logger interface).

Its input parameters are a list of objects which implement the LoggerConfig interface. These parameters are iterated through via a `multiConf` object that applies all configurations to the builder.

Defaults are automatically applied to all elements which aren't defined in the input configuration.

type LoggerBuilder

type LoggerBuilder struct {
	Out         io.Writer
	Prefix      string
	Sub         string
	Fmt         LogFormatter
	SkipExit    bool
	LevelFilter int32
}

LoggerBuilder struct describes a builder object for Loggers

The LoggerBuilder object will always be the target for configuration settings that are applied when building a Logger, and only after all elements are set (with defaults or otherwise) it is converted / copied into a Logger

type LoggerConfig

type LoggerConfig interface {
	Apply(lb *LoggerBuilder)
}

LoggerConfig interface describes the behavior that a LoggerConfig object should have

The single Apply(lb *LoggerBuilder) method allows for different modules to apply changes to a LoggerBuilder, in a non-blocking way for other features.

Each feature should implement its own structs with their own methods; where they can implement Apply(lb *LoggerBuilder) to set their own configurations to the input LoggerBuilder

var (
	// default configuration for a Logger
	DefaultConfig LoggerConfig = &multiconf{
		confs: []LoggerConfig{
			WithFormat(TextColorLevelFirst),
			WithOut(),
			WithPrefix(event.Default_Event_Prefix),
		},
	}

	// LoggerConfigs is a map of LoggerConfig indexed by an int value. This is done in a map
	// and not a list for manual ordering, spacing and manipulation of preset entries
	LoggerConfigs = map[int]LoggerConfig{
		0:  DefaultConfig,
		1:  LCSkipExit{},
		7:  WithOut(os.Stderr),
		8:  WithPrefix(event.Default_Event_Prefix),
		9:  WithFilter(event.Level_info),
		10: WithFilter(event.Level_warn),
		11: WithFilter(event.Level_error),
		12: NilLogger(),
	}

	DefaultCfg    LoggerConfig = LoggerConfigs[0]  // placeholder for an initialized default LoggerConfig
	SkipExit      LoggerConfig = LoggerConfigs[1]  // placeholder for an initialized skip-exits LoggerConfig
	StdOut        LoggerConfig = LoggerConfigs[7]  // placeholder for an initialized os.Stderr LoggerConfig
	PrefixDefault LoggerConfig = LoggerConfigs[8]  // placeholder for an initialized default-prefix LoggerConfig
	FilterInfo    LoggerConfig = LoggerConfigs[9]  // placeholder for an initialized Info-filtered LoggerConfig
	FilterWarn    LoggerConfig = LoggerConfigs[10] // placeholder for an initialized Warn-filtered LoggerConfig
	FilterError   LoggerConfig = LoggerConfigs[11] // placeholder for an initialized Error-filtered LoggerConfig
	NilConfig     LoggerConfig = LoggerConfigs[12] // placeholder for an initialized empty / nil LoggerConfig
	EmptyConfig   LoggerConfig = LoggerConfigs[12] // placeholder for an initialized empty / nil LoggerConfig
)
var (
	CfgFormatText                  LoggerConfig = LogFormatConfigs[0]  // placeholder for an initialized Text LoggerConfig
	CfgFormatProtobuf              LoggerConfig = LogFormatConfigs[1]  // placeholder for an initialized Protobuf LoggerConfig
	CfgFormatJSON                  LoggerConfig = LogFormatConfigs[2]  // placeholder for an initialized JSON LoggerConfig
	CfgFormatCSV                   LoggerConfig = LogFormatConfigs[3]  // placeholder for an initialized CSV LoggerConfig
	CfgFormatXML                   LoggerConfig = LogFormatConfigs[4]  // placeholder for an initialized XML LoggerConfig
	CfgFormatGob                   LoggerConfig = LogFormatConfigs[5]  // placeholder for an initialized Gob LoggerConfig
	CfgFormatBSON                  LoggerConfig = LogFormatConfigs[6]  // placeholder for an initialized JSON LoggerConfig
	CfgTextLongDate                LoggerConfig = LogFormatConfigs[7]  // placeholder for an initialized Text LoggerConfig, with a RFC3339 date format
	CfgTextShortDate               LoggerConfig = LogFormatConfigs[8]  // placeholder for an initialized Text LoggerConfig, with a RFC822Z date format
	CfgTextRubyDate                LoggerConfig = LogFormatConfigs[9]  // placeholder for an initialized Text LoggerConfig, with a RubyDate date format
	CfgTextDoubleSpace             LoggerConfig = LogFormatConfigs[10] // placeholder for an initialized Text LoggerConfig, with double spaces
	CfgTextLevelFirstSpaced        LoggerConfig = LogFormatConfigs[11] // placeholder for an initialized  LoggerConfig, with level-first and double spaces
	CfgTextLevelFirst              LoggerConfig = LogFormatConfigs[12] // placeholder for an initialized  LoggerConfig, with level-first
	CfgTextColorDoubleSpace        LoggerConfig = LogFormatConfigs[13] // placeholder for an initialized  LoggerConfig, with color and double spaces
	CfgTextColorLevelFirstSpaced   LoggerConfig = LogFormatConfigs[14] // placeholder for an initialized  LoggerConfig, with color, level-first and double spaces
	CfgTextColorLevelFirst         LoggerConfig = LogFormatConfigs[15] // placeholder for an initialized  LoggerConfig, with color and level-first
	CfgTextColor                   LoggerConfig = LogFormatConfigs[16] // placeholder for an initialized  LoggerConfig, with color
	CfgTextOnly                    LoggerConfig = LogFormatConfigs[17] // placeholder for an initialized  LoggerConfig, with only the text content
	CfgTextNoHeaders               LoggerConfig = LogFormatConfigs[18] // placeholder for an initialized  LoggerConfig, without headers
	CfgTextNoTimestamp             LoggerConfig = LogFormatConfigs[19] // placeholder for an initialized  LoggerConfig, without timestamp
	CfgTextColorNoTimestamp        LoggerConfig = LogFormatConfigs[20] // placeholder for an initialized  LoggerConfig, without timestamp
	CfgTextColorUpperNoTimestamp   LoggerConfig = LogFormatConfigs[21] // placeholder for an initialized  LoggerConfig, without timestamp and uppercase headers
	CfgFormatJSONSkipNewline       LoggerConfig = LogFormatConfigs[22] // placeholder for an initialized JSON LoggerConfig, with a skip-newline config
	CfgFormatJSONIndentSkipNewline LoggerConfig = LogFormatConfigs[23] // placeholder for an initialized JSON LoggerConfig, with a skip-newline and indentation config
	CfgFormatJSONIndent            LoggerConfig = LogFormatConfigs[24] // placeholder for an initialized JSON LoggerConfig, with an indentation config

)

func MultiConf

func MultiConf(conf ...LoggerConfig) LoggerConfig

MultiConf function is a wrapper for multiple configs to be bundled (and executed) in one shot.

Similar to io.MultiWriter, it will iterate through all set LoggerConfig and run the same method on each of them.

func NilLogger

func NilLogger() LoggerConfig

NilLogger function will create a minimal LoggerConfig with an empty writer, and that does not comply with exit (os.Exit(1) and panic()) signals

func WithDatabase

func WithDatabase(dbs ...io.WriteCloser) LoggerConfig

WithDatabase function creates a Logger config to use a database as a writer, while protobuf encoding events, to transmit to writers

func WithFilter

func WithFilter(level event.Level) LoggerConfig

WithFilter function will allow filtering Logger writes, only to contain a certain log level and above.

This method can be used to either separate different logging severities or to reduce the amount of bytes written to a logfile, by skipping more trivial messages

func WithFormat

func WithFormat(f LogFormatter) LoggerConfig

WithFormat is a wrapper to use LogFormatters as LoggerConfigs.

func WithOut

func WithOut(out ...io.Writer) LoggerConfig

WithOut function will allow creating a LoggerConfig that applies a (number of) io.Writer to a Logger

func WithPrefix

func WithPrefix(prefix string) LoggerConfig

WithPrefix function will allow creating a LoggerConfig that applies a prefix string to a Logger

func WithSub

func WithSub(sub string) LoggerConfig

WithSub function will allow creating a LoggerConfig that applies a sub-prefix string to a Logger

type Printer

type Printer interface {
	Output(m *event.Event) (n int, err error)
	Log(m ...*event.Event)

	Print(v ...interface{})
	Println(v ...interface{})
	Printf(format string, v ...interface{})

	Panic(v ...interface{})
	Panicln(v ...interface{})
	Panicf(format string, v ...interface{})

	Fatal(v ...interface{})
	Fatalln(v ...interface{})
	Fatalf(format string, v ...interface{})

	Error(v ...interface{})
	Errorln(v ...interface{})
	Errorf(format string, v ...interface{})

	Warn(v ...interface{})
	Warnln(v ...interface{})
	Warnf(format string, v ...interface{})

	Info(v ...interface{})
	Infoln(v ...interface{})
	Infof(format string, v ...interface{})

	Debug(v ...interface{})
	Debugln(v ...interface{})
	Debugf(format string, v ...interface{})

	Trace(v ...interface{})
	Traceln(v ...interface{})
	Tracef(format string, v ...interface{})
}

Printer interface defines what a (log) printer should be able to do

Besides the "raw" (Output(), Log()) methods, this interface extends the logger's API to have plenty of quick-access methods to print messages on different log levels, without relying on the event.EventBuilder

Similar to the standard library fmt package, its methods will follow the same logic and design as an fmt.Print(), fmt.Println(), and fmt.Printf() call

Directories

Path Synopsis
format
csv
gob
xml

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL