summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJosh Bleecher Snyder <josh@tailscale.com>2021-08-17 12:29:58 -0700
committerJosh Bleecher Snyder <josharian@gmail.com>2021-08-17 12:56:57 -0700
commit0c038b477ffce97c03664361663a68fd97b8a05a (patch)
treedeec795db3922078d3b9b1a3d3ae7757a8d54c5c
parent278e7de9c9ee92035e153427d4057ddc0da78fee (diff)
downloadtailscale-0c038b477ffce97c03664361663a68fd97b8a05a.tar.xz
tailscale-0c038b477ffce97c03664361663a68fd97b8a05a.zip
logtail: add a re-usable buffer for uploads
This avoids a per-upload alloc (which in practice often means per-log-line), up to 4k. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
-rw-r--r--logtail/logtail.go8
1 files changed, 5 insertions, 3 deletions
diff --git a/logtail/logtail.go b/logtail/logtail.go
index 71d449079..9763452bb 100644
--- a/logtail/logtail.go
+++ b/logtail/logtail.go
@@ -200,9 +200,10 @@ func (l *Logger) drainBlock() (shuttingDown bool) {
}
// drainPending drains and encodes a batch of logs from the buffer for upload.
+// It uses scratch as its initial buffer.
// If no logs are available, drainPending blocks until logs are available.
-func (l *Logger) drainPending() (res []byte) {
- buf := new(bytes.Buffer)
+func (l *Logger) drainPending(scratch []byte) (res []byte) {
+ buf := bytes.NewBuffer(scratch[:0])
buf.WriteByte('[')
entries := 0
@@ -261,8 +262,9 @@ func (l *Logger) drainPending() (res []byte) {
func (l *Logger) uploading(ctx context.Context) {
defer close(l.shutdownDone)
+ scratch := make([]byte, 4096) // reusable buffer to write into
for {
- body := l.drainPending()
+ body := l.drainPending(scratch)
origlen := -1 // sentinel value: uncompressed
// Don't attempt to compress tiny bodies; not worth the CPU cycles.
if l.zstdEncoder != nil && len(body) > 256 {