8363: Report arv-mount error messages as runtime_status warnings.
[arvados.git] / lib / crunchrun / logscanner.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package crunchrun
6
7 import (
8         "bytes"
9         "strings"
10 )
11
12 // logScanner is an io.Writer that calls ReportFunc(pattern) the first
13 // time one of the Patterns appears in the data. Patterns must not
14 // contain newlines.
15 type logScanner struct {
16         Patterns   []string
17         ReportFunc func(string)
18         reported   bool
19         buf        bytes.Buffer
20 }
21
22 func (s *logScanner) Write(p []byte) (int, error) {
23         if s.reported {
24                 // We only call reportFunc once. Once we've called it
25                 // there's no need to buffer/search subsequent writes.
26                 return len(p), nil
27         }
28         split := bytes.LastIndexByte(p, '\n')
29         if split < 0 {
30                 return s.buf.Write(p)
31         }
32         s.buf.Write(p[:split+1])
33         txt := s.buf.String()
34         for _, pattern := range s.Patterns {
35                 if strings.Contains(txt, pattern) {
36                         s.ReportFunc(pattern)
37                         s.reported = true
38                         return len(p), nil
39                 }
40         }
41         s.buf.Reset()
42         if split == len(p) {
43                 return len(p), nil
44         }
45         n, err := s.buf.Write(p[split+1:])
46         return n + split + 1, err
47 }