From 3cb34f8ec86a0b565d1c9541748d4e6f7543047b Mon Sep 17 00:00:00 2001 From: vlastahajek Date: Thu, 13 Aug 2020 16:23:59 +0200 Subject: [PATCH] feat: public log API with ability to disable logging --- CHANGELOG.md | 1 + api/query.go | 3 + api/write.go | 18 ++--- api/write_test.go | 8 +-- client.go | 9 ++- internal/http/service.go | 4 +- internal/log/logger.go | 65 ++++++++---------- internal/log/logger_test.go | 51 ++++++++++++++ internal/write/service.go | 20 +++--- log/logger.go | 102 ++++++++++++++++++++++++++++ log/logger_test.go | 132 ++++++++++++++++++++++++++++++++++++ options.go | 11 ++- 12 files changed, 357 insertions(+), 67 deletions(-) create mode 100644 internal/log/logger_test.go create mode 100644 log/logger.go create mode 100644 log/logger_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 46216164..93549de4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ### Features 1. [#165](https://github.com/influxdata/influxdb-client-go/pull/165) Allow overriding the http.Client for the http service. +1. [#180](https://github.com/influxdata/influxdb-client-go/pull/180) Provided public logger API to enable overriding logging. It is also possible to disable logging. ### Bug fixes 1. [#175](https://github.com/influxdata/influxdb-client-go/pull/175) Fixed WriteAPIs management. Keeping single instance for each org and bucket pair. diff --git a/api/query.go b/api/query.go index cdceae68..bb884357 100644 --- a/api/query.go +++ b/api/query.go @@ -26,6 +26,7 @@ import ( "github.com/influxdata/influxdb-client-go/api/query" "github.com/influxdata/influxdb-client-go/domain" ihttp "github.com/influxdata/influxdb-client-go/internal/http" + "github.com/influxdata/influxdb-client-go/internal/log" ) const ( @@ -74,6 +75,7 @@ func (q *queryAPI) QueryRaw(ctx context.Context, query string, dialect *domain.D if err != nil { return "", err } + log.Debugf("Query: %s", string(qrJSON)) var body string perror := q.httpService.PostRequest(ctx, queryURL, bytes.NewReader(qrJSON), func(req *http.Request) { req.Header.Set("Content-Type", "application/json") @@ -123,6 +125,7 @@ func (q *queryAPI) Query(ctx context.Context, query string) (*QueryTableResult, if err != nil { return nil, err } + log.Debugf("Query: %s", string(qrJSON)) perror := q.httpService.PostRequest(ctx, queryURL, bytes.NewReader(qrJSON), func(req *http.Request) { req.Header.Set("Content-Type", "application/json") req.Header.Set("Accept-Encoding", "gzip") diff --git a/api/write.go b/api/write.go index ff911151..3165c57d 100644 --- a/api/write.go +++ b/api/write.go @@ -94,7 +94,7 @@ func (w *WriteAPIImpl) waitForFlushing() { if writeBuffInfo.writeBuffLen == 0 { break } - log.Log.Info("Waiting buffer is flushed") + log.Info("Waiting buffer is flushed") time.Sleep(time.Millisecond) } for { @@ -103,13 +103,13 @@ func (w *WriteAPIImpl) waitForFlushing() { if writeBuffInfo.writeBuffLen == 0 { break } - log.Log.Info("Waiting buffer is flushed") + log.Info("Waiting buffer is flushed") time.Sleep(time.Millisecond) } } func (w *WriteAPIImpl) bufferProc() { - log.Log.Info("Buffer proc started") + log.Info("Buffer proc started") ticker := time.NewTicker(time.Duration(w.writeOptions.FlushInterval()) * time.Millisecond) x: for { @@ -132,13 +132,13 @@ x: w.bufferInfoCh <- buffInfo } } - log.Log.Info("Buffer proc finished") + log.Info("Buffer proc finished") w.doneCh <- struct{}{} } func (w *WriteAPIImpl) flushBuffer() { if len(w.writeBuffer) > 0 { - log.Log.Info("sending batch") + log.Info("sending batch") batch := iwrite.NewBatch(buffer(w.writeBuffer), w.writeOptions.RetryInterval()) w.writeCh <- batch w.writeBuffer = w.writeBuffer[:0] @@ -146,7 +146,7 @@ func (w *WriteAPIImpl) flushBuffer() { } func (w *WriteAPIImpl) writeProc() { - log.Log.Info("Write proc started") + log.Info("Write proc started") x: for { select { @@ -156,14 +156,14 @@ x: w.errCh <- err } case <-w.writeStop: - log.Log.Info("Write proc: received stop") + log.Info("Write proc: received stop") break x case buffInfo := <-w.writeInfoCh: buffInfo.writeBuffLen = len(w.writeCh) w.writeInfoCh <- buffInfo } } - log.Log.Info("Write proc finished") + log.Info("Write proc finished") w.doneCh <- struct{}{} } @@ -205,7 +205,7 @@ func (w *WriteAPIImpl) WriteRecord(line string) { func (w *WriteAPIImpl) WritePoint(point *write.Point) { line, err := w.service.EncodePoints(point) if err != nil { - log.Log.Errorf("point encoding error: %s\n", err.Error()) + log.Errorf("point encoding error: %s\n", err.Error()) } else { w.bufferCh <- line } diff --git a/api/write_test.go b/api/write_test.go index ac72521e..fc0c2d1d 100644 --- a/api/write_test.go +++ b/api/write_test.go @@ -19,7 +19,7 @@ import ( "github.com/influxdata/influxdb-client-go/api/write" ihttp "github.com/influxdata/influxdb-client-go/internal/http" - "github.com/influxdata/influxdb-client-go/internal/log" + "github.com/influxdata/influxdb-client-go/log" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -219,7 +219,7 @@ func TestWriteAPIImpl_Write(t *testing.T) { func TestGzipWithFlushing(t *testing.T) { service := newTestService(t, "http://localhost:8888") - log.Log.SetDebugLevel(4) + log.Log.SetLogLevel(log.DebugLevel) writeAPI := NewWriteAPI("my-org", "my-bucket", service, write.DefaultOptions().SetBatchSize(5).SetUseGZip(true)) points := genPoints(5) for _, p := range points { @@ -269,7 +269,7 @@ func TestFlushInterval(t *testing.T) { func TestRetry(t *testing.T) { service := newTestService(t, "http://localhost:8888") - log.Log.SetDebugLevel(5) + log.Log.SetLogLevel(log.DebugLevel) writeAPI := NewWriteAPI("my-org", "my-bucket", service, write.DefaultOptions().SetBatchSize(5).SetRetryInterval(10000)) points := genPoints(15) for i := 0; i < 5; i++ { @@ -306,7 +306,7 @@ func TestRetry(t *testing.T) { func TestWriteError(t *testing.T) { service := newTestService(t, "http://localhost:8888") - log.Log.SetDebugLevel(3) + log.Log.SetLogLevel(log.DebugLevel) service.replyError = &ihttp.Error{ StatusCode: 400, Code: "write", diff --git a/client.go b/client.go index 83253db8..6e229e55 100644 --- a/client.go +++ b/client.go @@ -15,7 +15,8 @@ import ( "github.com/influxdata/influxdb-client-go/api" "github.com/influxdata/influxdb-client-go/domain" ihttp "github.com/influxdata/influxdb-client-go/internal/http" - "github.com/influxdata/influxdb-client-go/internal/log" + ilog "github.com/influxdata/influxdb-client-go/internal/log" + "github.com/influxdata/influxdb-client-go/log" ) // Client provides API to communicate with InfluxDBServer. @@ -101,8 +102,10 @@ func NewClientWithOptions(serverURL string, authToken string, options *Options) httpService: service, apiClient: domain.NewClientWithResponses(service), } - log.Log.SetDebugLevel(client.Options().LogLevel()) - log.Log.Infof("Using URL '%s', token '%s'", serverURL, authToken) + if log.Log != nil { + log.Log.SetLogLevel(options.LogLevel()) + } + ilog.Infof("Using URL '%s', token '%s'", serverURL, authToken) return client } func (c *clientImpl) Options() *Options { diff --git a/internal/http/service.go b/internal/http/service.go index f5bac8ac..7d8c3f9f 100644 --- a/internal/http/service.go +++ b/internal/http/service.go @@ -16,6 +16,7 @@ import ( "strconv" http2 "github.com/influxdata/influxdb-client-go/api/http" + "github.com/influxdata/influxdb-client-go/internal/log" ) // RequestCallback defines function called after a request is created before any call @@ -59,7 +60,7 @@ func NewService(serverURL, authorization string, httpOptions *http2.Options) Ser serverAPIURL: serverAPIURL, serverURL: serverURL, authorization: authorization, - client: httpOptions.HTTPClient(), + client: httpOptions.HTTPClient(), } } @@ -114,6 +115,7 @@ func (s *service) DoHTTPRequest(req *http.Request, requestCallback RequestCallba } func (s *service) DoHTTPRequestWithResponse(req *http.Request, requestCallback RequestCallback) (*http.Response, error) { + log.Infof("HTTP %s req to %s", req.Method, req.URL.String()) req.Header.Set("Authorization", s.authorization) req.Header.Set("User-Agent", UserAgent) if requestCallback != nil { diff --git a/internal/log/logger.go b/internal/log/logger.go index cfc16c43..aa5a2128 100644 --- a/internal/log/logger.go +++ b/internal/log/logger.go @@ -6,61 +6,50 @@ package log import ( - "fmt" - "log" + ilog "github.com/influxdata/influxdb-client-go/log" ) -var Log Logger - -// Logger provides filtered and categorized logging API. -// It logs to standard logger, only errors by default -type Logger struct { - debugLevel uint -} - -// SetDebugLevel to filter log messages. Each level mean to log all categories bellow -// 0 errors , 1 - warning, 2 - info, 3 - debug -func (l *Logger) SetDebugLevel(debugLevel uint) { - l.debugLevel = debugLevel -} - -func (l *Logger) Debugf(format string, v ...interface{}) { - if l.debugLevel > 2 { - log.Print("[D]! ", fmt.Sprintf(format, v...)) +func Debugf(format string, v ...interface{}) { + if ilog.Log != nil { + ilog.Log.Debugf(format, v...) } } -func (l *Logger) Debug(msg string) { - if l.debugLevel > 2 { - log.Print("[D]! ", msg) +func Debug(msg string) { + if ilog.Log != nil { + ilog.Log.Debug(msg) } } -func (l *Logger) Infof(format string, v ...interface{}) { - if l.debugLevel > 1 { - log.Print("[I]! ", fmt.Sprintf(format, v...)) +func Infof(format string, v ...interface{}) { + if ilog.Log != nil { + ilog.Log.Infof(format, v...) } } -func (l *Logger) Info(msg string) { - if l.debugLevel > 1 { - log.Print("[I]! ", msg) +func Info(msg string) { + if ilog.Log != nil { + ilog.Log.Info(msg) } } -func (l *Logger) Warnf(format string, v ...interface{}) { - if l.debugLevel > 0 { - log.Print("[W]! ", fmt.Sprintf(format, v...)) +func Warnf(format string, v ...interface{}) { + if ilog.Log != nil { + ilog.Log.Warnf(format, v...) } } -func (l *Logger) Warn(msg string) { - if l.debugLevel > 0 { - log.Print("[W]! ", msg) +func Warn(msg string) { + if ilog.Log != nil { + ilog.Log.Warn(msg) } } -func (l *Logger) Errorf(format string, v ...interface{}) { - log.Print("[E]! ", fmt.Sprintf(format, v...)) +func Errorf(format string, v ...interface{}) { + if ilog.Log != nil { + ilog.Log.Errorf(format, v...) + } } -func (l *Logger) Error(msg string) { - log.Print("[E]! ", msg) +func Error(msg string) { + if ilog.Log != nil { + ilog.Log.Error(msg) + } } diff --git a/internal/log/logger_test.go b/internal/log/logger_test.go new file mode 100644 index 00000000..4be462e0 --- /dev/null +++ b/internal/log/logger_test.go @@ -0,0 +1,51 @@ +// Copyright 2020 InfluxData, Inc. All rights reserved. +// Use of this source code is governed by MIT +// license that can be found in the LICENSE file. + +package log_test + +import ( + "log" + "strings" + "testing" + + ilog "github.com/influxdata/influxdb-client-go/internal/log" + dlog "github.com/influxdata/influxdb-client-go/log" + "github.com/stretchr/testify/assert" +) + +func TestLogging(t *testing.T) { + var sb strings.Builder + log.SetOutput(&sb) + dlog.Log.SetLogLevel(dlog.DebugLevel) + //test default settings + ilog.Debug("Debug") + ilog.Debugf("Debugf %s %d", "message", 1) + ilog.Info("Info") + ilog.Infof("Infof %s %d", "message", 2) + ilog.Warn("Warn") + ilog.Warnf("Warnf %s %d", "message", 3) + ilog.Error("Error") + ilog.Errorf("Errorf %s %d", "message", 4) + assert.True(t, strings.Contains(sb.String(), "Debug")) + assert.True(t, strings.Contains(sb.String(), "Debugf message 1")) + assert.True(t, strings.Contains(sb.String(), "Info")) + assert.True(t, strings.Contains(sb.String(), "Infof message 2")) + assert.True(t, strings.Contains(sb.String(), "Warn")) + assert.True(t, strings.Contains(sb.String(), "Warnf message 3")) + assert.True(t, strings.Contains(sb.String(), "Error")) + assert.True(t, strings.Contains(sb.String(), "Errorf message 4")) + + sb.Reset() + + dlog.Log = nil + ilog.Debug("Debug") + ilog.Debugf("Debugf %s %d", "message", 1) + ilog.Info("Info") + ilog.Infof("Infof %s %d", "message", 2) + ilog.Warn("Warn") + ilog.Warnf("Warnf %s %d", "message", 3) + ilog.Error("Error") + ilog.Errorf("Errorf %s %d", "message", 4) + assert.True(t, len(sb.String()) == 0) +} diff --git a/internal/write/service.go b/internal/write/service.go index d1d5b469..95de2986 100644 --- a/internal/write/service.go +++ b/internal/write/service.go @@ -57,25 +57,25 @@ func NewService(org string, bucket string, httpService ihttp.Service, options *w } func (w *Service) HandleWrite(ctx context.Context, batch *Batch) error { - log.Log.Debug("Write proc: received write request") + log.Debug("Write proc: received write request") batchToWrite := batch retrying := false for { select { case <-ctx.Done(): - log.Log.Debug("Write proc: ctx cancelled req") + log.Debug("Write proc: ctx cancelled req") return ctx.Err() default: } if !w.retryQueue.isEmpty() { - log.Log.Debug("Write proc: taking batch from retry queue") + log.Debug("Write proc: taking batch from retry queue") if !retrying { b := w.retryQueue.first() // Can we write? In case of retryable error we must wait a bit if w.lastWriteAttempt.IsZero() || time.Now().After(w.lastWriteAttempt.Add(time.Millisecond*time.Duration(b.retryInterval))) { retrying = true } else { - log.Log.Warn("Write proc: cannot write yet, storing batch to queue") + log.Warn("Write proc: cannot write yet, storing batch to queue") w.retryQueue.push(batch) batchToWrite = nil } @@ -85,7 +85,7 @@ func (w *Service) HandleWrite(ctx context.Context, batch *Batch) error { batchToWrite.retries++ if batch != nil { if w.retryQueue.push(batch) { - log.Log.Warn("Write proc: Retry buffer full, discarding oldest batch") + log.Warn("Write proc: Retry buffer full, discarding oldest batch") } batch = nil } @@ -107,12 +107,12 @@ func (w *Service) HandleWrite(ctx context.Context, batch *Batch) error { func (w *Service) WriteBatch(ctx context.Context, batch *Batch) error { wURL, err := w.WriteURL() if err != nil { - log.Log.Errorf("%s\n", err.Error()) + log.Errorf("%s\n", err.Error()) return err } var body io.Reader body = strings.NewReader(batch.batch) - log.Log.Debugf("Writing batch: %s", batch.batch) + log.Debugf("Writing batch: %s", batch.batch) if w.writeOptions.UseGZip() { body, err = gzip.CompressWithGzip(body) if err != nil { @@ -133,7 +133,7 @@ func (w *Service) WriteBatch(ctx context.Context, batch *Batch) error { if perror != nil { if perror.StatusCode == http.StatusTooManyRequests || perror.StatusCode == http.StatusServiceUnavailable { - log.Log.Errorf("Write error: %s\nBatch kept for retrying\n", perror.Error()) + log.Errorf("Write error: %s\nBatch kept for retrying\n", perror.Error()) if perror.RetryAfter > 0 { batch.retryInterval = perror.RetryAfter * 1000 } else { @@ -141,11 +141,11 @@ func (w *Service) WriteBatch(ctx context.Context, batch *Batch) error { } if batch.retries < w.writeOptions.MaxRetries() { if w.retryQueue.push(batch) { - log.Log.Warn("Retry buffer full, discarding oldest batch") + log.Warn("Retry buffer full, discarding oldest batch") } } } else { - log.Log.Errorf("Write error: %s\n", perror.Error()) + log.Errorf("Write error: %s\n", perror.Error()) } return perror } diff --git a/log/logger.go b/log/logger.go new file mode 100644 index 00000000..ceb5882d --- /dev/null +++ b/log/logger.go @@ -0,0 +1,102 @@ +// Copyright 2020 InfluxData, Inc. All rights reserved. +// Use of this source code is governed by MIT +// license that can be found in the LICENSE file. + +// Package log defines Logging API. +// The global Log variable contains the actual logger. Set it to own implementation to override logging. Set it to nil to disable logging +package log + +import ( + "fmt" + "log" +) + +// Log is the library wide logger. Setting to nil disables logging. +var Log Logger = &logger{logLevel: ErrorLevel, prefix: "influxdb2client"} + +// Log levels +const ( + ErrorLevel uint = iota + WarningLevel + InfoLevel + DebugLevel +) + +// Logger defines interface for logging +type Logger interface { + // SetLogLevel sets allowed logging level. + SetLogLevel(logLevel uint) + // SetPrefix sets logging prefix. + SetPrefix(prefix string) + // Writes formatted debug message if debug logLevel is enabled. + Debugf(format string, v ...interface{}) + // Writes debug message if debug is enabled. + Debug(msg string) + // Writes formatted info message if info logLevel is enabled. + Infof(format string, v ...interface{}) + // Writes info message if info logLevel is enabled + Info(msg string) + // Writes formatted warning message if warning logLevel is enabled. + Warnf(format string, v ...interface{}) + // Writes warning message if warning logLevel is enabled. + Warn(msg string) + // Writes formatted error message + Errorf(format string, v ...interface{}) + // Writes error message + Error(msg string) +} + +// logger provides default implementation for Logger. It logs using Go log API +type logger struct { + prefix string + logLevel uint +} + +func (l *logger) SetLogLevel(logLevel uint) { + l.logLevel = logLevel +} + +func (l *logger) SetPrefix(prefix string) { + l.prefix = prefix +} + +func (l *logger) Debugf(format string, v ...interface{}) { + if l.logLevel >= DebugLevel { + log.Print(l.prefix, " D! ", fmt.Sprintf(format, v...)) + } +} +func (l *logger) Debug(msg string) { + if l.logLevel >= DebugLevel { + log.Print(l.prefix, " D! ", msg) + } +} + +func (l *logger) Infof(format string, v ...interface{}) { + if l.logLevel >= InfoLevel { + log.Print(l.prefix, " I! ", fmt.Sprintf(format, v...)) + } +} +func (l *logger) Info(msg string) { + if l.logLevel >= DebugLevel { + log.Print(l.prefix, " I! ", msg) + } +} + +func (l *logger) Warnf(format string, v ...interface{}) { + if l.logLevel >= WarningLevel { + log.Print(l.prefix, " W! ", fmt.Sprintf(format, v...)) + } +} +func (l *logger) Warn(msg string) { + if l.logLevel >= WarningLevel { + log.Print(l.prefix, " W! ", msg) + } +} + +func (l *logger) Errorf(format string, v ...interface{}) { + log.Print(l.prefix, " E! ", fmt.Sprintf(format, v...)) +} + +func (l *logger) Error(msg string) { + log.Print(l.prefix, " [E]! ", msg) +} diff --git a/log/logger_test.go b/log/logger_test.go new file mode 100644 index 00000000..67f12d0c --- /dev/null +++ b/log/logger_test.go @@ -0,0 +1,132 @@ +// Copyright 2020 InfluxData, Inc. All rights reserved. +// Use of this source code is governed by MIT +// license that can be found in the LICENSE file. + +package log_test + +import ( + "fmt" + "log" + "strings" + "testing" + + dlog "github.com/influxdata/influxdb-client-go/log" + "github.com/stretchr/testify/assert" +) + +func logMessages() { + dlog.Log.Debug("Debug") + dlog.Log.Debugf("Debugf %s %d", "message", 1) + dlog.Log.Info("Info") + dlog.Log.Infof("Infof %s %d", "message", 2) + dlog.Log.Warn("Warn") + dlog.Log.Warnf("Warnf %s %d", "message", 3) + dlog.Log.Error("Error") + dlog.Log.Errorf("Errorf %s %d", "message", 4) +} + +func verifyLogs(t *testing.T, sb *strings.Builder, logLevel uint, prefix string) { + if logLevel >= dlog.DebugLevel { + assert.True(t, strings.Contains(sb.String(), prefix+" D! Debug")) + assert.True(t, strings.Contains(sb.String(), prefix+" D! Debugf message 1")) + } else { + assert.False(t, strings.Contains(sb.String(), prefix+" D! Debug")) + assert.False(t, strings.Contains(sb.String(), prefix+" D! Debugf message 1")) + } + if logLevel >= dlog.InfoLevel { + assert.True(t, strings.Contains(sb.String(), prefix+" I! Info")) + assert.True(t, strings.Contains(sb.String(), prefix+" I! Infof message 2")) + } else { + assert.False(t, strings.Contains(sb.String(), prefix+" I! Info")) + assert.False(t, strings.Contains(sb.String(), prefix+" I! Infof message 2")) + + } + if logLevel >= dlog.WarningLevel { + assert.True(t, strings.Contains(sb.String(), prefix+" W! Warn")) + assert.True(t, strings.Contains(sb.String(), prefix+" W! Warnf message 3")) + } else { + assert.False(t, strings.Contains(sb.String(), prefix+" W! Warn")) + assert.False(t, strings.Contains(sb.String(), prefix+" W! Warnf message 3")) + } + if logLevel >= dlog.ErrorLevel { + assert.True(t, strings.Contains(sb.String(), prefix+" E! Error")) + assert.True(t, strings.Contains(sb.String(), prefix+" E! Errorf message 4")) + } +} + +func TestLogging(t *testing.T) { + var sb strings.Builder + log.SetOutput(&sb) + log.SetFlags(0) + //test default settings + logMessages() + verifyLogs(t, &sb, dlog.ErrorLevel, "influxdb2client") + + sb.Reset() + dlog.Log.SetLogLevel(dlog.WarningLevel) + logMessages() + verifyLogs(t, &sb, dlog.WarningLevel, "influxdb2client") + + sb.Reset() + dlog.Log.SetLogLevel(dlog.InfoLevel) + logMessages() + verifyLogs(t, &sb, dlog.InfoLevel, "influxdb2client") + + sb.Reset() + dlog.Log.SetLogLevel(dlog.DebugLevel) + logMessages() + verifyLogs(t, &sb, dlog.DebugLevel, "influxdb2client") + + sb.Reset() + dlog.Log.SetPrefix("client") + logMessages() + verifyLogs(t, &sb, dlog.DebugLevel, "client") +} + +func TestCustomLogger(t *testing.T) { + var sb strings.Builder + log.SetOutput(&sb) + log.SetFlags(0) + dlog.Log = &testLogger{} + //test default settings + logMessages() + verifyLogs(t, &sb, dlog.DebugLevel, "testlogger") +} + +type testLogger struct { +} + +func (l *testLogger) SetLogLevel(_ uint) { +} + +func (l *testLogger) SetPrefix(_ string) { +} + +func (l *testLogger) Debugf(format string, v ...interface{}) { + log.Print("testlogger", " D! ", fmt.Sprintf(format, v...)) +} +func (l *testLogger) Debug(msg string) { + log.Print("testlogger", " D! ", msg) +} + +func (l *testLogger) Infof(format string, v ...interface{}) { + log.Print("testlogger", " I! ", fmt.Sprintf(format, v...)) +} +func (l *testLogger) Info(msg string) { + log.Print("testlogger", " I! ", msg) +} + +func (l *testLogger) Warnf(format string, v ...interface{}) { + log.Print("testlogger", " W! ", fmt.Sprintf(format, v...)) +} +func (l *testLogger) Warn(msg string) { + log.Print("testlogger", " W! ", msg) +} + +func (l *testLogger) Errorf(format string, v ...interface{}) { + log.Print("testlogger", " E! ", fmt.Sprintf(format, v...)) +} + +func (l *testLogger) Error(msg string) { + log.Print("testlogger", " [E]! ", msg) +} diff --git a/options.go b/options.go index 6f2feb0e..6cdcea17 100644 --- a/options.go +++ b/options.go @@ -83,8 +83,15 @@ func (o *Options) LogLevel() uint { return o.logLevel } -// SetLogLevel set level to filter log messages. Each level mean to log all categories bellow. 0 error, 1 - warning, 2 - info, 3 - debug -// Debug level will print also content of writen batches +// SetLogLevel set level to filter log messages. Each level mean to log all categories bellow. Default is ErrorLevel. +// There are four level constant int the log package in this library: +// - ErrorLevel +// - WarningLevel +// - InfoLevel +// - DebugLevel +// The DebugLevel will print also content of writen batches, queries. +// The InfoLevel prints HTTP requests info, among others. +// Set log.Log to nil in order to completely disable logging. func (o *Options) SetLogLevel(logLevel uint) *Options { o.logLevel = logLevel return o