Commit 093191eb2230cc24d6d609f6307b8681d9baae3a

Authored by Marko Tikvić
1 parent 1f7fbc601b
Exists in master

much cleaner, much better

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