Commit 3e936a3c2f80ff83b96672d6474b2358499ade44

Authored by Marko Tikvić
1 parent ed6549a336
Exists in master

output file name sequence fix

Showing 1 changed file with 22 additions and 7 deletions   Show diff stats
1 package gologger 1 package gologger
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 "net/http" 5 "net/http"
6 "net/http/httputil" 6 "net/http/httputil"
7 "os" 7 "os"
8 "path/filepath" 8 "path/filepath"
9 "runtime" 9 "runtime"
10 "strings" 10 "strings"
11 "sync" 11 "sync"
12 "time" 12 "time"
13 ) 13 )
14 14
15 const ( 15 const (
16 MaxLogSize5MB int64 = 5 * 1024 * 1024 16 MaxLogSize5MB int64 = 5 * 1024 * 1024
17 MaxLogSize1MB int64 = 1 * 1024 * 1024 17 MaxLogSize1MB int64 = 1 * 1024 * 1024
18 MaxLogSize500KB int64 = 500 * 1024 18 MaxLogSize500KB int64 = 500 * 1024
19 MaxLogSize100KB int64 = 100 * 1024 19 MaxLogSize100KB int64 = 100 * 1024
20 MaxLogSize512B int64 = 512 20 MaxLogSize512B int64 = 512
21 logDirName = "log" 21 logDirName = "log"
22 ) 22 )
23 23
24 type Logger struct { 24 type Logger struct {
25 mu *sync.Mutex 25 mu *sync.Mutex
26 outputFile *os.File 26 outputFile *os.File
27 27
28 outputFileName string 28 outputFileName string
29 fullName string
29 maxFileSize int64 30 maxFileSize int64
30 31
31 splitCount int 32 splitCount int
32 } 33 }
33 34
34 func New(name string, maxFileSize int64) (logger *Logger, err error) { 35 func New(name string, maxFileSize int64) (logger *Logger, err error) {
35 logger = &Logger{} 36 logger = &Logger{}
36 37
37 logger.outputFileName = name + "-log" 38 logger.outputFileName = name + "-log"
38 logger.mu = &sync.Mutex{} 39 logger.mu = &sync.Mutex{}
39 logger.maxFileSize = maxFileSize 40 logger.maxFileSize = maxFileSize
40 41
41 err = os.Mkdir(logDirName, os.ModePerm) 42 err = os.Mkdir(logDirName, os.ModePerm)
42 if err != nil { 43 if err != nil {
43 if !os.IsExist(err) { 44 if !os.IsExist(err) {
44 fmt.Printf("logger: mkdir: couldn't create event log directory\n") 45 fmt.Printf("logger: mkdir: couldn't create event log directory\n")
45 return nil, err 46 return nil, err
46 } 47 }
47 } 48 }
48 49
49 date := strings.Replace(time.Now().Format(time.RFC3339), ":", ".", -1) 50 date := strings.Replace(time.Now().Format(time.RFC3339), ":", ".", -1)
50 logger.outputFileName += "_" + date + ".txt" 51 logger.outputFileName += "_" + date
51 path := filepath.Join(logDirName, logger.outputFileName) 52 logger.fullName = logger.outputFileName + ".txt"
53 path := filepath.Join(logDirName, logger.fullName)
52 logger.outputFile, err = os.Create(path) 54 logger.outputFile, err = os.Create(path)
53 if err != nil { 55 if err != nil {
54 fmt.Printf("logger: new: couldn't create event log file\n") 56 fmt.Printf("logger: new: couldn't create event log file\n")
55 return nil, err 57 return nil, err
56 } 58 }
57 59
58 return logger, nil 60 return logger, nil
59 } 61 }
60 62
61 func (l *Logger) Print(format string, v ...interface{}) { 63 func (l *Logger) Print(format string, v ...interface{}) {
62 msg := fmt.Sprintf(format, v...) 64 msg := fmt.Sprintf(format, v...)
63 fmt.Printf(time.Now().Format(time.RFC3339) + ": " + msg + "\n") 65 fmt.Printf(time.Now().Format(time.RFC3339) + ": " + msg + "\n")
64 } 66 }
65 67
66 func (l *Logger) Log(format string, v ...interface{}) { 68 func (l *Logger) Log(format string, v ...interface{}) {
67 if l.outputFile == nil { 69 if l.outputFile == nil {
68 return 70 return
69 } 71 }
70 72
71 l.mu.Lock() 73 l.mu.Lock()
72 defer l.mu.Unlock() 74 defer l.mu.Unlock()
73 75
74 msg := fmt.Sprintf(format, v...) 76 msg := fmt.Sprintf(format, v...)
75 s := time.Now().Format(time.RFC3339) + ": " + msg + "\n" 77 s := time.Now().Format(time.RFC3339) + ": " + msg + "\n"
76 if l.shouldSplit(len(s)) { 78 if l.shouldSplit(len(s)) {
77 l.split() 79 l.split()
78 } 80 }
79 l.outputFile.WriteString(s) 81 l.outputFile.WriteString(s)
80 } 82 }
81 83
82 func (l *Logger) RequestLog(req *http.Request, userid string) string { 84 func (l *Logger) RequestLog(req *http.Request, userid string) string {
83 if l.outputFile == nil { 85 if l.outputFile == nil {
84 return "" 86 return ""
85 } 87 }
86 88
87 if userid == "" { 89 if userid == "" {
88 userid = "-" 90 userid = "-"
89 } 91 }
90 92
91 var b strings.Builder 93 var b strings.Builder
92 b.WriteString("Request:\n") 94 b.WriteString("Request:\n")
93 // CLF-like header 95 // CLF-like header
94 ts := time.Now().Format(time.RFC3339) 96 ts := time.Now().Format(time.RFC3339)
95 fmt.Fprintf(&b, "%s %s\n", req.RemoteAddr, ts) 97 fmt.Fprintf(&b, "%s %s\n", req.RemoteAddr, ts)
96 98
97 body, err := httputil.DumpRequest(req, true) 99 headers := req.Header
98 if err != nil { 100 content := headers.Get("Content-Type")
99 fmt.Fprintf(os.Stderr, "%v\n", err) 101 if content != "application/json" {
102 b.WriteString(fmt.Sprintf("%s %s\n", req.Method, req.URL))
103 for k, h := range headers {
104 b.WriteString(k + ": ")
105 for _, h2 := range h {
106 b.WriteString(h2 + " ")
107 }
108 b.WriteString("\n")
109 }
100 } else { 110 } else {
101 b.WriteString(string(body)) 111 body, err := httputil.DumpRequest(req, true)
112 if err != nil {
113 fmt.Fprintf(os.Stderr, "%v\n", err)
114 } else {
115 b.WriteString(string(body))
116 }
102 } 117 }
103 b.WriteString("\n\n") 118 b.WriteString("\n\n")
104 119
105 msg := b.String() 120 msg := b.String()
106 121
107 return msg 122 return msg
108 } 123 }
109 124
110 func (l *Logger) ResponseLog(status int, duration time.Duration, size int64) string { 125 func (l *Logger) ResponseLog(status int, duration time.Duration, size int64) string {
111 if l.outputFile == nil { 126 if l.outputFile == nil {
112 return "" 127 return ""
113 } 128 }
114 129
115 var b strings.Builder 130 var b strings.Builder
116 fmt.Fprintf(&b, "Response:\n%d %v %dB\n", status, duration, size) 131 fmt.Fprintf(&b, "Response:\n%d %v %dB\n", status, duration, size)
117 b.WriteString("==============================================================\n") 132 b.WriteString("==============================================================\n")
118 msg := b.String() 133 msg := b.String()
119 134
120 return msg 135 return msg
121 } 136 }
122 137
123 func (l *Logger) LogHTTPTraffic(in string, out string) { 138 func (l *Logger) LogHTTPTraffic(in string, out string) {
124 if l.outputFile == nil { 139 if l.outputFile == nil {
125 return 140 return
126 } 141 }
127 142
128 msg := in + out 143 msg := in + out
129 144
130 l.mu.Lock() 145 l.mu.Lock()
131 defer l.mu.Unlock() 146 defer l.mu.Unlock()
132 147
133 if l.shouldSplit(len(msg)) { 148 if l.shouldSplit(len(msg)) {
134 l.split() 149 l.split()
135 } 150 }
136 l.outputFile.WriteString(msg) 151 l.outputFile.WriteString(msg)
137 } 152 }
138 153
139 func (l *Logger) Trace(format string, v ...interface{}) { 154 func (l *Logger) Trace(format string, v ...interface{}) {
140 if l.outputFile == nil { 155 if l.outputFile == nil {
141 return 156 return
142 } 157 }
143 158
144 l.mu.Lock() 159 l.mu.Lock()
145 defer l.mu.Unlock() 160 defer l.mu.Unlock()
146 _, file, line, ok := runtime.Caller(1) 161 _, file, line, ok := runtime.Caller(1)
147 162
148 s := "" 163 s := ""
149 msg := fmt.Sprintf(format, v...) 164 msg := fmt.Sprintf(format, v...)
150 if ok { 165 if ok {
151 s = fmt.Sprintf("%s: %s %d: %s\n", time.Now().Format(time.RFC3339), file, line, msg) 166 s = fmt.Sprintf("%s: %s %d: %s\n", time.Now().Format(time.RFC3339), file, line, msg)
152 } else { 167 } else {
153 s = fmt.Sprintf(time.Now().Format(time.RFC3339) + ": [can't retreive stack details]:" + msg + "\n") 168 s = fmt.Sprintf(time.Now().Format(time.RFC3339) + ": [can't retreive stack details]:" + msg + "\n")
154 } 169 }
155 if l.shouldSplit(len(s)) { 170 if l.shouldSplit(len(s)) {
156 l.split() 171 l.split()
157 } 172 }
158 l.outputFile.WriteString(s) 173 l.outputFile.WriteString(s)
159 } 174 }
160 175
161 func (l *Logger) Close() { 176 func (l *Logger) Close() {
162 if l.outputFile == nil { 177 if l.outputFile == nil {
163 return 178 return
164 } 179 }
165 180
166 err := l.outputFile.Close() 181 err := l.outputFile.Close()
167 if err != nil { 182 if err != nil {
168 fmt.Printf("logger: on exit: couldn't close event log file\n") 183 fmt.Printf("logger: on exit: couldn't close event log file\n")
169 } 184 }
170 } 185 }
171 186
172 func (l *Logger) split() { 187 func (l *Logger) split() {
173 if l.outputFile == nil { 188 if l.outputFile == nil {
174 return 189 return
175 } 190 }
176 191
177 // close old file 192 // close old file
178 err := l.outputFile.Close() 193 err := l.outputFile.Close()
179 if err != nil { 194 if err != nil {
180 fmt.Printf("logger: split: couldn't close event file\n") 195 fmt.Printf("logger: split: couldn't close event file\n")
181 return 196 return
182 } 197 }
183 198
184 l.splitCount++ 199 l.splitCount++
185 // open new file 200 // open new file
186 var errnew error 201 var errnew error
187 path := filepath.Join(logDirName, l.outputFileName+fmt.Sprintf("(%d)", l.splitCount)) 202 path := filepath.Join(logDirName, l.outputFileName+fmt.Sprintf("(%d)", l.splitCount)+".txt")
188 l.outputFile, errnew = os.Create(path) 203 l.outputFile, errnew = os.Create(path)
189 204
190 if errnew != nil { 205 if errnew != nil {
191 fmt.Printf("logger: split: couldn't create event log file\n") 206 fmt.Printf("logger: split: couldn't create event log file\n")
192 } 207 }
193 } 208 }
194 209
195 func (l *Logger) shouldSplit(nextEntrySize int) bool { 210 func (l *Logger) shouldSplit(nextEntrySize int) bool {
196 stats, _ := l.outputFile.Stat() 211 stats, _ := l.outputFile.Stat()
197 return int64(nextEntrySize) >= (l.maxFileSize - stats.Size()) 212 return int64(nextEntrySize) >= (l.maxFileSize - stats.Size())
198 } 213 }
199 214