Commit df74f4a7ee0b8df78da5b96abc0749b19854ddd0

Authored by Marko Tikvić
1 parent aa60a45eec
Exists in master

new filename format

Showing 1 changed file with 61 additions and 34 deletions   Show diff stats
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()