eventlog reads the event log that progress.Log writes. A view of what a
program did reads it, and so does a server that runs a command as a child
and sends on the child’s progress.
| Name | What it does |
|---|---|
eventlog.Decode | one line back into what was written, every text sanitised |
eventlog.NewTail, eventlog.Tail | reads a log as it grows, and follows it when it is rotated |
eventlog.NewReducer, eventlog.Reducer | folds the lines into runs, each the tree of its spans |
eventlog.NewForwarder, eventlog.Forwarder | gives the events of one trace to a sink, once each |
eventlog.ErrVersion | a line of another version of the format |
dir, err := os.MkdirTemp("", "view")
if err != nil {
panic(err)
}
defer func() { _ = os.RemoveAll(dir) }()
path := filepath.Join(dir, "activity.jsonl")
// A command of the program, which appends to its log.
f, err := os.Create(path)
if err != nil {
panic(err)
}
log := progress.NewLog(f, progress.LogOptions{RunID: "0123456789abcdef", Version: "v1.2.3"})
bus := progress.NewBus(progress.BusOptions{Sinks: []progress.Sink{log}, Program: "prog"})
ctx, cmd := progress.Start(progress.WithBus(context.Background(), bus), progress.KindCommand, "status")
fanout.Map(ctx, []string{"exe1", "exe2"}, fanout.MapOptions[string]{Step: "probe the nodes"},
func(_ context.Context, node string) (struct{}, error) {
if node == "exe2" {
return struct{}{}, errors.New("no route to host")
}
return struct{}{}, nil
})
cmd.End(nil)
bus.Close()
if err := log.Close(); err != nil {
panic(err)
}
_ = f.Close()
// The view.
red := eventlog.NewReducer(eventlog.ReducerOptions{})
tail := eventlog.NewTail(path, red)
if _, err := tail.Poll(); err != nil {
panic(err)
}
fmt.Println(red.Changed())
for _, run := range red.Runs() {
fmt.Println(run.Program, run.Version, run.Root.Name, run.Root.Status)
for _, step := range run.Root.Children {
fmt.Println(" ", step.Kind, step.Name, step.Status, step.Err)
for _, target := range step.Children {
fmt.Println(" ", target.Kind, target.Node, target.Status)
}
}
}[0123456789abcdef]
prog v1.2.3 status ok
step probe the nodes failed 1 of 2 failed: exe2
target exe1 ok
target exe2 failedprogress/eventlog/example_test.go. CI runs it and checks its output.NOTE
A reader of version 1 passes over the keys and the values that it does not
know. So a log that a later release writes, with a key added, still reads.
A line of another version is refused with ErrVersion.