diff options
author | Andrew Newdigate <andrew@gitlab.com> | 2019-07-24 10:50:11 +0300 |
---|---|---|
committer | Andrew Newdigate <andrew@gitlab.com> | 2019-08-30 18:20:42 +0300 |
commit | 4e80090046d58d8ddd80a38939262a957d6dea1f (patch) | |
tree | aca3cf4db1f57e86946673dc7d0e2b96359a683d /internal/logging | |
parent | 95eb6930f030af0f5f1cecb734dc283d1735e0c6 (diff) |
Add full HTTP metrics and logging to GitLab pages using LabKit
Diffstat (limited to 'internal/logging')
-rw-r--r-- | internal/logging/logging.go | 80 | ||||
-rw-r--r-- | internal/logging/logging_test.go | 54 |
2 files changed, 134 insertions, 0 deletions
diff --git a/internal/logging/logging.go b/internal/logging/logging.go new file mode 100644 index 00000000..f0682573 --- /dev/null +++ b/internal/logging/logging.go @@ -0,0 +1,80 @@ +package logging + +import ( + "net/http" + + "github.com/sirupsen/logrus" + "gitlab.com/gitlab-org/labkit/log" + + "gitlab.com/gitlab-org/gitlab-pages/internal/request" +) + +// ConfigureLogging will initialize the system logger. +func ConfigureLogging(format string, verbose bool) error { + var levelOption log.LoggerOption + + if format == "" { + format = "text" + } + + if verbose { + levelOption = log.WithLogLevel("debug") + } else { + levelOption = log.WithLogLevel("info") + } + + _, err := log.Initialize( + log.WithFormatter(format), + levelOption, + ) + return err +} + +// getAccessLogger will return the default logger, except when +// the log format is text, in which case a combined HTTP access +// logger will be configured. This behaviour matches Workhorse +func getAccessLogger(format string) (*logrus.Logger, error) { + if format != "text" && format != "" { + return logrus.StandardLogger(), nil + } + + accessLogger := log.New() + _, err := log.Initialize( + log.WithLogger(accessLogger), // Configure `accessLogger` + log.WithFormatter("combined"), // Use the combined formatter + ) + if err != nil { + return nil, err + } + + return accessLogger, nil +} + +// getExtraLogFields is used to inject additional fields into the +// HTTP access logger middleware. +func getExtraLogFields(r *http.Request) log.Fields { + var projectID uint64 + if d := request.GetDomain(r); d != nil { + projectID = d.GetID(r) + } + + return log.Fields{ + "pages_https": request.IsHTTPS(r), + "pages_host": request.GetHost(r), + "pages_project_id": projectID, + } +} + +// AccessLogger configures the GitLab pages HTTP access logger middleware +func AccessLogger(handler http.Handler, format string) (http.Handler, error) { + + accessLogger, err := getAccessLogger(format) + if err != nil { + return nil, err + } + + return log.AccessLogger(handler, + log.WithExtraFields(getExtraLogFields), + log.WithAccessLogger(accessLogger), + ), nil +} diff --git a/internal/logging/logging_test.go b/internal/logging/logging_test.go new file mode 100644 index 00000000..dd3bd831 --- /dev/null +++ b/internal/logging/logging_test.go @@ -0,0 +1,54 @@ +package logging + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/require" + + "gitlab.com/gitlab-org/gitlab-pages/internal/domain" + "gitlab.com/gitlab-org/gitlab-pages/internal/request" +) + +func TestGetExtraLogFields(t *testing.T) { + tests := []struct { + name string + https bool + host string + domain *domain.D + }{ + { + name: "https", + https: true, + host: "githost.io", + domain: &domain.D{}, + }, + { + name: "http", + https: false, + host: "githost.io", + domain: &domain.D{}, + }, + { + name: "no_domain", + https: false, + host: "githost.io", + domain: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + req, err := http.NewRequest("GET", "/", nil) + require.NoError(t, err) + + req = request.WithHTTPSFlag(req, tt.https) + req = request.WithHostAndDomain(req, tt.host, tt.domain) + + got := getExtraLogFields(req) + require.Equal(t, got["pages_https"], tt.https) + require.Equal(t, got["pages_host"], tt.host) + require.Equal(t, got["pages_project_id"], 0) + }) + } +} |