This section is empty.


This section is empty.


This section is empty.


type Client

type Client struct {

	// contains filtered or unexported fields


Client is a client to a local LogDog Butler.

The methods here allow you to open a stream (text, binary or datagram) which you can then use to send data to LogDog.

func New

func New(path string, namespace types.StreamName) (*Client, error)

New instantiates a new Client instance. This type of instance will be parsed from the supplied path string, which takes the form:


Supported protocols

Below is the list of all supported protocols:

unix:/path/to/socket (POSIX only)

Connects to a UNIX domain socket at "/path/to/socket". This is the preferred protocol for Linux/Mac.

net.pipe:name (Windows only)

Connects to a local Windows named pipe "\\.\pipe\name". This is the preferred protocol for Windows.

null (All platforms)

Sinks all connections and writes into a null data sink. Useful for tests, or for running programs which use logdog but you don't care about their logdog outputs.

func NewLoopback

func NewLoopback(b butler, namespace types.StreamName) *Client

NewLoopback makes a loopback Client attached to a Butler instance.

The `butler` interface should be, exactly:


The interface is merely used for import cycle management.

NOTE: `ForProcess` will be a no-op for the created Client. If you intend to generate streams from this Client to attach to subprocesses, you would be better served by using New to create a real client.

func (*Client) NewBinaryStream

func (c *Client) NewBinaryStream(ctx context.Context, name types.StreamName, opts ...Option) (io.WriteCloser, error)

NewBinaryStream returns a new open binary stream to the butler.

Binary streams use fixed size chunks to delimit log sections.

func (*Client) NewDatagramStream

func (c *Client) NewDatagramStream(ctx context.Context, name types.StreamName, opts ...Option) (DatagramStream, error)

NewDatagramStream returns a new datagram stream to the butler.

Datagram streams allow you to send messages without having to demark the separation between messages.

NOTE: It is an error to pass ForProcess as an Option (see documentation on ForProcess for more detail).

func (*Client) NewTextStream

func (c *Client) NewTextStream(ctx context.Context, name types.StreamName, opts ...Option) (io.WriteCloser, error)

NewTextStream returns a new open text-based stream to the butler.

Text streams look for newlines to delimit log sections.

type DatagramStream

type DatagramStream interface {

	// WriteDatagram writes `dg` as a single datagram.
	WriteDatagram(dg []byte) error

DatagramStream is the interface for datagram oriented streams.

type FakeClient

type FakeClient struct {

FakeClient implements a client which doesn't connect to a real server, but allows the retrieval of the dialed data later via GetFakeData.

func NewFake

func NewFake(namespace types.StreamName) FakeClient

NewFake makes a FakeClient which absorbs all data written to the client, and allows retrieval via extra methods.

func (FakeClient) GetFakeData

func (c FakeClient) GetFakeData() map[types.StreamName]FakeStreamData

GetFakeData returns all absorbed data collected by this client so far.

Note that the FakeStreamData objects are `live`, and so calling their methods will always get you the current value of those streams. You'll need to call this method again if you expect a new stream to show up, however.

func (FakeClient) SetFakeError

func (c FakeClient) SetFakeError(err error)

SetFakeError causes New* methods on this Client to return this error.

type FakeStreamData

type FakeStreamData interface {
	// GetFlags returns the stream's streamproto.Flags from when the stream was
	// opened.
	GetFlags() streamproto.Flags

	// GetStreamData returns the written text/binary data as a string.
	// If this is a datagram stream, returns "".
	GetStreamData() string

	// GetDatagrams returns the written datagrams as a list of strings.
	// If this is a text/binary stream, returns nil.
	GetDatagrams() []string

	// Returns true iff the user of the client has closed this stream.
	IsClosed() bool

FakeStreamData is data about a single stream for a client created with the "fake" protocol. You can retrieve this with Client.GetFakeData().

type Option

type Option func(*options)

Option functions are returned by the With* functions in this package and can be passed to the Client.New*Stream methods to alter their contents during initial stream setup.

func ForProcess

func ForProcess() Option

ForProcess opens this stream optimized for subprocess IO (i.e. to attach to "os/exec".Cmd.Std{out,err}).

Accidentally passing a non-`ForProcess` stream to a subprocess will result in an extra pipe, and an extra goroutine with a copy loop in the parent process.

ForProcess is only allowed on Text and Binary streams, not datagram streams. This is because the datagram stream is "packet" oriented, but stdout/stderr are not. If an application knows enough about the butler protocol to properly frame its output, it should just open a butler connection directly, rather than emitting framed data on its standard outputs.

Note that when using a stream as a replacement for a process stdout/stderr handle, it must be used in the following manner (error checks omitted for brevity). The important thing to notice is that stdout must be Close'd after Wait (which could be accomplised by a defer). Failure to do this will keep the Stream open from the butler's point of view, which will prevent the butler from closing down.

stdout, _ = logdogServ.Client.NewTextStream(
  ..., streamclient.ForProcess())
cmd.Stdout = stdout



Using this has some caveats, depending on the underlying stream implementation:


Clients created with NewLocal ignore this option.


Clients created with NewFake ignore this option.


The "null" protocol will return an open File pointing to os.DevNull.

Windows - NamedPipe

This stream will be opened as a synchronous *os.File, and so will be suitable for os/exec's specific optimizations for this type (namely: it will be passed as a replacement HANDLE for stdout/stderr, and no extra pipe/goroutine will be allocated).

Accidentally using a `ForProcess` stream in the current process will result in go falling back to its internal IO threadpool to emulate asynchrony. Without `ForProcess`, the stream will use Windows-native OVERLAPPED IO completion ports, which allows the go process to be much more efficient with its thread count.

Mac and Linux - Unix Domain Sockets

This stream will be dialed as a regular unix socket, but will be converted to an *os.File via `"net".UnixConn.File()`, and the original file handle ("Conn") closed.

Accidentally using a `ForProcess` stream in the current process isn't extremely harmful (because Go has a decent event-based IO system for *NIX systems).

func WithContentType

func WithContentType(contentType string) Option

WithContentType returns an Option to set the content type for a new stream.

The content type can be read by LogDog clients and may be used to indicate the type of data in this stream.

By default:

* Text streams have the type "text/plain"
* Binary streams have the type "application/octet-stream"
* Datagram streams have the type "application/x-logdog-datagram"

func WithTagMap

func WithTagMap(tags map[string]string) Option

WithTagMap allows you to add arbitrary tags to this stream (subject to the limits in `logdog/common/types.ValidateTag`).

By default, streams have no additional tags.

func WithTags

func WithTags(keyValues ...string) Option

WithTags allows you to add arbitrary tags to this stream (subject to the limits in `logdog/common/types.ValidateTag`). This is a convenience version of WithTagMap.

You must supply tags in pairs of {key, value}. Otherwise this function panics.

By default, streams have no additional tags.

func WithTimestamp

func WithTimestamp(stamp time.Time) Option

WithTimestamp allows you to set the 'starting' timestamp for this stream.

Panics if given a timestamp that ptypes.TimestampProto cannot handle (no real timestamps will ever fall into this range).

By default the stream will be marked as starting at `clock.Now(ctx)`.