Commit dda53db017c8a649ef6f2631c915ce626b66d440

Authored by Marko Tikvić
1 parent cccb4b47c0
Exists in master

log response changes

Showing 1 changed file with 6 additions and 4 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 maxFileSize int64 29 maxFileSize int64
30 30
31 splitCount int 31 splitCount int
32 } 32 }
33 33
34 func New(name string, maxFileSize int64) (logger *Logger, err error) { 34 func New(name string, maxFileSize int64) (logger *Logger, err error) {
35 logger = &Logger{} 35 logger = &Logger{}
36 36
37 logger.outputFileName = name + "-log" 37 logger.outputFileName = name + "-log"
38 logger.mu = &sync.Mutex{} 38 logger.mu = &sync.Mutex{}
39 logger.maxFileSize = maxFileSize 39 logger.maxFileSize = maxFileSize
40 40
41 err = os.Mkdir(logDirName, os.ModePerm) 41 err = os.Mkdir(logDirName, os.ModePerm)
42 if err != nil { 42 if err != nil {
43 if !os.IsExist(err) { 43 if !os.IsExist(err) {
44 fmt.Printf("logger: mkdir: couldn't create event log directory\n") 44 fmt.Printf("logger: mkdir: couldn't create event log directory\n")
45 return nil, err 45 return nil, err
46 } 46 }
47 } 47 }
48 48
49 date := strings.Replace(time.Now().Format(time.RFC3339), ":", ".", -1) 49 date := strings.Replace(time.Now().Format(time.RFC3339), ":", ".", -1)
50 logger.outputFileName += "_" + date + ".txt" 50 logger.outputFileName += "_" + date + ".txt"
51 path := filepath.Join(logDirName, logger.outputFileName) 51 path := filepath.Join(logDirName, logger.outputFileName)
52 logger.outputFile, err = os.Create(path) 52 logger.outputFile, err = os.Create(path)
53 if err != nil { 53 if err != nil {
54 fmt.Printf("logger: new: couldn't create event log file\n") 54 fmt.Printf("logger: new: couldn't create event log file\n")
55 return nil, err 55 return nil, err
56 } 56 }
57 57
58 return logger, nil 58 return logger, nil
59 } 59 }
60 60
61 func (l *Logger) Print(format string, v ...interface{}) { 61 func (l *Logger) Print(format string, v ...interface{}) {
62 msg := fmt.Sprintf(format, v...) 62 msg := fmt.Sprintf(format, v...)
63 fmt.Printf(time.Now().Format(time.RFC3339) + ": " + msg + "\n") 63 fmt.Printf(time.Now().Format(time.RFC3339) + ": " + msg + "\n")
64 } 64 }
65 65
66 func (l *Logger) Log(format string, v ...interface{}) { 66 func (l *Logger) Log(format string, v ...interface{}) {
67 if l.outputFile != nil { 67 if l.outputFile != nil {
68 l.mu.Lock() 68 l.mu.Lock()
69 defer l.mu.Unlock() 69 defer l.mu.Unlock()
70 70
71 msg := fmt.Sprintf(format, v...) 71 msg := fmt.Sprintf(format, v...)
72 s := time.Now().Format(time.RFC3339) + ": " + msg + "\n" 72 s := time.Now().Format(time.RFC3339) + ": " + msg + "\n"
73 if l.shouldSplit(len(s)) { 73 if l.shouldSplit(len(s)) {
74 l.split() 74 l.split()
75 } 75 }
76 l.outputFile.WriteString(s) 76 l.outputFile.WriteString(s)
77 } 77 }
78 } 78 }
79 79
80 func (l *Logger) LogRequest(req *http.Request, userid string) { 80 func (l *Logger) LogRequest(req *http.Request, userid string) {
81 if l.outputFile != nil { 81 if l.outputFile != nil {
82 if userid == "" { 82 if userid == "" {
83 userid = "-" 83 userid = "-"
84 } 84 }
85 85
86 var b strings.Builder 86 var b strings.Builder
87 b.WriteString("Request:\n") 87 b.WriteString("Request:\n")
88 // CLF-like header 88 // CLF-like header
89 ts := time.Now().Format(time.RFC3339) 89 ts := time.Now().Format(time.RFC3339)
90 fmt.Fprintf(&b, "%s %s\n", req.RemoteAddr, ts) 90 fmt.Fprintf(&b, "%s %s\n", req.RemoteAddr, ts)
91 91
92 body, err := httputil.DumpRequest(req, true) 92 body, err := httputil.DumpRequest(req, true)
93 if err != nil { 93 if err != nil {
94 fmt.Fprintf(os.Stderr, "%v\n", err) 94 fmt.Fprintf(os.Stderr, "%v\n", err)
95 } else { 95 } else {
96 b.WriteString(string(body)) 96 b.WriteString(string(body))
97 } 97 }
98 b.WriteString("\n\n") 98 b.WriteString("\n")
99 99
100 msg := b.String() 100 msg := b.String()
101 101
102 l.mu.Lock() 102 l.mu.Lock()
103 defer l.mu.Unlock() 103 defer l.mu.Unlock()
104 104
105 if l.shouldSplit(len(msg)) { 105 if l.shouldSplit(len(msg)) {
106 l.split() 106 l.split()
107 } 107 }
108 l.outputFile.WriteString(msg) 108 l.outputFile.WriteString(msg)
109 } 109 }
110 } 110 }
111 111
112 func (l *Logger) LogResponse(w http.ResponseWriter, duration time.Duration) { 112 func (l *Logger) LogResponse(w http.ResponseWriter, req *http.Request, duration time.Duration) {
113 if l.outputFile != nil { 113 if l.outputFile != nil {
114 var b strings.Builder 114 var b strings.Builder
115 b.WriteString("Response:\n") 115 b.WriteString("Response:\n")
116 fmt.Fprintf(&b, "%s %s\n", req.Method, req.RequestURI)
116 for k, v := range w.Header() { 117 for k, v := range w.Header() {
117 b.WriteString(fmt.Sprintf("%s: %s\n", k, v)) 118 fmt.Fprintf(&b, "%s: %s\n", k, v)
118 } 119 }
119 b.WriteString(fmt.Sprintf("\nCompleted in: %v\n", duration)) 120 fmt.Fprintf(&b, "\nCompleted in: %v\n", duration)
121 b.WriteString("==============================================================\n\n")
120 msg := b.String() 122 msg := b.String()
121 123
122 l.mu.Lock() 124 l.mu.Lock()
123 defer l.mu.Unlock() 125 defer l.mu.Unlock()
124 126
125 if l.shouldSplit(len(msg)) { 127 if l.shouldSplit(len(msg)) {
126 l.split() 128 l.split()
127 } 129 }
128 l.outputFile.WriteString(msg) 130 l.outputFile.WriteString(msg)
129 } 131 }
130 } 132 }
131 133
132 func (l *Logger) Trace(format string, v ...interface{}) { 134 func (l *Logger) Trace(format string, v ...interface{}) {
133 if l.outputFile != nil { 135 if l.outputFile != nil {
134 l.mu.Lock() 136 l.mu.Lock()
135 defer l.mu.Unlock() 137 defer l.mu.Unlock()
136 _, file, line, ok := runtime.Caller(1) 138 _, file, line, ok := runtime.Caller(1)
137 139
138 s := "" 140 s := ""
139 msg := fmt.Sprintf(format, v...) 141 msg := fmt.Sprintf(format, v...)
140 if ok { 142 if ok {
141 s = fmt.Sprintf("%s: %s %d: %s\n", time.Now().Format(time.RFC3339), file, line, msg) 143 s = fmt.Sprintf("%s: %s %d: %s\n", time.Now().Format(time.RFC3339), file, line, msg)
142 } else { 144 } else {
143 s = fmt.Sprintf(time.Now().Format(time.RFC3339) + ": [can't retreive stack details]:" + msg + "\n") 145 s = fmt.Sprintf(time.Now().Format(time.RFC3339) + ": [can't retreive stack details]:" + msg + "\n")
144 } 146 }
145 if l.shouldSplit(len(s)) { 147 if l.shouldSplit(len(s)) {
146 l.split() 148 l.split()
147 } 149 }
148 l.outputFile.WriteString(s) 150 l.outputFile.WriteString(s)
149 } 151 }
150 } 152 }
151 153
152 func (l *Logger) Close() { 154 func (l *Logger) Close() {
153 if l.outputFile != nil { 155 if l.outputFile != nil {
154 err := l.outputFile.Close() 156 err := l.outputFile.Close()
155 if err != nil { 157 if err != nil {
156 fmt.Printf("logger: on exit: couldn't close event log file\n") 158 fmt.Printf("logger: on exit: couldn't close event log file\n")
157 } 159 }
158 } 160 }
159 } 161 }
160 162
161 func (l *Logger) split() { 163 func (l *Logger) split() {
162 // close old file 164 // close old file
163 err := l.outputFile.Close() 165 err := l.outputFile.Close()
164 if err != nil { 166 if err != nil {
165 fmt.Printf("logger: split: couldn't close event file\n") 167 fmt.Printf("logger: split: couldn't close event file\n")
166 return 168 return
167 } 169 }
168 170
169 l.splitCount++ 171 l.splitCount++
170 // open new file 172 // open new file
171 var errnew error 173 var errnew error
172 path := filepath.Join(logDirName, l.outputFileName+fmt.Sprintf("(%d)", l.splitCount)) 174 path := filepath.Join(logDirName, l.outputFileName+fmt.Sprintf("(%d)", l.splitCount))
173 l.outputFile, errnew = os.Create(path) 175 l.outputFile, errnew = os.Create(path)
174 176
175 if errnew != nil { 177 if errnew != nil {
176 fmt.Printf("logger: split: couldn't create event log file\n") 178 fmt.Printf("logger: split: couldn't create event log file\n")
177 } 179 }
178 } 180 }
179 181
180 func (l *Logger) shouldSplit(nextEntrySize int) bool { 182 func (l *Logger) shouldSplit(nextEntrySize int) bool {
181 stats, _ := l.outputFile.Stat() 183 stats, _ := l.outputFile.Stat()
182 return int64(nextEntrySize) >= (l.maxFileSize - stats.Size()) 184 return int64(nextEntrySize) >= (l.maxFileSize - stats.Size())
183 } 185 }
184 186