README

Trace

A simple tracing framework for the Go programming language.

Copyright (C) 2013 Jochen Voss

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

The homepage of this package is at http://www.seehuhn.de/pages/trace . Please send any comments or bug reports to the program's author, Jochen Voss voss@seehuhn.de .

Overview

The trace package provides a simple tracing framework for the excellent Go programming language. Code using this framework can emit diagnostic messages using the trace.T() function. In normal operation, calls to trace.T() have no effect and are very fast. When tracing is enabled, in order to track down a problem or to explore the inner workings of a program, listeners can be attached to record and display all trace messages.

Main features:

  • Low overhead when no listeners are installed.
  • Flexible selection of messages by listeners via message origin and/or priority.

Installation

go get github.com/seehuhn/trace

Usage

Code using this framework can emit diagnostic messages using the trace.T() function. Example:

trace.T("a/b/c", trace.PrioError,
        "failed to connect to server %q, using offline mode", serverName)

The first argument in this call is a path which gives information about the origin of the message, the second argument indicates the importance of the message. Both, the path and the priority are used to decide which listeners receive the correponding message. The following arguments, a format string and additional optional arguments, are passed to fmt.Sprintf to compose the message reported to the listeners registered for the given message path.

Listeners can subscribe to messages, either for a given path or for all paths, using the Register() method. A minimum priority for messages to be delivered can be used. Example:

func MyListener(t time.Time, path string, prio Priority, msg string) {
    log.Println(msg)
}

func main() {
    listener := trace.Register(MyListener, "a/b", trace.PrioAll)
    // ... code which calls trace.T()
    listener.Unregister()
}

This code installs MyListener as a handler which receives all messages sent for the path "a/b" and its sub-paths.

Full usage instructions can be found in the package's online help, for example using the following command:

go doc github.com/seehuhn/trace

Documentation

Overview

Package trace implements a simple tracing framework which can be used to diagnose run-time problems.

Sending Messages

Code using this framework can emit diagnostic messages using the trace.T() function. Example:

trace.T("client/setup", trace.PrioError,
        "failed to connect to server %q, using offline mode", serverName)

The first argument in this call is a path which gives information about the origin of the message, the second argument indicates the importance of the message. Both, the path and the priority are used to decide which listeners receive the correponding message. The following arguments, a format string and additional optional arguments, are passed to fmt.Sprintf to compose the message reported to the listeners registered for the given message path.

Receiving Messages

Listeners can subscribe to messages, either for a given path or for all paths, using the Register() method. A minimum priority for messages to be delivered can be used. Example:

func printTrace(t time.Time, path string, prio trace.Priority, msg string) {
        fmt.Printf("%s:%s: %s\n", t.Format("15:04:05.000"), path, msg)
}

func main() {
        listener := trace.Register(printTrace, "client", trace.PrioAll)
        // ... code which calls trace.T()
        listener.Unregister()
}

This code installs printTrace as a handler which receives all messages sent for the path "client" and its sub-paths.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Callers

func Callers() []string

Callers is a helper function to get a stack trace from within a trace listener function. The result is a list of strings, each giving a Go source file name, followed by a colon and a line number within the source file. The first string corresponds to the call of trace.T(), the last string corresponds to the program's main function. If Callers() is called from outside a trace listener, a run-time panic is triggered.

func T

func T(path string, prio Priority, format string, args ...interface{})

T is used to send a trace message and to the registered listeners.

The argument 'path' indicates which component of the program the caller of T belongs to; the value consists of slash separated, hierarchical fields where the first field, by convention, should coincide with the package name. 'path' must not be the empty string and must neither start nor end with a slash.

The argument 'prio' indicates the priority of the message, higher values indicating higher importance. Messages with positive priority values (corresponding to the pre-defined priorities PrioCritical, PrioError, and PrioInfo) should be phrased in a way that they make sense to a person not familiar with the source code of the program. Messages of priority PrioDebug or higher should consist of a single line.

The argument 'format' and the following, optional arguments are passed to fmt.Sprintf to compose the message reported to the listeners registered for the given message path.

Types

type Listener

type Listener func(t time.Time, path string, prio Priority, msg string)

Listener is the type of functions which can be registered using the Register() function.

type ListenerHandle

type ListenerHandle uint

ListenerHandle is the type returned by Register(). The returned values can be used in Unregister() to remove previously installed handlers.

func Register

func Register(listener Listener, path string, prio Priority) ListenerHandle

Register adds the function 'listener' to the list of functions receiving trace messages.

The argument 'path' restricts the messages received to messages corresponding to the given path and its sub-paths (see the description of 'T' for details). The value must neither start nor end in a slash. The empty string can be used to receive trace messages from all paths.

The listener will receive all messages of priority 'prio' and higher. The value PrioAll can be used for 'prio' to receive all messages. The value PrioInfo can be used to receive all messages for the given path which do not require familiarity with the program source code.

func (ListenerHandle) Unregister

func (handle ListenerHandle) Unregister()

Unregister removes a previously installed listener. The argument 'handle' must be the value returned by the corresponding call to Register()

type Priority

type Priority int32

Priority is the type used to denote message priorities. The higher the value, the more important the message is.

const (
	// PrioCritical indicates a one-line message emitted just before
	// the program has to be aborted because of an internal error.
	// The message should contain information which may help to
	// determine the underlying problem and should be phrased in a way
	// that the text makes sense to a person not familiar with the
	// source code of the program.  A message of priority PrioCritical
	// could, for example, give the name of a missing but required
	// configuration file.
	PrioCritical Priority = 2000

	// PrioError indicates a non-fatal, one-line message which is
	// likely to be of interest to an administrator of the system
	// running the program.  The message should be phrased in a way
	// that the text makes sense to a person not familiar with the
	// source code of the program.  A message of priority PrioError
	// could, for example, indicate that the program runs with reduced
	// functionality because of a configuration error.
	PrioError Priority = 1000

	// PrioInfo indicates one-line status messages which allow to
	// track the activity of the program, and which may be of interest
	// to a person trying to understand the normal operation of the
	// program.  The message should be phrased in a way that the text
	// makes sense to a person not familiar with the source code of
	// the program.  A message of priority PrioInfo could, for
	// example, indicate that a configuration file has been read.
	PrioInfo Priority = 0

	// PrioDebug indicates a one-line message which is likely to be of
	// interest to a developer of the program.  The message text may
	// assume that the reader is familiar with the source code of the
	// program.  A message of priority PrioDebug could, for example,
	// indicate that a library returned an unexpected error code.
	PrioDebug Priority = -1000

	// PrioVerbose indicates a message which may be of interest to a
	// developer of the program.  The message text may assume that the
	// reader is familiar with the source code of the program, and the
	// text may consist of several lines.  A message of priority
	// PrioDebug could, for example, give the contents of a remote
	// server response to assist with debugging of network protocol
	// incompatibility.
	PrioVerbose Priority = -2000

	// PrioAll is used to register a listener which receives all
	// messages for a given path.
	PrioAll Priority = math.MinInt32
)