-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy patherrlog.go
109 lines (89 loc) · 2.37 KB
/
errlog.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package dev
import (
"bufio"
"fmt"
"io"
"os"
"path/filepath"
"time"
)
// ErrlogPath builds the full pathname for errlog file.
func ErrlogPath(pathPrefix, id string) string {
dir := filepath.Dir(pathPrefix)
path := filepath.Join(dir, id) + ".errlog"
return path
}
func errlog(logger hasPrintf, result FetchResult, pathPrefix string, debug bool, histSize int) {
now := time.Now()
path := ErrlogPath(pathPrefix, result.DevID)
f, openErr := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0640)
if openErr != nil {
logger.Printf("errlog: could not open dev log: '%s': %v", path, openErr)
return
}
defer f.Close()
// load lines
lines, lineErr := loadLines(bufio.NewReader(f), histSize-1)
if lineErr != nil {
logger.Printf("errlog: could not load lines: '%s': %v", path, lineErr)
return
}
if debug {
logger.Printf("errlog debug: '%s': %d lines", path, len(lines))
}
// truncate file
if truncErr := f.Truncate(0); truncErr != nil {
logger.Printf("errlog: truncate error: %v", truncErr)
return
}
if _, seekErr := f.Seek(0, 0); seekErr != nil {
logger.Printf("errlog: seek error: %v", seekErr)
return
}
// push result
w := bufio.NewWriter(f)
msg := fmt.Sprintf("%s success=%v elapsed=%v model=%s dev=%s host=%s transport=%s code=%d message=[%s]",
now.String(),
result.Code == fetchErrNone,
result.End.Sub(result.Begin),
result.Model, result.DevID, result.DevHostPort, result.Transport, result.Code, result.Msg)
logger.Printf("errlog: push: %s: %s", path, msg)
_, pushErr := w.WriteString(msg + "\n")
if pushErr != nil {
logger.Printf("errlog: push error: '%s': %v", path, pushErr)
return
}
// write lines back to file
for _, line := range lines {
_, writeErr := w.Write(line)
if writeErr != nil {
logger.Printf("errlog: write error: '%s': %v", path, writeErr)
break
}
}
if flushErr := w.Flush(); flushErr != nil {
logger.Printf("errlog: flush: '%s': %v", path, flushErr)
}
if syncErr := f.Sync(); syncErr != nil {
logger.Printf("errlog: sync: '%s': %v", path, syncErr)
}
}
func loadLines(r *bufio.Reader, max int) ([][]byte, error) {
var lines [][]byte
LOOP:
for lineCount := 0; lineCount < max; lineCount++ {
line, readErr := r.ReadBytes(LF)
if len(line) > 0 {
lines = append(lines, line)
}
switch readErr {
case io.EOF:
break LOOP
case nil:
continue
default:
return lines, readErr
}
}
return lines, nil
}