mirror of https://github.com/grafana/loki
Updated stream json objects to be more parse friendly (#1010)
* Added custom marshaller for Entry Signed-off-by: Joe Elliott <number101010@gmail.com> * Added comment and test Signed-off-by: Joe Elliott <number101010@gmail.com> * Fixed spelling error * Added a custom marshaller to map entries => values * Added support for labels Signed-off-by: Joe Elliott <number101010@gmail.com> * Changed test to only check to the microsecond level Signed-off-by: Joe Elliott <number101010@gmail.com> * Extended Entry tests Signed-off-by: Joe Elliott <number101010@gmail.com> * Swapped to nanosecs encoded as strings * Cleaned up docs with new loki paths. Removed references to deprecated endpoints * Added support for /loki/api/v1/push Signed-off-by: Joe Elliott <number101010@gmail.com> * Removed obsolete comment Signed-off-by: Joe Elliott <number101010@gmail.com> * Updated docs for new push endpoint Signed-off-by: Joe Elliott <number101010@gmail.com> * Ran gofmt on test file Signed-off-by: Joe Elliott <number101010@gmail.com> * Set GOGC=20 on test to avoid out of memory issue in circle ci Signed-off-by: Joe Elliott <number101010@gmail.com>pull/1016/head
parent
47637852fb
commit
6185d54320
@ -0,0 +1,35 @@ |
||||
package logproto |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
fmt "fmt" |
||||
|
||||
"github.com/prometheus/prometheus/promql" |
||||
) |
||||
|
||||
// MarshalJSON converts an Entry object to be prom compatible for http queries
|
||||
func (e *Entry) MarshalJSON() ([]byte, error) { |
||||
l, err := json.Marshal(e.Line) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
return []byte(fmt.Sprintf("[\"%d\",%s]", e.Timestamp.UnixNano(), l)), nil |
||||
} |
||||
|
||||
// MarshalJSON converts a Stream object to be prom compatible for http queries
|
||||
func (s *Stream) MarshalJSON() ([]byte, error) { |
||||
parsedLabels, err := promql.ParseMetric(s.Labels) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
l, err := json.Marshal(parsedLabels) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
e, err := json.Marshal(s.Entries) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
return []byte(fmt.Sprintf("{\"stream\":%s,\"values\":%s}", l, e)), nil |
||||
} |
||||
@ -0,0 +1,85 @@ |
||||
package logproto |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
fmt "fmt" |
||||
reflect "reflect" |
||||
"testing" |
||||
time "time" |
||||
|
||||
"github.com/prometheus/prometheus/promql" |
||||
"github.com/stretchr/testify/require" |
||||
) |
||||
|
||||
var ( |
||||
entries = []Entry{ |
||||
{ |
||||
Timestamp: time.Now(), |
||||
Line: "testline", |
||||
}, |
||||
{ |
||||
Timestamp: time.Date(2019, 9, 10, 1, 1, 1, 1, time.UTC), |
||||
Line: "{}\"'!@$%&*^(_)(", |
||||
}, |
||||
} |
||||
streams = []Stream{ |
||||
{ |
||||
Labels: "{}", |
||||
Entries: []Entry{}, |
||||
}, |
||||
{ |
||||
Labels: "{name=\"value\",name1=\"value1\"}", |
||||
Entries: []Entry{}, |
||||
}, |
||||
} |
||||
) |
||||
|
||||
func Test_EntryMarshalJSON(t *testing.T) { |
||||
var array []interface{} |
||||
|
||||
for _, entry := range entries { |
||||
|
||||
bytes, err := entry.MarshalJSON() |
||||
require.NoError(t, err) |
||||
|
||||
err = json.Unmarshal(bytes, &array) |
||||
require.NoError(t, err) |
||||
|
||||
timestamp, ok := array[0].(string) |
||||
require.True(t, ok) |
||||
|
||||
line, ok := array[1].(string) |
||||
require.True(t, ok) |
||||
|
||||
require.Equal(t, fmt.Sprint(entry.Timestamp.UnixNano()), timestamp, "Timestamps not equal ", array[0]) |
||||
require.Equal(t, entry.Line, line, "Lines are not equal ", array[1]) |
||||
} |
||||
} |
||||
|
||||
func Test_StreamMarshalJSON(t *testing.T) { |
||||
actual := struct { |
||||
Labels map[string]string `json:"stream"` |
||||
Entries []Entry `json:"values"` |
||||
}{} |
||||
|
||||
for _, expected := range streams { |
||||
|
||||
bytes, err := expected.MarshalJSON() |
||||
require.NoError(t, err) |
||||
|
||||
err = json.Unmarshal(bytes, &actual) |
||||
require.NoError(t, err) |
||||
|
||||
// check labels
|
||||
expectedLabels, err := promql.ParseMetric(expected.Labels) |
||||
require.NoError(t, err) |
||||
|
||||
require.Equal(t, len(actual.Labels), len(expectedLabels)) |
||||
for _, l := range expectedLabels { |
||||
require.Equal(t, l.Value, actual.Labels[l.Name]) |
||||
} |
||||
|
||||
// check entries
|
||||
require.True(t, reflect.DeepEqual(actual.Entries, expected.Entries)) |
||||
} |
||||
} |
||||
Loading…
Reference in new issue