types/logger: add ArgWriter

This commit is contained in:
Brad Fitzpatrick 2020-05-13 14:47:13 -07:00
parent 33b2f30cea
commit fe97bedf67
2 changed files with 31 additions and 0 deletions

View File

@ -8,9 +8,11 @@
package logger
import (
"bufio"
"container/list"
"fmt"
"io"
"io/ioutil"
"log"
"sync"
@ -111,3 +113,17 @@ func RateLimitedFn(logf Logf, f float64, burst int, maxCache int) Logf {
}
}
}
// ArgWriter is a fmt.Formatter that can be passed to any Logf func to
// efficiently write to a %v argument without allocations.
type ArgWriter func(*bufio.Writer)
func (fn ArgWriter) Format(f fmt.State, _ rune) {
bw := argBufioPool.Get().(*bufio.Writer)
bw.Reset(f)
fn(bw)
bw.Flush()
argBufioPool.Put(bw)
}
var argBufioPool = &sync.Pool{New: func() interface{} { return bufio.NewWriterSize(ioutil.Discard, 1024) }}

View File

@ -5,6 +5,8 @@
package logger
import (
"bufio"
"bytes"
"fmt"
"log"
"testing"
@ -62,3 +64,16 @@ func TestRateLimiter(t *testing.T) {
}
}
func TestArgWriter(t *testing.T) {
got := new(bytes.Buffer)
fmt.Fprintf(got, "Greeting: %v", ArgWriter(func(bw *bufio.Writer) {
bw.WriteString("Hello, ")
bw.WriteString("world")
bw.WriteByte('!')
}))
const want = "Greeting: Hello, world!"
if got.String() != want {
t.Errorf("got %q; want %q", got, want)
}
}