mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Unexport FastTimeMarshalJSON
Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
parent
27cfa68af1
commit
7de92de636
7 changed files with 65 additions and 77 deletions
|
@ -113,18 +113,14 @@ func writeMessageBuf(w io.Writer, m *logger.Message, extra json.RawMessage, buf
|
|||
}
|
||||
|
||||
func marshalMessage(msg *logger.Message, extra json.RawMessage, buf *bytes.Buffer) error {
|
||||
timestamp, err := jsonlog.FastTimeMarshalJSON(msg.Timestamp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logLine := msg.Line
|
||||
if !msg.Partial {
|
||||
logLine = append(msg.Line, '\n')
|
||||
}
|
||||
err = (&jsonlog.JSONLogs{
|
||||
err := (&jsonlog.JSONLogs{
|
||||
Log: logLine,
|
||||
Stream: msg.Source,
|
||||
Created: timestamp,
|
||||
Created: msg.Timestamp,
|
||||
RawAttrs: extra,
|
||||
}).MarshalJSONBuf(buf)
|
||||
if err != nil {
|
||||
|
|
|
@ -105,7 +105,7 @@ func (mj *JSONLog) MarshalJSONBuf(buf *bytes.Buffer) error {
|
|||
buf.WriteString(`,`)
|
||||
}
|
||||
buf.WriteString(`"time":`)
|
||||
timestamp, err = FastTimeMarshalJSON(mj.Created)
|
||||
timestamp, err = fastTimeMarshalJSON(mj.Created)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@ package jsonlog
|
|||
import (
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"encoding/json"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestJSONLogMarshalJSON(t *testing.T) {
|
||||
|
@ -21,14 +25,8 @@ func TestJSONLogMarshalJSON(t *testing.T) {
|
|||
}
|
||||
for jsonLog, expression := range logs {
|
||||
data, err := jsonLog.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
res := string(data)
|
||||
t.Logf("Result of WriteLog: %q", res)
|
||||
logRe := regexp.MustCompile(expression)
|
||||
if !logRe.MatchString(res) {
|
||||
t.Fatalf("Log line not in expected format [%v]: %q", expression, res)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
assert.Regexp(t, regexp.MustCompile(expression), string(data))
|
||||
assert.NoError(t, json.Unmarshal(data, &map[string]interface{}{}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,16 +3,15 @@ package jsonlog
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// JSONLogs is based on JSONLog.
|
||||
// It allows marshalling JSONLog from Log as []byte
|
||||
// and an already marshalled Created timestamp.
|
||||
// JSONLogs marshals encoded JSONLog objects
|
||||
type JSONLogs struct {
|
||||
Log []byte `json:"log,omitempty"`
|
||||
Stream string `json:"stream,omitempty"`
|
||||
Created string `json:"time"`
|
||||
Log []byte `json:"log,omitempty"`
|
||||
Stream string `json:"stream,omitempty"`
|
||||
Created time.Time `json:"time"`
|
||||
|
||||
// json-encoded bytes
|
||||
RawAttrs json.RawMessage `json:"attrs,omitempty"`
|
||||
|
@ -50,8 +49,14 @@ func (mj *JSONLogs) MarshalJSONBuf(buf *bytes.Buffer) error {
|
|||
if !first {
|
||||
buf.WriteString(`,`)
|
||||
}
|
||||
|
||||
created, err := fastTimeMarshalJSON(mj.Created)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buf.WriteString(`"time":`)
|
||||
buf.WriteString(mj.Created)
|
||||
buf.WriteString(created)
|
||||
buf.WriteString(`}`)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -2,38 +2,39 @@ package jsonlog
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"regexp"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestJSONLogsMarshalJSONBuf(t *testing.T) {
|
||||
logs := map[*JSONLogs]string{
|
||||
{Log: []byte(`"A log line with \\"`)}: `^{\"log\":\"\\\"A log line with \\\\\\\\\\\"\",\"time\":}$`,
|
||||
{Log: []byte("A log line")}: `^{\"log\":\"A log line\",\"time\":}$`,
|
||||
{Log: []byte("A log line with \r")}: `^{\"log\":\"A log line with \\r\",\"time\":}$`,
|
||||
{Log: []byte("A log line with & < >")}: `^{\"log\":\"A log line with \\u0026 \\u003c \\u003e\",\"time\":}$`,
|
||||
{Log: []byte("A log line with utf8 : 🚀 ψ ω β")}: `^{\"log\":\"A log line with utf8 : 🚀 ψ ω β\",\"time\":}$`,
|
||||
{Stream: "stdout"}: `^{\"stream\":\"stdout\",\"time\":}$`,
|
||||
{Stream: "stdout", Log: []byte("A log line")}: `^{\"log\":\"A log line\",\"stream\":\"stdout\",\"time\":}$`,
|
||||
{Created: "time"}: `^{\"time\":time}$`,
|
||||
{}: `^{\"time\":}$`,
|
||||
{Log: []byte(`"A log line with \\"`)}: `^{\"log\":\"\\\"A log line with \\\\\\\\\\\"\",\"time\":`,
|
||||
{Log: []byte("A log line")}: `^{\"log\":\"A log line\",\"time\":`,
|
||||
{Log: []byte("A log line with \r")}: `^{\"log\":\"A log line with \\r\",\"time\":`,
|
||||
{Log: []byte("A log line with & < >")}: `^{\"log\":\"A log line with \\u0026 \\u003c \\u003e\",\"time\":`,
|
||||
{Log: []byte("A log line with utf8 : 🚀 ψ ω β")}: `^{\"log\":\"A log line with utf8 : 🚀 ψ ω β\",\"time\":`,
|
||||
{Stream: "stdout"}: `^{\"stream\":\"stdout\",\"time\":`,
|
||||
{Stream: "stdout", Log: []byte("A log line")}: `^{\"log\":\"A log line\",\"stream\":\"stdout\",\"time\":`,
|
||||
{Created: time.Date(2017, 9, 1, 1, 1, 1, 1, time.UTC)}: `^{\"time\":"2017-09-01T01:01:01.000000001Z"}$`,
|
||||
|
||||
{}: `^{\"time\":"0001-01-01T00:00:00Z"}$`,
|
||||
// These ones are a little weird
|
||||
{Log: []byte("\u2028 \u2029")}: `^{\"log\":\"\\u2028 \\u2029\",\"time\":}$`,
|
||||
{Log: []byte{0xaF}}: `^{\"log\":\"\\ufffd\",\"time\":}$`,
|
||||
{Log: []byte{0x7F}}: `^{\"log\":\"\x7f\",\"time\":}$`,
|
||||
{Log: []byte("\u2028 \u2029")}: `^{\"log\":\"\\u2028 \\u2029\",\"time\":`,
|
||||
{Log: []byte{0xaF}}: `^{\"log\":\"\\ufffd\",\"time\":`,
|
||||
{Log: []byte{0x7F}}: `^{\"log\":\"\x7f\",\"time\":`,
|
||||
// with raw attributes
|
||||
{Log: []byte("A log line"), RawAttrs: []byte(`{"hello":"world","value":1234}`)}: `^{\"log\":\"A log line\",\"attrs\":{\"hello\":\"world\",\"value\":1234},\"time\":}$`,
|
||||
{Log: []byte("A log line"), RawAttrs: []byte(`{"hello":"world","value":1234}`)}: `^{\"log\":\"A log line\",\"attrs\":{\"hello\":\"world\",\"value\":1234},\"time\":`,
|
||||
}
|
||||
for jsonLog, expression := range logs {
|
||||
var buf bytes.Buffer
|
||||
if err := jsonLog.MarshalJSONBuf(&buf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
res := buf.String()
|
||||
t.Logf("Result of WriteLog: %q", res)
|
||||
logRe := regexp.MustCompile(expression)
|
||||
if !logRe.MatchString(res) {
|
||||
t.Fatalf("Log line not in expected format [%v]: %q", expression, res)
|
||||
}
|
||||
err := jsonLog.MarshalJSONBuf(&buf)
|
||||
require.NoError(t, err)
|
||||
assert.Regexp(t, regexp.MustCompile(expression), buf.String())
|
||||
assert.NoError(t, json.Unmarshal(buf.Bytes(), &map[string]interface{}{}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ import (
|
|||
|
||||
const jsonFormat = `"` + time.RFC3339Nano + `"`
|
||||
|
||||
// FastTimeMarshalJSON avoids one of the extra allocations that
|
||||
// fastTimeMarshalJSON avoids one of the extra allocations that
|
||||
// time.MarshalJSON is making.
|
||||
func FastTimeMarshalJSON(t time.Time) (string, error) {
|
||||
func fastTimeMarshalJSON(t time.Time) (string, error) {
|
||||
if y := t.Year(); y < 0 || y >= 10000 {
|
||||
// RFC 3339 is clear that years are 4 digits exactly.
|
||||
// See golang.org/issue/4556#c15 for more discussion.
|
||||
|
|
|
@ -3,45 +3,33 @@ package jsonlog
|
|||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/internal/testutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// Testing to ensure 'year' fields is between 0 and 9999
|
||||
func TestFastTimeMarshalJSONWithInvalidDate(t *testing.T) {
|
||||
func TestFastTimeMarshalJSONWithInvalidYear(t *testing.T) {
|
||||
aTime := time.Date(-1, 1, 1, 0, 0, 0, 0, time.Local)
|
||||
json, err := FastTimeMarshalJSON(aTime)
|
||||
if err == nil {
|
||||
t.Fatalf("FastTimeMarshalJSON should throw an error, but was '%v'", json)
|
||||
}
|
||||
anotherTime := time.Date(10000, 1, 1, 0, 0, 0, 0, time.Local)
|
||||
json, err = FastTimeMarshalJSON(anotherTime)
|
||||
if err == nil {
|
||||
t.Fatalf("FastTimeMarshalJSON should throw an error, but was '%v'", json)
|
||||
}
|
||||
_, err := fastTimeMarshalJSON(aTime)
|
||||
testutil.ErrorContains(t, err, "year outside of range")
|
||||
|
||||
anotherTime := time.Date(10000, 1, 1, 0, 0, 0, 0, time.Local)
|
||||
_, err = fastTimeMarshalJSON(anotherTime)
|
||||
testutil.ErrorContains(t, err, "year outside of range")
|
||||
}
|
||||
|
||||
func TestFastTimeMarshalJSON(t *testing.T) {
|
||||
aTime := time.Date(2015, 5, 29, 11, 1, 2, 3, time.UTC)
|
||||
json, err := FastTimeMarshalJSON(aTime)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expected := "\"2015-05-29T11:01:02.000000003Z\""
|
||||
if json != expected {
|
||||
t.Fatalf("Expected %v, got %v", expected, json)
|
||||
}
|
||||
json, err := fastTimeMarshalJSON(aTime)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "\"2015-05-29T11:01:02.000000003Z\"", json)
|
||||
|
||||
location, err := time.LoadLocation("Europe/Paris")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
aTime = time.Date(2015, 5, 29, 11, 1, 2, 3, location)
|
||||
json, err = FastTimeMarshalJSON(aTime)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expected = "\"2015-05-29T11:01:02.000000003+02:00\""
|
||||
if json != expected {
|
||||
t.Fatalf("Expected %v, got %v", expected, json)
|
||||
}
|
||||
json, err = fastTimeMarshalJSON(aTime)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "\"2015-05-29T11:01:02.000000003+02:00\"", json)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue