Data proxy: Log proxy errors using Grafana logger (#22174)

Now any errors logged by http.ReverseProxy are forwarded to 
Grafana's logger and includes more contextual information like
level (error), user id, org id, username, proxy path, referer and 
IP address.

Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
This commit is contained in:
Carl Bergquist 2020-02-18 13:26:01 +01:00 committed by GitHub
parent 08bf2a5452
commit ff9556229a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"net/http/httputil"
@ -17,7 +18,7 @@ import (
"golang.org/x/oauth2"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
glog "github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/login/social"
m "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
@ -26,7 +27,7 @@ import (
)
var (
logger = log.New("data-proxy-log")
logger = glog.New("data-proxy-log")
client = newHTTPClient()
)
@ -57,6 +58,18 @@ type httpClient interface {
Do(req *http.Request) (*http.Response, error)
}
type logWrapper struct {
logger glog.Logger
}
// Write writes log messages as bytes from proxy
func (lw *logWrapper) Write(p []byte) (n int, err error) {
withoutNewline := strings.TrimSuffix(string(p), "\n")
lw.logger.Error("Data proxy error", "error", withoutNewline)
return len(p), nil
}
// NewDataSourceProxy creates a new Datasource proxy
func NewDataSourceProxy(ds *m.DataSource, plugin *plugins.DataSourcePlugin, ctx *m.ReqContext, proxyPath string, cfg *setting.Cfg) *DataSourceProxy {
targetURL, _ := url.Parse(ds.Url)
@ -83,9 +96,12 @@ func (proxy *DataSourceProxy) HandleRequest() {
return
}
proxyErrorLogger := logger.New("userId", proxy.ctx.UserId, "orgId", proxy.ctx.OrgId, "uname", proxy.ctx.Login, "path", proxy.ctx.Req.URL.Path, "remote_addr", proxy.ctx.RemoteAddr(), "referer", proxy.ctx.Req.Referer())
reverseProxy := &httputil.ReverseProxy{
Director: proxy.getDirector(),
FlushInterval: time.Millisecond * 200,
ErrorLog: log.New(&logWrapper{logger: proxyErrorLogger}, "", 0),
}
transport, err := proxy.ds.GetHttpTransport()