glager

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: May 11, 2023 License: Apache-2.0 Imports: 8 Imported by: 0

README

Build Status Coverage Status

glager

Package glager provides a set of Gomega matchers to verify certain events have been logged using the Lager format.

Installation

go get github.com/st3v/glager

Matchers

There are two matchers, glager.HaveLogged and glager.ContainSequence. While their behavior is identical, one might provide better test readability than the other depending on the test scenario. For example, HaveLogged works best when use with the included glager.TestLogger.

logger := glager.NewLogger("test")

...

Expect(logger).To(HaveLogged(...))

ContainSequence on the other hand reads nice when used with gbytes.Buffer or io.Reader.

log := gbytes.NewBuffer()
logger := lager.NewLogger("test")
logger.RegisterSink(lager.NewWriterSink(log, lager.DEBUG))

...

Expect(log).To(ContainSequence(...))

Both matchers verify that a certain sequence of log entries have been written using the lager logging format. Depending on the expected log level a log entry passed to the matcher can be specified using one the following methods.

// Info specifies a log entry with level lager.INFO.
glager.Info(...)

// Debug specifies a log entry with level lager.DEBUG.
glager.Debug(...)

// Error specifies a log entry with level lager.ERROR.
glager.Error(...)

// Fatal specifies a log entry with level lager.FATAL.
glager.Fatal(...)

All of the above methods take a set of optional arguments used to specify the expected details of a given log entry. The available properties are:

// Source specifies a string that indicates the log source. The source of a
// lager logger is usually specified at instantiation time. Source is sometimes
// also called component.
glager.Source("source")

// Message specifies a string that represent the message of a given log entry.
glager.Message("message")

// Action is an alias for Message, lager uses the term action is used
// alternatively to message.
glager.Action("action")

// Data specifies the data logged by a given log entry. Arguments are specified
// as an alternating sequence of keys (string) and values (interface{}).
glager.Data("key1", "value1", "key2", "value2", ...)

// AnyErr can be used to match an Error or Fatal log entry, without matching the
// actual error that has been logged.
glager.AnyErr

When passing a sequence of log entries to the matcher, you only have to include the entries you are actually interested in. They don't have to be contiguous entries in the log. All that matters is their properties and their respective order.

Similarly, you don't have to specify all possible properties of a given log entry but only the ones you actually care about. For example, if all that matters to you is that there were two subsequent calls to logger.Info, you could use:

Expect(logger).To(HaveLogged(Info(), Info()))

If you care about the data that has been logged something like the following might work for you.

Expect(logger).To(HaveLogged(
  Info(Data("some-string", "string-value")),
  Info(Data("some-integer", 12345)),
))

Example Usage

See example_test.go for executable examples.

import (
  "code.cloudfoundry.com/lager"
  . "github.com/onsi/gomega"
  . "github.com/st3v/glager"
)

...

// instantiate glager.TestLogger inside your test and
logger := NewLogger("test")

// pass logger to your code and use it in there to log stuff
func(logger *lager.Logger) {
  logger.Info("myFunc", lager.Data(map[string]interface{}{
    "event": "start",
  }))

  logger.Debug("myFunc", lager.Data(map[string]interface{}{
    "some": "stuff",
    "more": "stuff",
  }))

  logger.Error("myFunc",
    errors.New("some error"),
    lager.Data(map[string]interface{}{
      "details": "stuff",
    }),
  )

  logger.Info("myFunc", lager.Data(map[string]interface{}{
    "event": "done",
  }))
}()

...

// verify logging inside your test
Expect(logger).To(HaveLogged(
  Info(
    Message("test.myFunc"),
    Data("event", "start"),
  ),
  Debug(
    Data("more", "stuff"),
  ),
  Error(AnyErr),
))

...

License

glager is licensed under the Apache License, Version 2.0. See LICENSE for details.

Documentation

Overview

Package glager provides Gomega matchers to verify lager logging.

See https://github.com/onsi/gomega and https://code.cloudfoundry.org/lager for more information.

Index

Constants

This section is empty.

Variables

View Source
var AnyErr error = nil

AnyErr can be used to check of arbitrary errors when matching Error entries.

Functions

func Action

func Action(action string) option

Action is an alias for Message, lager uses the term action is used alternatively to message.

func ContainSequence

func ContainSequence(expectedSequence ...logEntry) types.GomegaMatcher

ContainSequence checks if the specified entries appear inside the log in the right order. The entries do not have to be contiguous inide the log, all that matters is their respective order.

Log entries passed to this mtcher do not have to be complete, i.e. you do not have to specify all available properties but only the ones you are actually interested in. Unspecified properties are being ignored when matching the entries, i.e they can have arbitrary values.

This matcher works best when used with a Buffer.

Example:

  // instantiate regular lager logger and register buffer as sink
  log := gbytes.NewBuffer()
  logger := lager.NewLogger("test")
  logger.RegisterSink(lager.NewWriterSink(log, lager.DEBUG))

  // pass it to your code and use it in there to log stuff
  myFunc(logger)

  // verify logging inside your test, using the log buffer
  // in this example we are only interested in the data of the log entries
  Expect(log).To(ContainSequence(
	   Info(
		   Data("event", "start"),
	   ),
	   Info(
		   Data("event", "done"),
	   ),
  ))

func Data

func Data(kv ...interface{}) option

Data specifies the data logged by a given log entry. Arguments are specified as an alternating sequence of keys (string) and values (interface{}).

func Debug

func Debug(options ...option) logEntry

Debug returns a log entry of type lager.DEBUG that can be used with the HaveLogged and ContainSequence matchers.

func Error

func Error(err error, options ...option) logEntry

Error returns a log entry of type lager.ERROR that can be used with the HaveLogged and ContainSequence matchers.

func Fatal

func Fatal(err error, options ...option) logEntry

Fatal returns a log entry of type lager.FATAL that can be used with the HaveLogged and ContainSequence matchers.

func HaveLogged added in v0.3.0

func HaveLogged(expectedSequence ...logEntry) types.GomegaMatcher

HaveLogged is an alias for ContainSequence. It checks if the specified entries appear inside the log in the right sequence. The entries do not have to be contiguous in the log, all that matters is the order and the properties of the entries.

Log entries passed to this mtcher do not have to be complete, i.e. you do not have to specify all available properties but only the ones you are actually interested in. Unspecified properties are being ignored when matching the entries, i.e they can have arbitrary values.

This matcher works best when used with a TestLogger.

Example:

  // instantiate glager.TestLogger inside your test and
  logger := NewLogger("test")

  // pass it to your code and use it in there to log stuff
  myFunc(logger)

  // verify logging inside your test, using the logger
  // in this example we are interested in the log level, the message, and the
  // data of the log entries
  Expect(logger).To(HaveLogged(
	   Info(
		   Message("test.myFunc"),
		   Data("event", "start"),
	   ),
	   Info(
		   Message("test.myFunc"),
		   Data("event", "done"),
	   ),
  ))

func Info

func Info(options ...option) logEntry

Info returns a log entry of type lager.INFO that can be used with the HaveLogged and ContainSequence matchers.

func LogEntry added in v0.4.0

func LogEntry(logLevel lager.LogLevel, options ...option) logEntry

LogEntry returns a log entry for the specified log level that can be used with the HaveLogged and ContainSequence matchers.

func Message

func Message(msg string) option

Message specifies a string that represent the message of a given log entry.

func Source

func Source(src string) option

Source specifies a string that indicates the log source. The source of a lager logger is usually specified at instantiation time. Source is sometimes also called component.

Types

type ContentsProvider

type ContentsProvider interface {
	// Contents returns a slice of bytes.
	Contents() []byte
}

ContentsProvider implements Contents function.

type TestLogger

type TestLogger struct {
	lager.Logger
	// contains filtered or unexported fields
}

TestLogger embedds an actual lager logger and implements gbytes.BufferProvider. This comes in handy when used with the HaveLogged matcher.

func NewLogger

func NewLogger(component string) *TestLogger

NewLogger returns a new TestLogger that can be used with the HaveLogged matcher. The returned logger uses log level lager.DEBUG.

func (*TestLogger) Buffer

func (l *TestLogger) Buffer() *gbytes.Buffer

Buffer implements gbytes.BufferProvider.Buffer.

Jump to

Keyboard shortcuts

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