Commit df74f4a7ee0b8df78da5b96abc0749b19854ddd0
1 parent
aa60a45eec
Exists in
master
new filename format
Showing
1 changed file
with
61 additions
and
34 deletions
Show diff stats
main.go
1 | package gologger | 1 | package gologger |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | "io/ioutil" | ||
6 | "net/http" | ||
5 | "os" | 7 | "os" |
6 | "path/filepath" | 8 | "path/filepath" |
7 | "runtime" | 9 | "runtime" |
8 | "strings" | 10 | "strings" |
9 | "sync" | 11 | "sync" |
10 | "time" | 12 | "time" |
11 | ) | 13 | ) |
12 | 14 | ||
13 | const ( | 15 | const ( |
14 | MaxLogSize5MB int64 = 5 * 1024 * 1024 | 16 | MaxLogSize5MB int64 = 5 * 1024 * 1024 |
15 | MaxLogSize1MB int64 = 1 * 1024 * 1024 | 17 | MaxLogSize1MB int64 = 1 * 1024 * 1024 |
16 | MaxLogSize500KB int64 = 500 * 1024 | 18 | MaxLogSize500KB int64 = 500 * 1024 |
17 | MaxLogSize100KB int64 = 100 * 1024 | 19 | MaxLogSize100KB int64 = 100 * 1024 |
18 | MaxLogSize512B int64 = 512 | 20 | MaxLogSize512B int64 = 512 |
19 | logDirName = "log" | 21 | logDirName = "log" |
20 | ) | 22 | ) |
21 | 23 | ||
22 | type Logger struct { | 24 | type Logger struct { |
23 | mu *sync.Mutex | 25 | mu *sync.Mutex |
24 | outputFile *os.File | 26 | outputFile *os.File |
25 | 27 | ||
26 | outputFileName string | 28 | outputFileName string |
27 | maxFileSize int64 | 29 | maxFileSize int64 |
30 | |||
31 | splitCount int | ||
28 | } | 32 | } |
29 | 33 | ||
30 | func New(name string, maxFileSize int64) (logger *Logger, err error) { | 34 | func New(name string, maxFileSize int64) (logger *Logger, err error) { |
31 | logger = &Logger{} | 35 | logger = &Logger{} |
32 | 36 | ||
33 | logger.outputFileName = name + "-log" | 37 | logger.outputFileName = name + "-log" |
34 | logger.mu = &sync.Mutex{} | 38 | logger.mu = &sync.Mutex{} |
35 | logger.maxFileSize = maxFileSize | 39 | logger.maxFileSize = maxFileSize |
36 | 40 | ||
37 | err = os.Mkdir(logDirName, os.ModePerm) | 41 | err = os.Mkdir(logDirName, os.ModePerm) |
38 | if err != nil { | 42 | if err != nil { |
39 | if !os.IsExist(err) { | 43 | if !os.IsExist(err) { |
40 | fmt.Printf("logger: mkdir: couldn't create event log directory\n") | 44 | fmt.Printf("logger: mkdir: couldn't create event log directory\n") |
41 | return nil, err | 45 | return nil, err |
42 | } | 46 | } |
43 | } | 47 | } |
44 | 48 | ||
45 | date := strings.Split(time.Now().Format(time.RFC3339), "T")[0] | 49 | date := strings.Replace(time.Now().Format(time.RFC3339), ":", ".", -1) |
46 | timestamp := "_" + date | 50 | logger.outputFileName += "_" + date + ".txt" |
47 | path := filepath.Join(logDirName, logger.outputFileName+timestamp+".txt") | 51 | path := filepath.Join(logDirName, logger.outputFileName) |
48 | logger.outputFile, err = os.Create(path) | 52 | logger.outputFile, err = os.Create(path) |
49 | if err != nil { | 53 | if err != nil { |
50 | fmt.Printf("logger: new: couldn't create event log file\n") | 54 | fmt.Printf("logger: new: couldn't create event log file\n") |
51 | return nil, err | 55 | return nil, err |
52 | } | 56 | } |
53 | 57 | ||
54 | return logger, nil | 58 | return logger, nil |
55 | } | 59 | } |
56 | 60 | ||
57 | func (logger *Logger) Print(format string, v ...interface{}) { | 61 | func (l *Logger) Print(format string, v ...interface{}) { |
58 | msg := fmt.Sprintf(format, v...) | 62 | msg := fmt.Sprintf(format, v...) |
59 | fmt.Printf(time.Now().Format(time.RFC3339) + ": " + msg + "\n") | 63 | fmt.Printf(time.Now().Format(time.RFC3339) + ": " + msg + "\n") |
60 | } | 64 | } |
61 | 65 | ||
62 | func (logger *Logger) Log(format string, v ...interface{}) { | 66 | func (l *Logger) Log(format string, v ...interface{}) { |
63 | if logger.outputFile != nil { | 67 | if l.outputFile != nil { |
64 | logger.mu.Lock() | 68 | l.mu.Lock() |
65 | defer logger.mu.Unlock() | 69 | defer l.mu.Unlock() |
66 | 70 | ||
67 | msg := fmt.Sprintf(format, v...) | 71 | msg := fmt.Sprintf(format, v...) |
68 | s := time.Now().Format(time.RFC3339) + ": " + msg + "\n" | 72 | s := time.Now().Format(time.RFC3339) + ": " + msg + "\n" |
69 | if logger.shouldSplit(len(s)) { | 73 | if l.shouldSplit(len(s)) { |
70 | logger.split() | 74 | l.split() |
71 | } | 75 | } |
72 | logger.outputFile.WriteString(s) | 76 | l.outputFile.WriteString(s) |
73 | } | 77 | } |
74 | } | 78 | } |
75 | 79 | ||
76 | // TODO(marko) | 80 | func (l *Logger) LogRequest(req *http.Request, userid string) { |
77 | /* | 81 | if l.outputFile != nil { |
78 | func (logger *Logger) LogHTTPRequest(req *http.Request) { | 82 | if userid == "" { |
79 | if logger.outputFile != nil { | 83 | userid = "-" |
80 | logger.mu.Lock() | 84 | } |
81 | defer logger.mu.Unlock() | ||
82 | 85 | ||
83 | msg := fmt.Sprintf(format, v...) | 86 | var b strings.Builder |
84 | if logger.shouldSplit(len(s)) { | 87 | // CLF-like header |
85 | logger.split() | 88 | ts := time.Now().Format(time.RFC3339) |
89 | fmt.Fprintf(&b, "%s - %s [%s] \"%s %s\" %s\n", req.RemoteAddr, userid, ts, req.Method, req.URL.Path, req.Proto) | ||
90 | |||
91 | b.WriteString("\nURL encoded:\n") | ||
92 | for k, v := range req.Form { | ||
93 | fmt.Fprintf(&b, "%s = %s\n", k, v) | ||
94 | } | ||
95 | |||
96 | b.WriteString("\nBody:\n") | ||
97 | buf, err := ioutil.ReadAll(req.Body) | ||
98 | if err == nil { | ||
99 | b.WriteString(string(buf)) | ||
100 | } else { | ||
101 | fmt.Fprintf(os.Stderr, "%v\n", err) | ||
102 | } | ||
103 | b.WriteString("\n\n") | ||
104 | |||
105 | msg := b.String() | ||
106 | //fmt.Println(msg) | ||
107 | |||
108 | l.mu.Lock() | ||
109 | defer l.mu.Unlock() | ||
110 | |||
111 | if l.shouldSplit(len(msg)) { | ||
112 | l.split() | ||
86 | } | 113 | } |
87 | logger.outputFile.WriteString(time.Now().Format(time.RFC3339) + ": " + msg + "\n") | 114 | l.outputFile.WriteString(msg) |
88 | } | 115 | } |
89 | } | 116 | } |
90 | */ | ||
91 | 117 | ||
92 | func (logger *Logger) Trace(format string, v ...interface{}) { | 118 | func (l *Logger) Trace(format string, v ...interface{}) { |
93 | if logger.outputFile != nil { | 119 | if l.outputFile != nil { |
94 | logger.mu.Lock() | 120 | l.mu.Lock() |
95 | defer logger.mu.Unlock() | 121 | defer l.mu.Unlock() |
96 | _, file, line, ok := runtime.Caller(1) | 122 | _, file, line, ok := runtime.Caller(1) |
97 | 123 | ||
98 | s := "" | 124 | s := "" |
99 | msg := fmt.Sprintf(format, v...) | 125 | msg := fmt.Sprintf(format, v...) |
100 | if ok { | 126 | if ok { |
101 | s = fmt.Sprintf("%s: %s %d: %s\n", time.Now().Format(time.RFC3339), file, line, msg) | 127 | s = fmt.Sprintf("%s: %s %d: %s\n", time.Now().Format(time.RFC3339), file, line, msg) |
102 | } else { | 128 | } else { |
103 | s = fmt.Sprintf(time.Now().Format(time.RFC3339) + ": [can't retreive stack details]:" + msg + "\n") | 129 | s = fmt.Sprintf(time.Now().Format(time.RFC3339) + ": [can't retreive stack details]:" + msg + "\n") |
104 | } | 130 | } |
105 | if logger.shouldSplit(len(s)) { | 131 | if l.shouldSplit(len(s)) { |
106 | logger.split() | 132 | l.split() |
107 | } | 133 | } |
108 | logger.outputFile.WriteString(s) | 134 | l.outputFile.WriteString(s) |
109 | } | 135 | } |
110 | } | 136 | } |
111 | 137 | ||
112 | func (logger *Logger) Close() { | 138 | func (l *Logger) Close() { |
113 | if logger.outputFile != nil { | 139 | if l.outputFile != nil { |
114 | err := logger.outputFile.Close() | 140 | err := l.outputFile.Close() |
115 | if err != nil { | 141 | if err != nil { |
116 | fmt.Printf("logger: on exit: couldn't close event log file\n") | 142 | fmt.Printf("logger: on exit: couldn't close event log file\n") |
117 | } | 143 | } |
118 | } | 144 | } |
119 | } | 145 | } |
120 | 146 | ||
121 | func (l *Logger) split() { | 147 | func (l *Logger) split() { |
122 | timestamp := "_" + time.Now().Format(time.RFC3339) | ||
123 | // close old file | 148 | // close old file |
124 | err := l.outputFile.Close() | 149 | err := l.outputFile.Close() |
125 | if err != nil { | 150 | if err != nil { |
126 | fmt.Printf("logger: split: couldn't close event file\n") | 151 | fmt.Printf("logger: split: couldn't close event file\n") |
127 | return | 152 | return |
128 | } | 153 | } |
154 | |||
155 | l.splitCount++ | ||
129 | // open new file | 156 | // open new file |
130 | var errnew error | 157 | var errnew error |
131 | path := filepath.Join(logDirName, l.outputFileName+timestamp) | 158 | path := filepath.Join(logDirName, l.outputFileName+fmt.Sprintf("(%d)", l.splitCount)) |
132 | l.outputFile, errnew = os.Create(path) | 159 | l.outputFile, errnew = os.Create(path) |
133 | 160 | ||
134 | if errnew != nil { | 161 | if errnew != nil { |
135 | fmt.Printf("logger: split: couldn't create event log file\n") | 162 | fmt.Printf("logger: split: couldn't create event log file\n") |
136 | } | 163 | } |
137 | } | 164 | } |
138 | 165 | ||
139 | func (l *Logger) shouldSplit(nextEntrySize int) bool { | 166 | func (l *Logger) shouldSplit(nextEntrySize int) bool { |
140 | stats, _ := l.outputFile.Stat() | 167 | stats, _ := l.outputFile.Stat() |