encoding

package
v0.0.0-...-dc4a015 Latest Latest
Warning

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

Go to latest
Published: Oct 25, 2017 License: BSD-3-Clause, MIT Imports: 6 Imported by: 0

Documentation

Overview

Package encoding implements a streaming Decoder and Encoder for all versions of the Go trace format. For a higher level interface see the parent trace package.

Overview

This library will Decode all previous versions of the trace codec, while only emitting Events in the latest version. Unlike the go tool it does not buffer events during decoding to make them immediately available without allocation with large performance gains. It is fast enough to easily allow decoding in the same process that is performing the tracing, enabling you to defer writes to network/disk until interesting occurrences happen.

Most of the API closely resembles events emitted from the runtime. To get a quick primer I suggest starting with the "Go Execution Tracer" design document located at: https://golang.ir/s/go15trace

In general Events have intuitive names, when they are not it may help to read the scheduler design doc at https://golang.ir/s/go11sched. It's a bit dated but remains conceptually accurate and serves as a good primer. After that https://github.com/golang/go/wiki/DesignDocuments for GC, preemption, syscalls and everything else. Recently I also came across runtime/HACKING.md in Go master which provides some good material as well.

Compatibility

The Go trace format seems to be evolving continuously as new events are added and old events refined. This is a good thing but it does make it difficult to provide backwards compatibility. The maintenance burden of representing each event as it's native versions format would be high and error prone. Not to mention difficult to consume as you special cased each version.

So instead all prior trace format versions will be properly decoded by this library into a single Event structure matching the latest version. The args decoded by this package will always match their version. For example, EvBatch from event.Version1 (Go 1.5) has an additional sequence argument that will be left untouched.

Example
package main

import (
	"fmt"
	"os"

	"github.com/cstockton/go-trace/encoding"
	"github.com/cstockton/go-trace/event"
)

func main() {
	f, err := os.Open(`../internal/tracefile/testdata/go1.8/log.trace`)
	if err != nil {
		fmt.Println(`Err:`, err)
		return
	}
	defer f.Close()

	var (
		created int
		evt     event.Event
		dec     = encoding.NewDecoder(f)
	)
	for i := 1; dec.More(); i++ {
		evt.Reset()
		if err := dec.Decode(&evt); err != nil {
			break // err will be in Err()
		}
		if evt.Type == event.EvGoCreate {
			created++ // Count all the GoCreate events.
		}
		if i%40 == 0 {
			fmt.Println(evt.Type) // printing a sampling of data
		}
	}
	if err := dec.Err(); err != nil {
		fmt.Println(`Err:`, err)
	}
	fmt.Printf("\nCreated %v goroutines\n", created)

}
Output:

event.HeapAlloc
event.HeapAlloc
event.HeapAlloc
event.GoCreate
event.ProcStop
event.String
event.String
event.Stack

Created 12 goroutines

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Decoder

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

Decoder reads events encoded in the Go trace format from an input stream.

func NewDecoder

func NewDecoder(r io.Reader) *Decoder

NewDecoder returns a new decoder that reads from r. If the given r is a bufio.Reader then the decoder will use it for buffering, otherwise creating a new bufio.Reader.

func (*Decoder) Decode

func (d *Decoder) Decode(evt *event.Event) error

Decode the next event from the input stream into the given *event.Event.

The evt argument must be non-nil or permanent failure occurs. Callers must call evt.Reset() if reusing *event.Event to prevent prior fields persisting.

Allocating a zero-value event.Event is sufficient as the decoder will create the Args and Data slices on demand. For performance it will use the same slice backings if they already have sufficient capacity. This allows zero allocation decoding by reusing an event, object, i.e.:

// The below allocations are generous, Args contains an average of 3-6 vals
// with an exception of Stack traces being depth * Frames. Data simply holds
// strings like file paths and func names.
evt := &event.Event{Args: make(512), Data: make(4096)}
for { dec.Decode(evt); ... }

Once a error is returned all future calls will return the same error until Reset is called. If the error is a io.EOF value then the Decoding was a success if at least one event has been read, otherwise io.ErrUnexpectedEOF is returned.

func (*Decoder) Err

func (d *Decoder) Err() error

Err returns the first error that occurred during decoding, if that error was io.EOF then Err() returns nil and the decoding was successful.

func (*Decoder) More

func (d *Decoder) More() bool

More returns true when events may still be retrieved, false otherwise. The first time More returns false, all future calls will return false until Reset is called.

func (*Decoder) Reset

func (d *Decoder) Reset(r io.Reader)

Reset the Decoder to read from r, if r is a bufio.Reader it will use it for buffering, otherwise resetting the existing bufio.Reader which may have been obtained from the caller of NewDecoder.

func (*Decoder) Version

func (d *Decoder) Version() (event.Version, error)

Version retrieves the version information contained in the encoded trace. You do not need to call this function directly to begin retrieving events. No I/O occurs unless no prior calls to Decode() have been made.

type Encoder

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

Encoder writes events encoded in the Go trace format to an output stream.

Events produced by the Encoder are always lexically correct, logical consistency with runtime produced events is the responsibility of the caller. It is included for testing systems that consume or parse trace events.

func NewEncoder

func NewEncoder(w io.Writer) *Encoder

NewEncoder returns a new encoder that emits events to w in the latest version of the Go trace format.

func (*Encoder) Emit

func (e *Encoder) Emit(evt *event.Event) error

Emit writes a single event to the the output stream. If Emit returns a non-nil error then failure is permanent and all future calls will immediately return the same error.

func (*Encoder) Err

func (e *Encoder) Err() error

Err returns the first error that occurred during encoding, once an error occurs all future calls to Err() will return the same value.

func (*Encoder) Reset

func (e *Encoder) Reset(w io.Writer)

Reset the Encoder for writing to w.

Jump to

Keyboard shortcuts

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