Blame view

main.go 4.25 KB
a99c98307   Marko Tikvić   first commit
1
2
3
4
  package gologger
  
  import (
  	"fmt"
df74f4a7e   Marko Tikvić   new filename format
5
  	"net/http"
cccb4b47c   Marko Tikvić   log http response
6
  	"net/http/httputil"
a99c98307   Marko Tikvić   first commit
7
  	"os"
e025a8738   Marko Tikvić   platform agnostic...
8
  	"path/filepath"
98708cdaf   Marko Tikvić   new version, does...
9
  	"runtime"
aa60a45ee   Marko Tikvić   changed log file ...
10
  	"strings"
3ba7b5695   Marko Tikvić   added mutex locks...
11
  	"sync"
baa4468b7   Marko Tikvić   Comments go befor...
12
  	"time"
a99c98307   Marko Tikvić   first commit
13
  )
92485819d   Marko Tikvić   lint
14
  // Block ...
434e7da25   Marko Tikvić   changed initializ...
15
16
17
18
19
20
  const (
  	MaxLogSize5MB   int64 = 5 * 1024 * 1024
  	MaxLogSize1MB   int64 = 1 * 1024 * 1024
  	MaxLogSize500KB int64 = 500 * 1024
  	MaxLogSize100KB int64 = 100 * 1024
  	MaxLogSize512B  int64 = 512
98cf2ceeb   Marko Tikvić   new interaface; a...
21
  	logDirName            = "log"
434e7da25   Marko Tikvić   changed initializ...
22
  )
a99c98307   Marko Tikvić   first commit
23

92485819d   Marko Tikvić   lint
24
  // Logger ...
5eaa49d2a   Marko Tikvić   new design; allow...
25
  type Logger struct {
98cf2ceeb   Marko Tikvić   new interaface; a...
26
27
  	mu         *sync.Mutex
  	outputFile *os.File
23ce66f0f   Marko Tikvić   optional init par...
28

98cf2ceeb   Marko Tikvić   new interaface; a...
29
  	outputFileName string
3e936a3c2   Marko Tikvić   output file name ...
30
  	fullName       string
98cf2ceeb   Marko Tikvić   new interaface; a...
31
  	maxFileSize    int64
df74f4a7e   Marko Tikvić   new filename format
32
33
  
  	splitCount int
a99c98307   Marko Tikvić   first commit
34
  }
92485819d   Marko Tikvić   lint
35
  // New ...
98cf2ceeb   Marko Tikvić   new interaface; a...
36
  func New(name string, maxFileSize int64) (logger *Logger, err error) {
5eaa49d2a   Marko Tikvić   new design; allow...
37
  	logger = &Logger{}
23ce66f0f   Marko Tikvić   optional init par...
38

98cf2ceeb   Marko Tikvić   new interaface; a...
39
40
41
  	logger.outputFileName = name + "-log"
  	logger.mu = &sync.Mutex{}
  	logger.maxFileSize = maxFileSize
a99c98307   Marko Tikvić   first commit
42

98cf2ceeb   Marko Tikvić   new interaface; a...
43
44
45
46
47
  	err = os.Mkdir(logDirName, os.ModePerm)
  	if err != nil {
  		if !os.IsExist(err) {
  			fmt.Printf("logger: mkdir: couldn't create event log directory
  ")
5eaa49d2a   Marko Tikvić   new design; allow...
48
  			return nil, err
a99c98307   Marko Tikvić   first commit
49
50
  		}
  	}
df74f4a7e   Marko Tikvić   new filename format
51
  	date := strings.Replace(time.Now().Format(time.RFC3339), ":", ".", -1)
3e936a3c2   Marko Tikvić   output file name ...
52
53
54
  	logger.outputFileName += "_" + date
  	logger.fullName = logger.outputFileName + ".txt"
  	path := filepath.Join(logDirName, logger.fullName)
98cf2ceeb   Marko Tikvić   new interaface; a...
55
56
57
58
59
  	logger.outputFile, err = os.Create(path)
  	if err != nil {
  		fmt.Printf("logger: new: couldn't create event log file
  ")
  		return nil, err
e025a8738   Marko Tikvić   platform agnostic...
60
  	}
5eaa49d2a   Marko Tikvić   new design; allow...
61
  	return logger, nil
98708cdaf   Marko Tikvić   new version, does...
62
  }
92485819d   Marko Tikvić   lint
63
  // Log ...
df74f4a7e   Marko Tikvić   new filename format
64
  func (l *Logger) Log(format string, v ...interface{}) {
372beaf62   Marko Tikvić   refactored if sta...
65
66
67
68
69
70
71
72
73
74
75
76
  	if l.outputFile == nil {
  		return
  	}
  
  	l.mu.Lock()
  	defer l.mu.Unlock()
  
  	msg := fmt.Sprintf(format, v...)
  	s := time.Now().Format(time.RFC3339) + ": " + msg + "
  "
  	if l.shouldSplit(len(s)) {
  		l.split()
23ce66f0f   Marko Tikvić   optional init par...
77
  	}
372beaf62   Marko Tikvić   refactored if sta...
78
  	l.outputFile.WriteString(s)
98708cdaf   Marko Tikvić   new version, does...
79
  }
92485819d   Marko Tikvić   lint
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
  // Print ...
  func (l *Logger) Print(format string, v ...interface{}) {
  	msg := fmt.Sprintf(format, v...)
  	fmt.Printf("%s: %s
  ", time.Now().Format(time.RFC3339), msg)
  }
  
  // PrintTrace ...
  func (l *Logger) PrintTrace(format string, v ...interface{}) {
  	_, file, line, _ := runtime.Caller(1)
  
  	msg := fmt.Sprintf(format, v...)
  	fmt.Printf("%s: %s %d: %s
  ", time.Now().Format(time.RFC3339), file, line, msg)
  }
  
  // Trace ...
  func (l *Logger) Trace(format string, v ...interface{}) {
  	if l.outputFile == nil {
  		return
  	}
  
  	l.mu.Lock()
  	defer l.mu.Unlock()
  
  	_, file, line, _ := runtime.Caller(1)
  	msg := fmt.Sprintf(format, v...)
  	s := fmt.Sprintf("%s: %s %d: %s
  ", time.Now().Format(time.RFC3339), file, line, msg)
  
  	if l.shouldSplit(len(s)) {
  		l.split()
  	}
  	l.outputFile.WriteString(s)
  }
  
  // PrintAndTrace ...
  func (l *Logger) PrintAndTrace(format string, v ...interface{}) {
  	l.Print(format, v)
  	l.Trace(format, v)
  }
  
  // LogHTTPRequest ...
093191eb2   Marko Tikvić   much cleaner, muc...
123
  func (l *Logger) LogHTTPRequest(req *http.Request, userID string) string {
1f7fbc601   Marko Tikvić   logging user ID
124
125
  	if userID == "" {
  		userID = "-"
372beaf62   Marko Tikvić   refactored if sta...
126
  	}
df74f4a7e   Marko Tikvić   new filename format
127

372beaf62   Marko Tikvić   refactored if sta...
128
  	var b strings.Builder
093191eb2   Marko Tikvić   much cleaner, muc...
129

372beaf62   Marko Tikvić   refactored if sta...
130
131
132
  	b.WriteString("Request:
  ")
  	// CLF-like header
093191eb2   Marko Tikvić   much cleaner, muc...
133
134
  	fmt.Fprintf(&b, "%s %s %s
  ", req.RemoteAddr, userID, time.Now().Format(time.RFC3339))
cccb4b47c   Marko Tikvić   log http response
135

093191eb2   Marko Tikvić   much cleaner, muc...
136
137
138
139
  	body, err := httputil.DumpRequest(req, true)
  	if err != nil {
  		fmt.Fprintf(os.Stderr, "%v
  ", err)
cccb4b47c   Marko Tikvić   log http response
140
  	}
093191eb2   Marko Tikvić   much cleaner, muc...
141
142
143
  	b.WriteString(string(body) + "
  
  ")
372beaf62   Marko Tikvić   refactored if sta...
144

093191eb2   Marko Tikvić   much cleaner, muc...
145
146
  	return b.String()
  }
372beaf62   Marko Tikvić   refactored if sta...
147

feba66094   Marko Tikvić   split line constant
148
  const splitLine = "=============================================================="
92485819d   Marko Tikvić   lint
149
  // LogHTTPResponse ...
093191eb2   Marko Tikvić   much cleaner, muc...
150
  func (l *Logger) LogHTTPResponse(status int, duration time.Duration, size int) string {
feba66094   Marko Tikvić   split line constant
151
152
153
154
  	return fmt.Sprintf("Response:
  %d %v %dB
  %s
  ", status, duration, size, splitLine)
cccb4b47c   Marko Tikvić   log http response
155
  }
92485819d   Marko Tikvić   lint
156
  // CombineHTTPLogs ...
093191eb2   Marko Tikvić   much cleaner, muc...
157
  func (l *Logger) CombineHTTPLogs(in string, out string) {
372beaf62   Marko Tikvić   refactored if sta...
158
159
160
  	if l.outputFile == nil {
  		return
  	}
df74f4a7e   Marko Tikvić   new filename format
161

372beaf62   Marko Tikvić   refactored if sta...
162
163
  	l.mu.Lock()
  	defer l.mu.Unlock()
093191eb2   Marko Tikvić   much cleaner, muc...
164
  	msg := in + out
372beaf62   Marko Tikvić   refactored if sta...
165
166
  	if l.shouldSplit(len(msg)) {
  		l.split()
98708cdaf   Marko Tikvić   new version, does...
167
  	}
372beaf62   Marko Tikvić   refactored if sta...
168
  	l.outputFile.WriteString(msg)
98708cdaf   Marko Tikvić   new version, does...
169
  }
92485819d   Marko Tikvić   lint
170
  // Close ...
df74f4a7e   Marko Tikvić   new filename format
171
  func (l *Logger) Close() {
372beaf62   Marko Tikvić   refactored if sta...
172
173
174
175
176
177
178
179
  	if l.outputFile == nil {
  		return
  	}
  
  	err := l.outputFile.Close()
  	if err != nil {
  		fmt.Printf("logger: on exit: couldn't close event log file
  ")
a99c98307   Marko Tikvić   first commit
180
  	}
a99c98307   Marko Tikvić   first commit
181
  }
98cf2ceeb   Marko Tikvić   new interaface; a...
182
  func (l *Logger) split() {
372beaf62   Marko Tikvić   refactored if sta...
183
184
185
  	if l.outputFile == nil {
  		return
  	}
98cf2ceeb   Marko Tikvić   new interaface; a...
186
187
188
189
190
191
192
  	// close old file
  	err := l.outputFile.Close()
  	if err != nil {
  		fmt.Printf("logger: split: couldn't close event file
  ")
  		return
  	}
df74f4a7e   Marko Tikvić   new filename format
193
194
  
  	l.splitCount++
98cf2ceeb   Marko Tikvić   new interaface; a...
195
196
  	// open new file
  	var errnew error
3e936a3c2   Marko Tikvić   output file name ...
197
  	path := filepath.Join(logDirName, l.outputFileName+fmt.Sprintf("(%d)", l.splitCount)+".txt")
98cf2ceeb   Marko Tikvić   new interaface; a...
198
  	l.outputFile, errnew = os.Create(path)
a99c98307   Marko Tikvić   first commit
199

98cf2ceeb   Marko Tikvić   new interaface; a...
200
201
202
  	if errnew != nil {
  		fmt.Printf("logger: split: couldn't create event log file
  ")
a99c98307   Marko Tikvić   first commit
203
204
  	}
  }
98cf2ceeb   Marko Tikvić   new interaface; a...
205
206
207
  func (l *Logger) shouldSplit(nextEntrySize int) bool {
  	stats, _ := l.outputFile.Stat()
  	return int64(nextEntrySize) >= (l.maxFileSize - stats.Size())
a99c98307   Marko Tikvić   first commit
208
  }
92485819d   Marko Tikvić   lint
209