Commit 92485819d1dce07b76d7ef21ebecd8ad6ae9d8af
1 parent
feba660942
Exists in
master
lint
Showing
1 changed file
with
48 additions
and
30 deletions
Show diff stats
main.go
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 |