Fix precision truncation when no timestamp included (#3961)
This commit is contained in:
parent
9d2f3fcbb9
commit
bcaaeda49c
|
@ -10,13 +10,15 @@ type TimeFunc func() time.Time
|
|||
|
||||
type Builder struct {
|
||||
TimeFunc
|
||||
TimePrecision time.Duration
|
||||
|
||||
*metric
|
||||
}
|
||||
|
||||
func NewBuilder() *Builder {
|
||||
b := &Builder{
|
||||
TimeFunc: time.Now,
|
||||
TimeFunc: time.Now,
|
||||
TimePrecision: 1 * time.Nanosecond,
|
||||
}
|
||||
b.Reset()
|
||||
return b
|
||||
|
@ -44,7 +46,7 @@ func (b *Builder) Reset() {
|
|||
|
||||
func (b *Builder) Metric() (telegraf.Metric, error) {
|
||||
if b.tm.IsZero() {
|
||||
b.tm = b.TimeFunc()
|
||||
b.tm = b.TimeFunc().Truncate(b.TimePrecision)
|
||||
}
|
||||
|
||||
return b.metric, nil
|
||||
|
|
|
@ -33,6 +33,8 @@ const (
|
|||
DEFAULT_MAX_LINE_SIZE = 64 * 1024
|
||||
)
|
||||
|
||||
type TimeFunc func() time.Time
|
||||
|
||||
type HTTPListener struct {
|
||||
ServiceAddress string
|
||||
ReadTimeout internal.Duration
|
||||
|
@ -48,6 +50,8 @@ type HTTPListener struct {
|
|||
BasicUsername string
|
||||
BasicPassword string
|
||||
|
||||
TimeFunc
|
||||
|
||||
mu sync.Mutex
|
||||
wg sync.WaitGroup
|
||||
|
||||
|
@ -241,7 +245,7 @@ func (h *HTTPListener) serveWrite(res http.ResponseWriter, req *http.Request) {
|
|||
tooLarge(res)
|
||||
return
|
||||
}
|
||||
now := time.Now()
|
||||
now := h.TimeFunc()
|
||||
|
||||
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 {
|
||||
h.handler.SetPrecision(getPrecisionMultiplier(precision))
|
||||
h.handler.SetTimePrecision(getPrecisionMultiplier(precision))
|
||||
h.handler.SetTimeFunc(func() time.Time { return t })
|
||||
metrics, err := h.parser.Parse(b)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -437,6 +442,7 @@ func init() {
|
|||
inputs.Add("http_listener", func() telegraf.Input {
|
||||
return &HTTPListener{
|
||||
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
|
||||
}
|
||||
|
||||
func (h *MetricHandler) SetPrecision(factor time.Duration) {
|
||||
h.precision = factor
|
||||
func (h *MetricHandler) SetTimePrecision(precision time.Duration) {
|
||||
h.builder.TimePrecision = precision
|
||||
h.precision = precision
|
||||
}
|
||||
|
||||
func (h *MetricHandler) Metric() (telegraf.Metric, error) {
|
||||
|
|
|
@ -21,10 +21,12 @@ var DefaultTime = func() time.Time {
|
|||
}
|
||||
|
||||
var ptests = []struct {
|
||||
name string
|
||||
input []byte
|
||||
metrics []telegraf.Metric
|
||||
err error
|
||||
name string
|
||||
input []byte
|
||||
timeFunc func() time.Time
|
||||
precision time.Duration
|
||||
metrics []telegraf.Metric
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "minimal",
|
||||
|
@ -406,7 +408,7 @@ var ptests = []struct {
|
|||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "default timestamp",
|
||||
name: "no timestamp",
|
||||
input: []byte("cpu value=42"),
|
||||
metrics: []telegraf.Metric{
|
||||
Metric(
|
||||
|
@ -422,6 +424,47 @@ var ptests = []struct {
|
|||
},
|
||||
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",
|
||||
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) {
|
||||
handler := NewMetricHandler()
|
||||
handler.SetTimeFunc(DefaultTime)
|
||||
if tt.timeFunc != nil {
|
||||
handler.SetTimeFunc(tt.timeFunc)
|
||||
}
|
||||
if tt.precision > 0 {
|
||||
handler.SetTimePrecision(tt.precision)
|
||||
}
|
||||
parser := NewParser(handler)
|
||||
|
||||
metrics, err := parser.Parse(tt.input)
|
||||
|
|
Loading…
Reference in New Issue