Fix precision truncation when no timestamp included (#3961)
This commit is contained in:
parent
45e77b3301
commit
52d9a98b09
|
@ -10,13 +10,15 @@ type TimeFunc func() time.Time
|
||||||
|
|
||||||
type Builder struct {
|
type Builder struct {
|
||||||
TimeFunc
|
TimeFunc
|
||||||
|
TimePrecision time.Duration
|
||||||
|
|
||||||
*metric
|
*metric
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBuilder() *Builder {
|
func NewBuilder() *Builder {
|
||||||
b := &Builder{
|
b := &Builder{
|
||||||
TimeFunc: time.Now,
|
TimeFunc: time.Now,
|
||||||
|
TimePrecision: 1 * time.Nanosecond,
|
||||||
}
|
}
|
||||||
b.Reset()
|
b.Reset()
|
||||||
return b
|
return b
|
||||||
|
@ -44,7 +46,7 @@ func (b *Builder) Reset() {
|
||||||
|
|
||||||
func (b *Builder) Metric() (telegraf.Metric, error) {
|
func (b *Builder) Metric() (telegraf.Metric, error) {
|
||||||
if b.tm.IsZero() {
|
if b.tm.IsZero() {
|
||||||
b.tm = b.TimeFunc()
|
b.tm = b.TimeFunc().Truncate(b.TimePrecision)
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.metric, nil
|
return b.metric, nil
|
||||||
|
|
|
@ -33,6 +33,8 @@ const (
|
||||||
DEFAULT_MAX_LINE_SIZE = 64 * 1024
|
DEFAULT_MAX_LINE_SIZE = 64 * 1024
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type TimeFunc func() time.Time
|
||||||
|
|
||||||
type HTTPListener struct {
|
type HTTPListener struct {
|
||||||
ServiceAddress string
|
ServiceAddress string
|
||||||
ReadTimeout internal.Duration
|
ReadTimeout internal.Duration
|
||||||
|
@ -48,6 +50,8 @@ type HTTPListener struct {
|
||||||
BasicUsername string
|
BasicUsername string
|
||||||
BasicPassword string
|
BasicPassword string
|
||||||
|
|
||||||
|
TimeFunc
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
|
|
||||||
|
@ -241,7 +245,7 @@ func (h *HTTPListener) serveWrite(res http.ResponseWriter, req *http.Request) {
|
||||||
tooLarge(res)
|
tooLarge(res)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
now := time.Now()
|
now := h.TimeFunc()
|
||||||
|
|
||||||
precision := req.URL.Query().Get("precision")
|
precision := req.URL.Query().Get("precision")
|
||||||
|
|
||||||
|
@ -340,7 +344,8 @@ func (h *HTTPListener) serveWrite(res http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HTTPListener) parse(b []byte, t time.Time, precision string) error {
|
func (h *HTTPListener) parse(b []byte, t time.Time, precision string) error {
|
||||||
h.handler.SetPrecision(getPrecisionMultiplier(precision))
|
h.handler.SetTimePrecision(getPrecisionMultiplier(precision))
|
||||||
|
h.handler.SetTimeFunc(func() time.Time { return t })
|
||||||
metrics, err := h.parser.Parse(b)
|
metrics, err := h.parser.Parse(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -437,6 +442,7 @@ func init() {
|
||||||
inputs.Add("http_listener", func() telegraf.Input {
|
inputs.Add("http_listener", func() telegraf.Input {
|
||||||
return &HTTPListener{
|
return &HTTPListener{
|
||||||
ServiceAddress: ":8186",
|
ServiceAddress: ":8186",
|
||||||
|
TimeFunc: time.Now,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -26,8 +26,9 @@ func (h *MetricHandler) SetTimeFunc(f metric.TimeFunc) {
|
||||||
h.builder.TimeFunc = f
|
h.builder.TimeFunc = f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *MetricHandler) SetPrecision(factor time.Duration) {
|
func (h *MetricHandler) SetTimePrecision(precision time.Duration) {
|
||||||
h.precision = factor
|
h.builder.TimePrecision = precision
|
||||||
|
h.precision = precision
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *MetricHandler) Metric() (telegraf.Metric, error) {
|
func (h *MetricHandler) Metric() (telegraf.Metric, error) {
|
||||||
|
|
|
@ -21,10 +21,12 @@ var DefaultTime = func() time.Time {
|
||||||
}
|
}
|
||||||
|
|
||||||
var ptests = []struct {
|
var ptests = []struct {
|
||||||
name string
|
name string
|
||||||
input []byte
|
input []byte
|
||||||
metrics []telegraf.Metric
|
timeFunc func() time.Time
|
||||||
err error
|
precision time.Duration
|
||||||
|
metrics []telegraf.Metric
|
||||||
|
err error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "minimal",
|
name: "minimal",
|
||||||
|
@ -406,7 +408,7 @@ var ptests = []struct {
|
||||||
err: nil,
|
err: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "default timestamp",
|
name: "no timestamp",
|
||||||
input: []byte("cpu value=42"),
|
input: []byte("cpu value=42"),
|
||||||
metrics: []telegraf.Metric{
|
metrics: []telegraf.Metric{
|
||||||
Metric(
|
Metric(
|
||||||
|
@ -422,6 +424,47 @@ var ptests = []struct {
|
||||||
},
|
},
|
||||||
err: nil,
|
err: nil,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "no timestamp full precision",
|
||||||
|
input: []byte("cpu value=42"),
|
||||||
|
timeFunc: func() time.Time {
|
||||||
|
return time.Unix(42, 123456789)
|
||||||
|
},
|
||||||
|
metrics: []telegraf.Metric{
|
||||||
|
Metric(
|
||||||
|
metric.New(
|
||||||
|
"cpu",
|
||||||
|
map[string]string{},
|
||||||
|
map[string]interface{}{
|
||||||
|
"value": 42.0,
|
||||||
|
},
|
||||||
|
time.Unix(42, 123456789),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
err: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no timestamp partial precision",
|
||||||
|
input: []byte("cpu value=42"),
|
||||||
|
timeFunc: func() time.Time {
|
||||||
|
return time.Unix(42, 123456789)
|
||||||
|
},
|
||||||
|
precision: 1 * time.Millisecond,
|
||||||
|
metrics: []telegraf.Metric{
|
||||||
|
Metric(
|
||||||
|
metric.New(
|
||||||
|
"cpu",
|
||||||
|
map[string]string{},
|
||||||
|
map[string]interface{}{
|
||||||
|
"value": 42.0,
|
||||||
|
},
|
||||||
|
time.Unix(42, 123000000),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
err: nil,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "multiple lines",
|
name: "multiple lines",
|
||||||
input: []byte("cpu value=42\ncpu value=42"),
|
input: []byte("cpu value=42\ncpu value=42"),
|
||||||
|
@ -538,6 +581,12 @@ func TestParser(t *testing.T) {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
handler := NewMetricHandler()
|
handler := NewMetricHandler()
|
||||||
handler.SetTimeFunc(DefaultTime)
|
handler.SetTimeFunc(DefaultTime)
|
||||||
|
if tt.timeFunc != nil {
|
||||||
|
handler.SetTimeFunc(tt.timeFunc)
|
||||||
|
}
|
||||||
|
if tt.precision > 0 {
|
||||||
|
handler.SetTimePrecision(tt.precision)
|
||||||
|
}
|
||||||
parser := NewParser(handler)
|
parser := NewParser(handler)
|
||||||
|
|
||||||
metrics, err := parser.Parse(tt.input)
|
metrics, err := parser.Parse(tt.input)
|
||||||
|
|
Loading…
Reference in New Issue