Welcome to mirror list, hosted at ThFree Co, Russian Federation.

logging.go - gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c2980503ed8d571cda54331ee4311158a4af8b31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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
package main

import (
	"fmt"
	"net/http"
	"net/url"
	"time"

	log "github.com/sirupsen/logrus"
)

var (
	accessLogFormat = "text"
	logrusEntry     = log.WithField("system", "http")
)

func configureLogging(format string, verbose bool) {
	if verbose {
		log.SetLevel(log.DebugLevel)
	}

	switch format {
	case "json":
		log.SetFormatter(&log.JSONFormatter{})
		accessLogFormat = "json"
	default:
		log.SetFormatter(&log.TextFormatter{})
		accessLogFormat = "text"
	}
}

type loggingResponseWriter struct {
	rw      http.ResponseWriter
	status  int
	written int64
	started time.Time
}

func newLoggingResponseWriter(rw http.ResponseWriter) loggingResponseWriter {
	return loggingResponseWriter{
		rw:      rw,
		started: time.Now(),
	}
}

func (l *loggingResponseWriter) Header() http.Header {
	return l.rw.Header()
}

func (l *loggingResponseWriter) Write(data []byte) (n int, err error) {
	if l.status == 0 {
		l.WriteHeader(http.StatusOK)
	}
	n, err = l.rw.Write(data)
	l.written += int64(n)
	return
}

func (l *loggingResponseWriter) WriteHeader(status int) {
	if l.status != 0 {
		return
	}

	l.status = status
	l.rw.WriteHeader(status)
}

func (l *loggingResponseWriter) extractLogFields(r *http.Request) log.Fields {
	referer := r.Referer()
	parsedReferer, err := url.Parse(referer)

	// The referer query string may contain credentials, so remove if possible
	if err == nil {
		parsedReferer.RawQuery = ""
		referer = parsedReferer.String()
	}

	return log.Fields{
		"host":       r.Host,
		"remoteAddr": r.RemoteAddr,
		"method":     r.Method,
		"uri":        r.URL.Path, //The request query string may contain credentials
		"proto":      r.Proto,
		"status":     l.status,
		"written":    l.written,
		"referer":    referer,
		"userAgent":  r.UserAgent(),
		"duration":   time.Since(l.started).Seconds(),
	}
}

func (l *loggingResponseWriter) Log(r *http.Request) {
	fields := l.extractLogFields(r)

	switch accessLogFormat {
	case "text":
		fmt.Printf("%s %s - - [%s] %q %d %d %q %q %f\n",
			fields["host"], fields["remoteAddr"], l.started,
			fmt.Sprintf("%s %s %s", fields["method"], fields["uri"], fields["proto"]),
			fields["status"], fields["written"], fields["referer"], fields["userAgent"], fields["duration"],
		)
	case "json":
		logrusEntry.WithFields(fields).Info("access")
	default:
		panic("invalid access log format")
	}
}

func fatal(err error) {
	log.WithError(err).Fatal()
}