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