@@ -38,25 +38,26 @@ type line struct {
3838}
3939
4040type configuration struct {
41- timeFormat string // -timeformat="..."
42- template string // -template="..."
43- start string // -start="..."
44- readJSON bool // -readjson
45- jsonTemplate string // -jsontemplate="..."
46- colorScale string // -scale="..."
47- fast time.Duration // -scale-fast="..."
48- slow time.Duration // -scale-slow="..."
49- buffer bool // -delta-buffer
50- version string
41+ timeFormat string // -timeformat="..."
42+ template string // -template="..."
43+ start string // -start="..."
44+ readJSON bool // -readjson
45+ jsonTemplate string // -jsontemplate="..."
46+ colorScale string // -scale="..."
47+ fast time.Duration // -scale-fast="..."
48+ slow time.Duration // -scale-slow="..."
49+ buffer bool // -delta-buffer
50+ printVersionAndExit bool // -version
5151}
5252
5353type printerFunc func (line * line ) error
5454
5555var (
56+ version string
5657 config configuration
5758 printer printerFunc
5859 start * regexp.Regexp
59- jsonTemplate * template. Template
60+ jsonTemplate * templateWithBuffer
6061 scale color.Scale
6162)
6263
@@ -162,7 +163,12 @@ func init() {
162163 flag .DurationVar (& config .fast , "scale-fast" , 100 * time .Millisecond , "the lower bound for the color scale" )
163164 flag .DurationVar (& config .slow , "scale-slow" , 2 * time .Second , "the upper bound for the color scale" )
164165 flag .BoolVar (& config .buffer , "delta-buffer" , false , "buffer lines between -start matches, copy delta values from final line to buffered lines" )
166+ flag .BoolVar (& config .printVersionAndExit , "version" , false , "print version and exit" )
165167 flag .Parse ()
168+ if config .printVersionAndExit {
169+ fmt .Println (version )
170+ os .Exit (0 )
171+ }
166172 if knownFormat , ok := timeFormats [config .timeFormat ]; ok {
167173 config .timeFormat = knownFormat
168174 }
@@ -185,31 +191,60 @@ func init() {
185191 }
186192 if config .jsonTemplate != "" {
187193 config .readJSON = true
188- jsonTemplate = template .Must (template .New ("-jsontemplate" ).Option ("missingkey=zero" ).Parse (config .jsonTemplate ))
194+ jsonTemplate = & templateWithBuffer {
195+ template : template .Must (template .New ("-jsontemplate" ).Option ("missingkey=zero" ).Parse (config .jsonTemplate )),
196+ buffer : bytes .NewBuffer (nil ),
197+ }
189198 }
190199}
191200
192- func flushLineBuffer (buffer * []* line , line * line ) {
193- for _ , oldLine := range * buffer {
201+ type lineBuffer []* line
202+
203+ func (b * lineBuffer ) flush (line * line ) {
204+ for i , oldLine := range * b {
194205 oldLine .DeltaSecs = line .DeltaSecs
195206 oldLine .DeltaNanos = line .DeltaNanos
196207 oldLine .DeltaString = line .DeltaString
197208 oldLine .Delta = line .Delta
198- if err := printer (oldLine ); err != nil {
199- fmt .Fprintln (os .Stderr , "output error:" , err )
200- }
209+ oldLine .print ()
210+ (* b )[i ] = nil
211+ }
212+ * b = (* b )[:0 ]
213+ }
214+
215+ func (l * line ) print () {
216+ if err := printer (l ); err != nil {
217+ fmt .Fprintln (os .Stderr , "output error:" , err )
218+ }
219+ }
220+
221+ func (l * line ) parseJSON () {
222+ l .Object = new (interface {})
223+ if err := json .Unmarshal ([]byte (l .Text ), & l .Object ); err != nil {
224+ fmt .Fprintln (os .Stderr , "JSON parse error:" , err )
201225 }
202- * buffer = (* buffer )[:0 ]
226+ }
227+
228+ type templateWithBuffer struct {
229+ template * template.Template
230+ buffer * bytes.Buffer
231+ }
232+
233+ func (t * templateWithBuffer ) execute (data interface {}) string {
234+ t .buffer .Reset ()
235+ if err := t .template .Execute (t .buffer , data ); err != nil {
236+ fmt .Fprintln (os .Stderr , "template error:" , err )
237+ }
238+ return t .buffer .String ()
203239}
204240
205241func main () {
206242 scanner := bufio .NewScanner (os .Stdin )
207- lineBuffer := [] * line {}
243+ lineBuffer := lineBuffer {}
208244 line := line {Time : time .Now ()}
209245 first := line .Time
210246 last := line .Time
211247 i := uint64 (0 )
212- b := bytes .NewBuffer (nil )
213248 for scanner .Scan () {
214249 now := time .Now ()
215250 delta := now .Sub (last )
@@ -228,47 +263,42 @@ func main() {
228263 line .Time = now
229264 line .Text = scanner .Text ()
230265 line .I = i
231- match := line .Text
266+ match := & line .Text
232267 if config .readJSON {
233- line .Object = new (interface {})
234- if err := json .Unmarshal ([]byte (line .Text ), & line .Object ); err != nil {
235- fmt .Fprintln (os .Stderr , "JSON parse error:" , err )
236- }
268+ line .parseJSON ()
237269 if jsonTemplate != nil {
238- b .Reset ()
239- if err := jsonTemplate .Execute (b , line .Object ); err != nil {
240- fmt .Fprintln (os .Stderr , "template error:" , err )
241- }
242- line .JSONText = b .String ()
243- match = line .JSONText
270+ line .JSONText = jsonTemplate .execute (line .Object )
271+ match = & line .JSONText
244272 }
245273 }
246- if ! config .buffer {
247- if err := printer (& line ); err != nil {
248- fmt .Fprintln (os .Stderr , "output error:" , err )
249- }
274+
275+ startDefined := start != nil
276+ printLine := ! startDefined || ! config .buffer
277+ startMatches := startDefined && start .MatchString (* match )
278+ resetStopwatch := ! startDefined || startMatches
279+
280+ if printLine {
281+ line .print ()
250282 }
251- if start != nil {
252- if start .MatchString (match ) {
253- if config .buffer {
254- flushLineBuffer (& lineBuffer , & line )
255- }
256- last = now
257- line .StartText = line .Text
258- line .StartObject = line .Object
259- }
283+ if startMatches {
284+ line .StartText = line .Text
285+ line .StartObject = line .Object
260286 if config .buffer {
261- lineCopy := line
262- lineBuffer = append (lineBuffer , & lineCopy )
287+ lineBuffer .flush (& line )
263288 }
264- } else {
289+ }
290+ if ! printLine {
291+ lineCopy := line
292+ lineBuffer = append (lineBuffer , & lineCopy )
293+ }
294+ if resetStopwatch {
265295 last = now
266296 }
267297 i ++
268298 }
269299
270300 if config .buffer {
271- flushLineBuffer ( & lineBuffer , & line )
301+ lineBuffer . flush ( & line )
272302 }
273303
274304 if err := scanner .Err (); err != nil {
0 commit comments