From d44967635b318c09f53d56d440f63a18d21a7f57 Mon Sep 17 00:00:00 2001 From: webbrain-one <295484252+webbrain-one@users.noreply.github.com> Date: Sun, 30 Aug 2026 07:17:05 +0300 Subject: [PATCH] Add timestamps to process output Prefix process output lines with an `HH:MM:SS` timestamp to match honcho behavior. Refs #5 --- CHANGELOG.md | 2 +- executor.go | 4 +++- timestamp.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 timestamp.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ba822c..d5da1c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [Unreleased] -Nothing yet +- Add timestamps to process output (fgrosse/prox#5) ## [1.1.0] - 2024-07-13 - Improve file name matching when determining parser for value of --procfile flag (fgrosse/prox#8) diff --git a/executor.go b/executor.go index b20593d..03b4f4b 100644 --- a/executor.go +++ b/executor.go @@ -69,7 +69,9 @@ func (e *Executor) Run(ctx context.Context, processes []Process) error { defer logger.Sync() go e.monitorContext(ctx, logger) - output := e.newOutput(processes) + // Add a timestamp to the process output, but not to prox's own log + // output. + output := newOutput(processes, e.noColors, newTimestampWriter(e.output)) pp := make([]process, len(processes)) for i, p := range processes { po := output.next(p) diff --git a/timestamp.go b/timestamp.go new file mode 100644 index 0000000..89109e0 --- /dev/null +++ b/timestamp.go @@ -0,0 +1,49 @@ +package prox + +import ( + "bytes" + "io" + "sync" + "time" +) + +const timestampFormat = "15:04:05" + +// timestampWriter prefixes every complete line written to it with the current +// time (HH:MM:SS). +type timestampWriter struct { + w io.Writer + mu sync.Mutex + buf []byte +} + +func newTimestampWriter(w io.Writer) *timestampWriter { + return ×tampWriter{w: w} +} + +func (t *timestampWriter) Write(p []byte) (int, error) { + t.mu.Lock() + defer t.mu.Unlock() + + t.buf = append(t.buf, p...) + + for { + i := bytes.IndexByte(t.buf, '\n') + if i == -1 { + break + } + + line := t.buf[:i+1] + t.buf = t.buf[i+1:] + + stamped := make([]byte, 0, len(line)+9) + stamped = append(stamped, time.Now().Format(timestampFormat)+" "...) + stamped = append(stamped, line...) + + if _, err := t.w.Write(stamped); err != nil { + return 0, err + } + } + + return len(p), nil +}