Blame view

main.go 3.95 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
  )
434e7da25   Marko Tikvić   changed initializ...
14
15
16
17
18
19
  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...
20
  	logDirName            = "log"
434e7da25   Marko Tikvić   changed initializ...
21
  )
a99c98307   Marko Tikvić   first commit
22

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

98cf2ceeb   Marko Tikvić   new interaface; a...
27
28
  	outputFileName string
  	maxFileSize    int64
df74f4a7e   Marko Tikvić   new filename format
29
30
  
  	splitCount int
a99c98307   Marko Tikvić   first commit
31
  }
98cf2ceeb   Marko Tikvić   new interaface; a...
32
  func New(name string, maxFileSize int64) (logger *Logger, err error) {
5eaa49d2a   Marko Tikvić   new design; allow...
33
  	logger = &Logger{}
23ce66f0f   Marko Tikvić   optional init par...
34

98cf2ceeb   Marko Tikvić   new interaface; a...
35
36
37
  	logger.outputFileName = name + "-log"
  	logger.mu = &sync.Mutex{}
  	logger.maxFileSize = maxFileSize
a99c98307   Marko Tikvić   first commit
38

98cf2ceeb   Marko Tikvić   new interaface; a...
39
40
41
42
43
  	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...
44
  			return nil, err
a99c98307   Marko Tikvić   first commit
45
46
  		}
  	}
df74f4a7e   Marko Tikvić   new filename format
47
48
49
  	date := strings.Replace(time.Now().Format(time.RFC3339), ":", ".", -1)
  	logger.outputFileName += "_" + date + ".txt"
  	path := filepath.Join(logDirName, logger.outputFileName)
98cf2ceeb   Marko Tikvić   new interaface; a...
50
51
52
53
54
  	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...
55
  	}
5eaa49d2a   Marko Tikvić   new design; allow...
56
  	return logger, nil
98708cdaf   Marko Tikvić   new version, does...
57
  }
df74f4a7e   Marko Tikvić   new filename format
58
  func (l *Logger) Print(format string, v ...interface{}) {
98cf2ceeb   Marko Tikvić   new interaface; a...
59
60
61
  	msg := fmt.Sprintf(format, v...)
  	fmt.Printf(time.Now().Format(time.RFC3339) + ": " + msg + "
  ")
327c98634   Marko Tikvić   added Print() for...
62
  }
df74f4a7e   Marko Tikvić   new filename format
63
  func (l *Logger) Log(format string, v ...interface{}) {
372beaf62   Marko Tikvić   refactored if sta...
64
65
66
67
68
69
70
71
72
73
74
75
  	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...
76
  	}
372beaf62   Marko Tikvić   refactored if sta...
77
  	l.outputFile.WriteString(s)
98708cdaf   Marko Tikvić   new version, does...
78
  }
372beaf62   Marko Tikvić   refactored if sta...
79
80
81
82
  func (l *Logger) RequestLog(req *http.Request, userid string) string {
  	if l.outputFile == nil {
  		return ""
  	}
98cf2ceeb   Marko Tikvić   new interaface; a...
83

372beaf62   Marko Tikvić   refactored if sta...
84
85
86
  	if userid == "" {
  		userid = "-"
  	}
df74f4a7e   Marko Tikvić   new filename format
87

372beaf62   Marko Tikvić   refactored if sta...
88
89
90
91
92
93
94
  	var b strings.Builder
  	b.WriteString("Request:
  ")
  	// CLF-like header
  	ts := time.Now().Format(time.RFC3339)
  	fmt.Fprintf(&b, "%s %s
  ", req.RemoteAddr, ts)
cccb4b47c   Marko Tikvić   log http response
95

372beaf62   Marko Tikvić   refactored if sta...
96
97
98
99
100
101
102
103
104
105
  	body, err := httputil.DumpRequest(req, true)
  	if err != nil {
  		fmt.Fprintf(os.Stderr, "%v
  ", err)
  	} else {
  		b.WriteString(string(body))
  	}
  	b.WriteString("
  
  ")
cccb4b47c   Marko Tikvić   log http response
106

372beaf62   Marko Tikvić   refactored if sta...
107
108
109
110
  	msg := b.String()
  
  	return msg
  }
ed6549a33   Marko Tikvić   minor output form...
111
  func (l *Logger) ResponseLog(status int, duration time.Duration, size int64) string {
372beaf62   Marko Tikvić   refactored if sta...
112
113
  	if l.outputFile == nil {
  		return ""
cccb4b47c   Marko Tikvić   log http response
114
  	}
372beaf62   Marko Tikvić   refactored if sta...
115
116
  
  	var b strings.Builder
ed6549a33   Marko Tikvić   minor output form...
117
118
119
120
121
  	fmt.Fprintf(&b, "Response:
  %d %v %dB
  ", status, duration, size)
  	b.WriteString("==============================================================
  ")
372beaf62   Marko Tikvić   refactored if sta...
122
123
124
  	msg := b.String()
  
  	return msg
cccb4b47c   Marko Tikvić   log http response
125
  }
372beaf62   Marko Tikvić   refactored if sta...
126
127
128
129
  func (l *Logger) LogHTTPTraffic(in string, out string) {
  	if l.outputFile == nil {
  		return
  	}
df74f4a7e   Marko Tikvić   new filename format
130

372beaf62   Marko Tikvić   refactored if sta...
131
  	msg := in + out
df74f4a7e   Marko Tikvić   new filename format
132

372beaf62   Marko Tikvić   refactored if sta...
133
134
135
136
137
  	l.mu.Lock()
  	defer l.mu.Unlock()
  
  	if l.shouldSplit(len(msg)) {
  		l.split()
98708cdaf   Marko Tikvić   new version, does...
138
  	}
372beaf62   Marko Tikvić   refactored if sta...
139
  	l.outputFile.WriteString(msg)
98708cdaf   Marko Tikvić   new version, does...
140
  }
df74f4a7e   Marko Tikvić   new filename format
141
  func (l *Logger) Trace(format string, v ...interface{}) {
372beaf62   Marko Tikvić   refactored if sta...
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
  	if l.outputFile == nil {
  		return
  	}
  
  	l.mu.Lock()
  	defer l.mu.Unlock()
  	_, file, line, ok := runtime.Caller(1)
  
  	s := ""
  	msg := fmt.Sprintf(format, v...)
  	if ok {
  		s = fmt.Sprintf("%s: %s %d: %s
  ", time.Now().Format(time.RFC3339), file, line, msg)
  	} else {
  		s = fmt.Sprintf(time.Now().Format(time.RFC3339) + ": [can't retreive stack details]:" + msg + "
  ")
98708cdaf   Marko Tikvić   new version, does...
158
  	}
372beaf62   Marko Tikvić   refactored if sta...
159
160
161
162
  	if l.shouldSplit(len(s)) {
  		l.split()
  	}
  	l.outputFile.WriteString(s)
a99c98307   Marko Tikvić   first commit
163
  }
df74f4a7e   Marko Tikvić   new filename format
164
  func (l *Logger) Close() {
372beaf62   Marko Tikvić   refactored if sta...
165
166
167
168
169
170
171
172
  	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
173
  	}
a99c98307   Marko Tikvić   first commit
174
  }
98cf2ceeb   Marko Tikvić   new interaface; a...
175
  func (l *Logger) split() {
372beaf62   Marko Tikvić   refactored if sta...
176
177
178
  	if l.outputFile == nil {
  		return
  	}
98cf2ceeb   Marko Tikvić   new interaface; a...
179
180
181
182
183
184
185
  	// 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
186
187
  
  	l.splitCount++
98cf2ceeb   Marko Tikvić   new interaface; a...
188
189
  	// open new file
  	var errnew error
df74f4a7e   Marko Tikvić   new filename format
190
  	path := filepath.Join(logDirName, l.outputFileName+fmt.Sprintf("(%d)", l.splitCount))
98cf2ceeb   Marko Tikvić   new interaface; a...
191
  	l.outputFile, errnew = os.Create(path)
a99c98307   Marko Tikvić   first commit
192

98cf2ceeb   Marko Tikvić   new interaface; a...
193
194
195
  	if errnew != nil {
  		fmt.Printf("logger: split: couldn't create event log file
  ")
a99c98307   Marko Tikvić   first commit
196
197
  	}
  }
98cf2ceeb   Marko Tikvić   new interaface; a...
198
199
200
  func (l *Logger) shouldSplit(nextEntrySize int) bool {
  	stats, _ := l.outputFile.Stat()
  	return int64(nextEntrySize) >= (l.maxFileSize - stats.Size())
a99c98307   Marko Tikvić   first commit
201
  }