mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-13 03:42:35 -06:00
1b33bf3f6f
Fixes #705 Signed-off-by: Ashutosh Narkar <anarkar4387@gmail.com>
105 lines
2.0 KiB
Go
105 lines
2.0 KiB
Go
// Copyright 2018 The OPA Authors. All rights reserved.
|
|
// Use of this source code is governed by an Apache2
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package logs
|
|
|
|
import (
|
|
"bytes"
|
|
"compress/gzip"
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
// chunkEncoder implements log buffer chunking and compression. Log events are
|
|
// written to the encoder and the encoder outputs chunks that are fit to the
|
|
// configured limit.
|
|
type chunkEncoder struct {
|
|
limit int64
|
|
bytesWritten int
|
|
buf *bytes.Buffer
|
|
w *gzip.Writer
|
|
}
|
|
|
|
func newChunkEncoder(limit int64) *chunkEncoder {
|
|
enc := &chunkEncoder{
|
|
limit: limit,
|
|
}
|
|
enc.reset()
|
|
|
|
return enc
|
|
}
|
|
|
|
func (enc *chunkEncoder) Write(event EventV1) (result []byte, err error) {
|
|
var buf bytes.Buffer
|
|
if err := json.NewEncoder(&buf).Encode(event); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
bs := buf.Bytes()
|
|
|
|
if len(bs) == 0 {
|
|
return nil, nil
|
|
} else if int64(len(bs)+2) > enc.limit {
|
|
return nil, fmt.Errorf("upload chunk size too small")
|
|
}
|
|
|
|
if int64(len(bs)+enc.bytesWritten+1) > enc.limit {
|
|
if err := enc.writeClose(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
result = enc.reset()
|
|
}
|
|
|
|
if enc.bytesWritten == 0 {
|
|
n, err := enc.w.Write([]byte(`[`))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
enc.bytesWritten += n
|
|
} else {
|
|
n, err := enc.w.Write([]byte(`,`))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
enc.bytesWritten += n
|
|
}
|
|
|
|
n, err := enc.w.Write(bs)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
enc.bytesWritten += n
|
|
return
|
|
}
|
|
|
|
func (enc *chunkEncoder) writeClose() error {
|
|
if _, err := enc.w.Write([]byte(`]`)); err != nil {
|
|
return err
|
|
}
|
|
return enc.w.Close()
|
|
}
|
|
|
|
func (enc *chunkEncoder) Flush() ([]byte, error) {
|
|
if enc.bytesWritten == 0 {
|
|
return nil, nil
|
|
}
|
|
if err := enc.writeClose(); err != nil {
|
|
return nil, err
|
|
}
|
|
return enc.reset(), nil
|
|
}
|
|
|
|
func (enc *chunkEncoder) reset() []byte {
|
|
buf := enc.buf
|
|
enc.buf = new(bytes.Buffer)
|
|
enc.bytesWritten = 0
|
|
enc.w = gzip.NewWriter(enc.buf)
|
|
if buf != nil {
|
|
return buf.Bytes()
|
|
}
|
|
return nil
|
|
}
|