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.org/s/go15trace
In general Events have intuitive names, when they are not it may help to read the scheduler design doc at https://golang.org/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 ¶
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 ¶
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 ¶
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 ¶
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.
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 ¶
NewEncoder returns a new encoder that emits events to w in the latest version of the Go trace format.
func (*Encoder) Emit ¶
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.