Repository: go-logr/logr (go)

Issue:
Add NullLogger
Following discussion in #25, it is probably a good idea to add a `null.Logger` to logr that ignores all messages.

This can be used as a default logger by components that optionally allow you to pass in a logger. If none is passed in, it can simply use the null logger for all its logging.

The implementation would live under a "null" subpackage and could look like this (needs doc comments):

```go
package null

import "github.com/go-logr/logr"

type Logger struct{}

func (n Logger) Enabled() bool {
	return false
}

func (n Logger) Info(msg string, keysAndValues ...interface{}) {
}

func (n Logger) Error(err error, msg string, keysAndValues ...interface{}) {
}

func (n Logger) V(level int) logr.Logger {
	return n
}

func (n Logger) WithValues(keysAndValues ...interface{}) logr.Logger {
	return n
}

func (n Logger) WithName(name string) logr.Logger {
	return n
}
```

Usage:

```
import "github.com/go-logr/logr/null"

func foo() {
	l := null.Logger{}
}
```

Pull request description:
Add a Discard logger
**UPDATED**: Renamed the Null logger to Discard and removed the function to test for it.

Add a Discard logger exposed through a single `Discard()` function. 

The implementation was placed in the top level logr package to avoid an import loop if the top level packages wants to return a Discard logger.

The implementation was kept private to not pollute the package documentation with useless implementation details.

Usage:

```go
log := logr.Discard()
log.V(1).Info("Hello world") // discarded
```

Closes #26


Patch:
diff --git a/discard.go b/discard.go
new file mode 100644
index 0000000..267c796
--- /dev/null
+++ b/discard.go
@@ -0,0 +1,35 @@
+package logr
+
+// Discard returns a valid Logger that discards all messages logged to it.
+// It can be used whenever the caller is not interested in the logs.
+func Discard() Logger {
+	return discardLogger{}
+}
+
+// discardLogger is a Logger that discards all messages.
+type discardLogger struct{}
+
+func (l discardLogger) Enabled() bool {
+	return false
+}
+
+func (l discardLogger) Info(msg string, keysAndValues ...interface{}) {
+}
+
+func (l discardLogger) Error(err error, msg string, keysAndValues ...interface{}) {
+}
+
+func (l discardLogger) V(level int) Logger {
+	return l
+}
+
+func (l discardLogger) WithValues(keysAndValues ...interface{}) Logger {
+	return l
+}
+
+func (l discardLogger) WithName(name string) Logger {
+	return l
+}
+
+// Verify that it actually implements the interface
+var _ Logger = discardLogger{}


Test patch:
diff --git a/discard_test.go b/discard_test.go
new file mode 100644
index 0000000..2ba2769
--- /dev/null
+++ b/discard_test.go
@@ -0,0 +1,20 @@
+package logr
+
+import (
+	"errors"
+	"testing"
+)
+
+func TestDiscard(t *testing.T) {
+	l := Discard()
+	if _, ok := l.(discardLogger); !ok {
+		t.Error("did not return the expected underlying type")
+	}
+	// Verify that none of the methods panic, there is not more we can test.
+	l.WithName("discard").WithValues("z", 5).Info("Hello world")
+	l.Info("Hello world", "x", 1, "y", 2)
+	l.V(1).Error(errors.New("foo"), "a", 123)
+	if l.Enabled() {
+		t.Error("discard logger must always say it is disabled")
+	}
+}