influxdb/query/logging.go

69 lines
1.6 KiB
Go

package query
import (
"context"
"fmt"
"io"
"runtime/debug"
"time"
"github.com/influxdata/flux"
"github.com/influxdata/flux/iocounter"
"github.com/influxdata/influxdb/kit/check"
"github.com/influxdata/influxdb/kit/tracing"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
// LoggingProxyQueryService wraps a ProxyQueryService and logs the queries.
type LoggingProxyQueryService struct {
ProxyQueryService ProxyQueryService
QueryLogger Logger
NowFunction func() time.Time
Logger *zap.Logger
}
// Query executes and logs the query.
func (s *LoggingProxyQueryService) Query(ctx context.Context, w io.Writer, req *ProxyRequest) (stats flux.Statistics, err error) {
span, ctx := tracing.StartSpanFromContext(ctx)
defer span.Finish()
var n int64
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
if entry := s.Logger.Check(zapcore.InfoLevel, "QueryLogging panic"); entry != nil {
entry.Stack = string(debug.Stack())
entry.Write(zap.Error(err))
}
}
var now time.Time
if s.NowFunction != nil {
now = s.NowFunction()
} else {
now = time.Now()
}
log := Log{
OrganizationID: req.Request.OrganizationID,
ProxyRequest: req,
ResponseSize: n,
Time: now,
Statistics: stats,
Error: err,
}
s.QueryLogger.Log(log)
}()
wc := &iocounter.Writer{Writer: w}
stats, err = s.ProxyQueryService.Query(ctx, wc, req)
if err != nil {
return stats, tracing.LogError(span, err)
}
n = wc.Count()
return stats, nil
}
func (s *LoggingProxyQueryService) Check(ctx context.Context) check.Response {
return s.ProxyQueryService.Check(ctx)
}