Commit 92485819d1dce07b76d7ef21ebecd8ad6ae9d8af

Authored by Marko Tikvić
1 parent feba660942
Exists in master

lint

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