Commit b45f88e17f0d39b7eb32b7d10a93b9d7e187851f

Authored by Marko Tikvić
1 parent 92485819d1
Exists in master

more readable datetime format

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