aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclsr <clsr@clsr.net>2016-11-15 15:17:45 +0100
committerclsr <clsr@clsr.net>2016-11-15 19:28:43 +0100
commit1e55e61786eaedd59c067f4306fb8427dc92ef52 (patch)
treec24521f8d70d39508b4ed751c60e0f79891bfa48
parent1583e219cd6eda19c3e7158950e5be9c87d9a8de (diff)
downloadgomf-1e55e61786eaedd59c067f4306fb8427dc92ef52.tar.gz
gomf-1e55e61786eaedd59c067f4306fb8427dc92ef52.zip
Add logging support
-rw-r--r--api.go3
-rw-r--r--log.go138
-rw-r--r--main.go20
3 files changed, 160 insertions, 1 deletions
diff --git a/api.go b/api.go
index 49b8a61..464d110 100644
--- a/api.go
+++ b/api.go
@@ -67,7 +67,7 @@ func handleUpload(w http.ResponseWriter, r *http.Request) {
output := r.FormValue("output")
resp := response{Files: []result{}}
- if r.Method == http.MethodGet && output == "html" {
+ if r.Method == http.MethodGet && (output == "html" || output == "") {
respond(w, output, resp)
return
}
@@ -113,6 +113,7 @@ func handleUpload(w http.ResponseWriter, r *http.Request) {
Hash: hex.EncodeToString(bhash),
Size: size,
}
+ LogUpload(r, res)
resp.Files = append(resp.Files, res)
part.Close()
diff --git a/log.go b/log.go
new file mode 100644
index 0000000..f2305ce
--- /dev/null
+++ b/log.go
@@ -0,0 +1,138 @@
+package main
+
+import (
+ "crypto/sha1"
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "net"
+ "net/http"
+ "os"
+ "path"
+ "sync"
+ "time"
+)
+
+type Logger struct {
+ LogDir string
+ LogIP bool
+ LogUserAgent bool
+ LogReferer bool
+ HashIP bool
+ HashUserAgent bool
+ HashReferer bool
+ HashSalt string
+ logFile *os.File
+ encoder *json.Encoder
+ lastDate string
+ lock sync.Mutex
+}
+
+type LogEntry map[string]interface{}
+
+func InitLogger(logdir string) *Logger {
+ return &Logger{
+ LogDir: logdir,
+ }
+}
+
+func (l *Logger) Log(entry LogEntry) {
+ l.lock.Lock()
+ defer l.lock.Unlock()
+ _, err := l.getLogFile()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "error opening log file: %s\n", err)
+ return
+ }
+ err = l.encoder.Encode(entry)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "error writing to log: %s\n", err)
+ }
+}
+
+func (l *Logger) LogUpload(req *http.Request, res result) {
+ host, _, _ := net.SplitHostPort(req.RemoteAddr)
+ l.logUpload(
+ host, // ip
+ req.UserAgent(), // userAgent
+ req.Referer(), // referer
+ res.Name, // origName
+ path.Base(res.Url), // idext
+ res.Hash, // hash
+ res.Size, // size
+ )
+}
+
+func (l *Logger) logUpload(ip, userAgent, referer, origName, idext, hash string, size int64) {
+ if !l.LogIP {
+ ip = ""
+ } else if l.HashIP {
+ ip = l.hash(ip)
+ }
+ if !l.LogUserAgent {
+ userAgent = ""
+ } else if l.HashUserAgent {
+ userAgent = l.hash(userAgent)
+ }
+ if !l.LogReferer {
+ referer = ""
+ } else if l.HashReferer {
+ referer = l.hash(referer)
+ }
+ l.Log(LogEntry{
+ "type": "upload",
+ "timestamp": time.Now().UTC().Format(time.RFC3339),
+ "ip": ip,
+ "user_agent": userAgent,
+ "referer": referer,
+ "orig_name": origName,
+ "id": idext,
+ "hash": hash,
+ "size": size,
+ })
+}
+
+func (l *Logger) hash(s string) string {
+ h := sha1.New()
+ h.Write([]byte(l.HashSalt))
+ h.Write([]byte(s))
+ h.Write([]byte(l.HashSalt))
+ return base64.RawURLEncoding.EncodeToString(h.Sum(nil))
+}
+
+func (l *Logger) getLogFile() (*os.File, error) {
+ if l.lastDate == "" {
+ if err := os.MkdirAll(l.LogDir, 0755); err != nil {
+ return nil, err
+ }
+ }
+ currentDate := time.Now().UTC().Format("2006-01-02")
+ if l.lastDate == currentDate {
+ return l.logFile, nil
+ }
+ f, err := os.OpenFile(path.Join(l.LogDir, currentDate+".log.json"), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
+ if err != nil {
+ return f, err
+ }
+ if l.logFile != nil {
+ l.logFile.Close()
+ }
+ l.lastDate = currentDate
+ l.logFile = f
+ l.encoder = json.NewEncoder(f)
+ return f, nil
+}
+
+var DefaultLogger = InitLogger("log")
+
+func Log(entry LogEntry) {
+ if DefaultLogger != nil {
+ DefaultLogger.Log(entry)
+ }
+}
+
+func LogUpload(req *http.Request, res result) {
+ if DefaultLogger != nil {
+ DefaultLogger.LogUpload(req, res)
+ }
+}
diff --git a/main.go b/main.go
index 40dae35..d66416f 100644
--- a/main.go
+++ b/main.go
@@ -76,6 +76,14 @@ func main() {
grill := flag.Bool("grill", false, "enable grills")
idLength := flag.Int("id-length", DefaultIdLength, "length of uploaded file IDs")
idCharset := flag.String("id-charset", "", "charset for uploaded file IDs (default lowercase letters a-z)")
+ enableLog := flag.Bool("log", false, "enable logging")
+ logIP := flag.Bool("log-ip", false, "log IP addresses")
+ logIPHash := flag.Bool("log-ip-hash", false, "log hashed IP addresses")
+ logUA := flag.Bool("log-ua", false, "log User-Agent headers")
+ logUAHash := flag.Bool("log-ua-hash", false, "log hashed User-Agent headers")
+ logReferer := flag.Bool("log-referer", false, "log Referer headers")
+ logRefererHash := flag.Bool("log-referer-hash", false, "log hashed Referer headers")
+ logHashSalt := flag.String("log-hash-salt", "", "salt to use for hashed log entries")
flag.Parse()
@@ -96,6 +104,18 @@ func main() {
storage.IdCharset = *idCharset
}
+ if !*enableLog {
+ DefaultLogger = nil
+ } else {
+ DefaultLogger.LogIP = *logIP || *logIPHash
+ DefaultLogger.LogUserAgent = *logUA || *logUAHash
+ DefaultLogger.LogReferer = *logReferer || *logRefererHash
+ DefaultLogger.HashIP = *logIPHash
+ DefaultLogger.HashUserAgent = *logUAHash
+ DefaultLogger.HashReferer = *logRefererHash
+ DefaultLogger.HashSalt = *logHashSalt
+ }
+
http.HandleFunc("/upload.php", handleUpload)
http.Handle("/u/", http.StripPrefix("/u/", http.HandlerFunc(handleFile)))
if *grill {