logdog

package
v0.0.0-...-e560ebb Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2021 License: BSD-3-Clause Imports: 6 Imported by: 0

Documentation

Overview

Package logdog provide an interface for writing LogDog logs.

Since LogDog output is a single stream, this package is not goroutine safe.

Also, because it is a single stream, printing from any Logger or Step that is not the most recently created, or creating a second step at the same nesting level without closing the previous one is undefined behavior.

As a rule of thumb, do not call any methods on a Logger or Step after calling the Step method, until the returned Step is Closed. This is not enforced because it would require adding errors everywhere and complicating the API, or adding panics which is undesirable (logging errors are not severe enough to be fatal).

Example
lg := NewLogger(os.Stdout)
// Configure the Logger for deterministic output.
lg2 := lg.(*realLogger).logger
lg2.SetFlags(0)
lg2.SetPrefix("example: ")
lg.Print("Example logs")
func() {
	s := lg.Step("step1")
	defer s.Close()
	s.Print("Some logs")
}()
func() {
	s := lg.Step("failure")
	defer s.Close()
	s.Print("Oops, we failed")
	s.Failure()
}()
func() {
	s := lg.Step("error")
	defer s.Close()
	s.Print("Some error happened")
	s.Exception()
}()
Output:

example: Example logs
@@@SEED_STEP step1@@@
@@@STEP_CURSOR step1@@@
@@@STEP_STARTED@@@
example: Some logs
@@@STEP_CLOSED@@@
@@@SEED_STEP failure@@@
@@@STEP_CURSOR failure@@@
@@@STEP_STARTED@@@
example: Oops, we failed
@@@STEP_FAILURE@@@
@@@STEP_CLOSED@@@
@@@SEED_STEP error@@@
@@@STEP_CURSOR error@@@
@@@STEP_STARTED@@@
example: Some error happened
@@@STEP_EXCEPTION@@@
@@@STEP_CLOSED@@@
Example (Labeled_log)
lg := NewLogger(os.Stdout)
lg.LabeledLog("ijn", "ayanami")
lg.LabeledLog("ijn", "jintsuu")
Output:

@@@STEP_LOG_LINE@ijn@ayanami@@@
@@@STEP_LOG_LINE@ijn@jintsuu@@@
Example (Substeps)
lg := NewLogger(os.Stdout)
func() {
	s := lg.Step("step1")
	defer s.Close()
	func() {
		s2 := s.Step("substep1")
		defer s2.Close()
	}()
}()
func() {
	s := lg.Step("step2")
	defer s.Close()
	func() {
		s2 := s.Step("substep2")
		defer s2.Close()
		func() {
			s3 := s2.Step("substep3")
			defer s3.Close()
		}()
	}()
}()
Output:

@@@SEED_STEP step1@@@
@@@STEP_CURSOR step1@@@
@@@STEP_STARTED@@@
@@@SEED_STEP substep1@@@
@@@STEP_CURSOR substep1@@@
@@@STEP_NEST_LEVEL@1@@@
@@@STEP_STARTED@@@
@@@STEP_CLOSED@@@
@@@STEP_CURSOR step1@@@
@@@STEP_CLOSED@@@
@@@SEED_STEP step2@@@
@@@STEP_CURSOR step2@@@
@@@STEP_STARTED@@@
@@@SEED_STEP substep2@@@
@@@STEP_CURSOR substep2@@@
@@@STEP_NEST_LEVEL@1@@@
@@@STEP_STARTED@@@
@@@SEED_STEP substep3@@@
@@@STEP_CURSOR substep3@@@
@@@STEP_NEST_LEVEL@2@@@
@@@STEP_STARTED@@@
@@@STEP_CLOSED@@@
@@@STEP_CURSOR substep2@@@
@@@STEP_CLOSED@@@
@@@STEP_CURSOR step2@@@
@@@STEP_CLOSED@@@
Example (Text)
lg := NewTextLogger(os.Stdout)
ConfigForTest(lg)
lg.Print("Example logs")
func() {
	s := lg.Step("step1")
	defer s.Close()
	s.Print("Some logs")
}()
func() {
	s := lg.Step("failure")
	defer s.Close()
	s.Failure()
	s.Print("Oops, we failed")
}()
func() {
	s := lg.Step("error")
	defer s.Close()
	s.Exception()
	s.Print("Some error happened")
}()
Output:

example: Example logs
example: STEP step1
example: Some logs
example: STEP step1 OK
example: STEP failure
example: Oops, we failed
example: STEP failure FAIL
example: STEP error
example: Some error happened
example: STEP error ERROR
Example (Text_labeled_log)
lg := NewTextLogger(os.Stdout)
ConfigForTest(lg)
lg.LabeledLog("ijn", "ayanami")
lg.LabeledLog("ijn", "jintsuu")
Output:

example: LOG ijn ayanami
example: LOG ijn jintsuu
Example (Text_substeps)
lg := NewTextLogger(os.Stdout)
ConfigForTest(lg)
func() {
	s := lg.Step("step1")
	defer s.Close()
	func() {
		s2 := s.Step("substep1")
		defer s2.Close()
	}()
}()
func() {
	s := lg.Step("step2")
	defer s.Close()
	func() {
		s2 := s.Step("substep2")
		defer s2.Close()
		func() {
			s3 := s2.Step("substep3")
			defer s3.Close()
		}()
	}()
}()
Output:

example: STEP step1
example: STEP step1::substep1
example: STEP step1::substep1 OK
example: STEP step1 OK
example: STEP step2
example: STEP step2::substep2
example: STEP step2::substep2::substep3
example: STEP step2::substep2::substep3 OK
example: STEP step2::substep2 OK
example: STEP step2 OK

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ConfigForTest

func ConfigForTest(lg Logger)

ConfigForTest configures the text logger for deterministic output for tests.

Types

type Logger

type Logger interface {
	// RawWriter returns the raw backing Writer.  This can be used
	// for dumping copious log data from sources like a
	// subprocess.
	RawWriter() io.Writer
	// Basic log printing methods.
	Print(v ...interface{})
	Printf(format string, v ...interface{})
	Println(v ...interface{})
	// LogDog specific methods.
	Step(string) Step
	LabeledLog(string, string)
}

Logger defines the methods for writing LogDog logs. The implementation may format the output differently if the output stream is not being processed for LogDog (e.g., if the output is just a text stream).

The provided interface is consistent with top level LogDog output not associated with a step. Since it is not associated with a step, you cannot attach step links or indicate step failure.

func NewLogger

func NewLogger(w io.Writer) Logger

NewLogger returns a Logger that writes to the given writer, which should process LogDog annotations.

func NewTextLogger

func NewTextLogger(w io.Writer) Logger

NewTextLogger returns a text Logger that writes to the given writer. The output will be formatted for plain text and will not contain LogDog annotations.

type Step

type Step interface {
	Logger
	// Close writes out the end of the LogDog step.  Calling any
	// method on a step after it is closed is undefined, including
	// calling Close again.  This method always returns nil (but
	// implements io.Closer).
	Close() error
	Failure()
	Exception()
	AddLink(label, url string)
}

Step defines the methods for writing LogDog logs while a step is active. This provides a superset of the methods available globally via Logger.

Step also implements Logger, which means you could pass a Step to a hypothetical function that takes a root Logger, and the function which would normally log steps under the root would instead log substeps under the given Step. However, you would generally not assign a Step to a Logger variable.

Jump to

Keyboard shortcuts

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