Commit feba660942faa38fad1bd3153ce2104865844c9a

Authored by Marko Tikvić
1 parent 0adcd85023
Exists in master

split line constant

Showing 1 changed file with 3 additions and 2 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) Log(format string, v ...interface{}) { 63 func (l *Logger) Log(format string, v ...interface{}) {
64 if l.outputFile == nil { 64 if l.outputFile == nil {
65 return 65 return
66 } 66 }
67 67
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 func (l *Logger) LogHTTPRequest(req *http.Request, userID string) string { 79 func (l *Logger) LogHTTPRequest(req *http.Request, userID string) string {
80 if userID == "" { 80 if userID == "" {
81 userID = "-" 81 userID = "-"
82 } 82 }
83 83
84 var b strings.Builder 84 var b strings.Builder
85 85
86 b.WriteString("Request:\n") 86 b.WriteString("Request:\n")
87 // CLF-like header 87 // CLF-like header
88 fmt.Fprintf(&b, "%s %s %s\n", req.RemoteAddr, userID, time.Now().Format(time.RFC3339)) 88 fmt.Fprintf(&b, "%s %s %s\n", req.RemoteAddr, userID, time.Now().Format(time.RFC3339))
89 89
90 body, err := httputil.DumpRequest(req, true) 90 body, err := httputil.DumpRequest(req, true)
91 if err != nil { 91 if err != nil {
92 fmt.Fprintf(os.Stderr, "%v\n", err) 92 fmt.Fprintf(os.Stderr, "%v\n", err)
93 } 93 }
94 b.WriteString(string(body) + "\n\n") 94 b.WriteString(string(body) + "\n\n")
95 95
96 return b.String() 96 return b.String()
97 } 97 }
98 98
99 const splitLine = "=============================================================="
100
99 func (l *Logger) LogHTTPResponse(status int, duration time.Duration, size int) string { 101 func (l *Logger) LogHTTPResponse(status int, duration time.Duration, size int) string {
100 splitLine := "==============================================================\n" 102 return fmt.Sprintf("Response:\n%d %v %dB\n%s\n", status, duration, size, splitLine)
101 return fmt.Sprintf("Response:\n%d %v %dB\n%s", status, duration, size, splitLine)
102 } 103 }
103 104
104 func (l *Logger) CombineHTTPLogs(in string, out string) { 105 func (l *Logger) CombineHTTPLogs(in string, out string) {
105 if l.outputFile == nil { 106 if l.outputFile == nil {
106 return 107 return
107 } 108 }
108 109
109 l.mu.Lock() 110 l.mu.Lock()
110 defer l.mu.Unlock() 111 defer l.mu.Unlock()
111 112
112 msg := in + out 113 msg := in + out
113 if l.shouldSplit(len(msg)) { 114 if l.shouldSplit(len(msg)) {
114 l.split() 115 l.split()
115 } 116 }
116 l.outputFile.WriteString(msg) 117 l.outputFile.WriteString(msg)
117 } 118 }
118 119
119 func (l *Logger) PrintTrace(format string, v ...interface{}) { 120 func (l *Logger) PrintTrace(format string, v ...interface{}) {
120 _, file, line, _ := runtime.Caller(1) 121 _, file, line, _ := runtime.Caller(1)
121 122
122 msg := fmt.Sprintf(format, v...) 123 msg := fmt.Sprintf(format, v...)
123 fmt.Printf("%s: %s %d: %s\n", time.Now().Format(time.RFC3339), file, line, msg) 124 fmt.Printf("%s: %s %d: %s\n", time.Now().Format(time.RFC3339), file, line, msg)
124 } 125 }
125 126
126 func (l *Logger) Print(format string, v ...interface{}) { 127 func (l *Logger) Print(format string, v ...interface{}) {
127 msg := fmt.Sprintf(format, v...) 128 msg := fmt.Sprintf(format, v...)
128 fmt.Printf("%s: %s\n", time.Now().Format(time.RFC3339), msg) 129 fmt.Printf("%s: %s\n", time.Now().Format(time.RFC3339), msg)
129 } 130 }
130 131
131 func (l *Logger) Trace(format string, v ...interface{}) { 132 func (l *Logger) Trace(format string, v ...interface{}) {
132 if l.outputFile == nil { 133 if l.outputFile == nil {
133 return 134 return
134 } 135 }
135 136
136 l.mu.Lock() 137 l.mu.Lock()
137 defer l.mu.Unlock() 138 defer l.mu.Unlock()
138 139
139 _, file, line, _ := runtime.Caller(1) 140 _, file, line, _ := runtime.Caller(1)
140 msg := fmt.Sprintf(format, v...) 141 msg := fmt.Sprintf(format, v...)
141 s := fmt.Sprintf("%s: %s %d: %s\n", time.Now().Format(time.RFC3339), file, line, msg) 142 s := fmt.Sprintf("%s: %s %d: %s\n", time.Now().Format(time.RFC3339), file, line, msg)
142 143
143 if l.shouldSplit(len(s)) { 144 if l.shouldSplit(len(s)) {
144 l.split() 145 l.split()
145 } 146 }
146 l.outputFile.WriteString(s) 147 l.outputFile.WriteString(s)
147 } 148 }
148 149
149 func (l *Logger) Close() { 150 func (l *Logger) Close() {
150 if l.outputFile == nil { 151 if l.outputFile == nil {
151 return 152 return
152 } 153 }
153 154
154 err := l.outputFile.Close() 155 err := l.outputFile.Close()
155 if err != nil { 156 if err != nil {
156 fmt.Printf("logger: on exit: couldn't close event log file\n") 157 fmt.Printf("logger: on exit: couldn't close event log file\n")
157 } 158 }
158 } 159 }
159 160
160 func (l *Logger) split() { 161 func (l *Logger) split() {
161 if l.outputFile == nil { 162 if l.outputFile == nil {
162 return 163 return
163 } 164 }
164 165
165 // close old file 166 // close old file
166 err := l.outputFile.Close() 167 err := l.outputFile.Close()
167 if err != nil { 168 if err != nil {
168 fmt.Printf("logger: split: couldn't close event file\n") 169 fmt.Printf("logger: split: couldn't close event file\n")
169 return 170 return
170 } 171 }
171 172
172 l.splitCount++ 173 l.splitCount++
173 // open new file 174 // open new file
174 var errnew error 175 var errnew error
175 path := filepath.Join(logDirName, l.outputFileName+fmt.Sprintf("(%d)", l.splitCount)+".txt") 176 path := filepath.Join(logDirName, l.outputFileName+fmt.Sprintf("(%d)", l.splitCount)+".txt")
176 l.outputFile, errnew = os.Create(path) 177 l.outputFile, errnew = os.Create(path)
177 178
178 if errnew != nil { 179 if errnew != nil {
179 fmt.Printf("logger: split: couldn't create event log file\n") 180 fmt.Printf("logger: split: couldn't create event log file\n")
180 } 181 }
181 } 182 }
182 183
183 func (l *Logger) shouldSplit(nextEntrySize int) bool { 184 func (l *Logger) shouldSplit(nextEntrySize int) bool {
184 stats, _ := l.outputFile.Stat() 185 stats, _ := l.outputFile.Stat()
185 return int64(nextEntrySize) >= (l.maxFileSize - stats.Size()) 186 return int64(nextEntrySize) >= (l.maxFileSize - stats.Size())
186 } 187 }