1// Copyright 2013 Martini Authors
2// Copyright 2014 Unknwon
3//
4// Licensed under the Apache License, Version 2.0 (the "License"): you may
5// not use this file except in compliance with the License. You may obtain
6// a copy of the License at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13// License for the specific language governing permissions and limitations
14// under the License.
15
16package middleware
17
18import (
19	"net/http"
20	"time"
21
22	"github.com/grafana/grafana/pkg/services/contexthandler"
23	"github.com/grafana/grafana/pkg/setting"
24	"github.com/grafana/grafana/pkg/web"
25	cw "github.com/weaveworks/common/tracing"
26)
27
28func Logger(cfg *setting.Cfg) web.Handler {
29	return func(res http.ResponseWriter, req *http.Request, c *web.Context) {
30		start := time.Now()
31
32		rw := res.(web.ResponseWriter)
33		c.Next()
34
35		timeTaken := time.Since(start) / time.Millisecond
36
37		ctx := contexthandler.FromContext(c.Req.Context())
38		if ctx != nil && ctx.PerfmonTimer != nil {
39			ctx.PerfmonTimer.Observe(float64(timeTaken))
40		}
41
42		status := rw.Status()
43		if status == 200 || status == 304 {
44			if !cfg.RouterLogging {
45				return
46			}
47		}
48
49		if ctx != nil {
50			logParams := []interface{}{
51				"method", req.Method,
52				"path", req.URL.Path,
53				"status", status,
54				"remote_addr", c.RemoteAddr(),
55				"time_ms", int64(timeTaken),
56				"size", rw.Size(),
57				"referer", req.Referer(),
58			}
59
60			traceID, exist := cw.ExtractTraceID(ctx.Req.Context())
61			if exist {
62				logParams = append(logParams, "traceID", traceID)
63			}
64
65			if status >= 500 {
66				ctx.Logger.Error("Request Completed", logParams...)
67			} else {
68				ctx.Logger.Info("Request Completed", logParams...)
69			}
70		}
71	}
72}
73