influxdata / influxdata/kapacitor
potential bug in lambda expression
- Dominant language
- Go
- Stars
- 2.4k
- Forks
- 479
- Avg merge
- 4d 16h
- Merged PRs (30d)
- 4
Description
I have following script which generates the alert if cpu percentage usage is beyond 90%, if limit field is not in the stream then I default it to 0 and make sure when it is zero we do not use in division, but still it sometimes it throws division by zero exception, I have attached the stack trace as well.
```
stream
|from()
.database('test')
.measurement('cpu')
|default()
.field('usage_rate', 0)
.field('limit', 0)
|where(lambda: "limit" != 0 AND float("usage_rate" / "limit") > 0.9)
|alert()
.log('/tmp/alerts.log')
```
This TICK script results in following error
```
panic: runtime error: integer divide by zero
goroutine 546 [running]:
panic(0x1cd80c0, 0xc4200180b0)
/usr/local/go/src/runtime/panic.go:500 +0x1a1
github.com/influxdata/kapacitor/tick/stateful.glob..func51(0xc420a02080, 0xc4211b7920, 0x2e40340, 0xc4206c9aa8, 0x2e40340, 0xc4206c9ab0, 0x0, 0x0, 0x0, 0x0, ...)
/root/go/src/github.com/influxdata/kapacitor/tick/stateful/evaluation_funcs.go:1037 +0x258
github.com/influxdata/kapacitor/tick/stateful.(*EvalBinaryNode).eval(0xc420b47b00, 0xc420a02080, 0xc4211b7920, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
/root/go/src/github.com/influxdata/kapacitor/tick/stateful/eval_binary_node.go:249 +0xb3
github.com/influxdata/kapacitor/tick/stateful.(*EvalBinaryNode).evaluateDynamicNode(0xc420b47b00, 0xc420a02080, 0xc4211b7920, 0x2e40340, 0xc4206c9aa8, 0x2e40340, 0xc4206c9ab0, 0x0, 0x0, 0x0, ...)
/root/go/src/github.com/influxdata/kapacitor/tick/stateful/eval_binary_node.go:307 +0x28d
github.com/influxdata/kapacitor/tick/stateful.(*EvalBinaryNode).(github.com/influxdata/kapacitor/tick/stateful.evaluateDynamicNode)-fm(0xc420a02080, 0xc4211b7920, 0x2e40340, 0xc4206c9aa8, 0x2e40340, 0xc4206c9ab0, 0x0, 0x0, 0x0, 0x0, ...)
/root/go/src/github.com/influxdata/kapacitor/tick/stateful/eval_binary_node.go:106 +0xb4
github.com/influxdata/kapacitor/tick/stateful.(*EvalBinaryNode).eval(0xc420b47b00, 0xc420a02080, 0xc4211b7920, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
/root/go/src/github.com/influxdata/kapacitor/tick/stateful/eval_binary_node.go:249 +0xb3
github.com/influxdata/kapacitor/tick/stateful.(*EvalBinaryNode).EvalInt(0xc420b47b00, 0xc420a02080, 0xc4211b7920, 0xc420b68518, 0x1fb1a01, 0x3)
/root/go/src/github.com/influxdata/kapacitor/tick/stateful/eval_binary_node.go:226 +0x5a
github.com/influxdata/kapacitor/tick/stateful.glob..func28(0xc420a02080, 0xc4211b7920, 0x2e3ffc0, 0xc420b47b00, 0x2e40140, 0xc4206dd658, 0x0, 0x0, 0x0, 0x0, ...)
/root/go/src/github.com/influxdata/kapacitor/tick/stateful/evaluation_funcs.go:574 +0x8d
github.com/influxdata/kapacitor/tick/stateful.(*EvalBinaryNode).eval(0xc420b47ac0, 0xc420a02080, 0xc4211b7920, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
/root/go/src/github.com/influxdata/kapacitor/tick/stateful/eval_binary_node.go:249 +0xb3
github.com/influxdata/kapacitor/tick/stateful.(*EvalBinaryNode).evaluateDynamicNode(0xc420b47ac0, 0xc420a02080, 0xc4211b7920, 0x2e3ffc0, 0xc420b47b00, 0x2e40140, 0xc4206dd658, 0x0, 0x0, 0x0, ...)
/root/go/src/github.com/influxdata/kapacitor/tick/stateful/eval_binary_node.go:307 +0x28d
github.com/influxdata/kapacitor/tick/stateful.(*EvalBinaryNode).EvalBool(0xc420b47ac0, 0xc420a02080, 0xc4211b7920, 0x67ad04, 0x0, 0x0)
/root/go/src/github.com/influxdata/kapacitor/tick/stateful/eval_binary_node.go:192 +0xd2
github.com/influxdata/kapacitor/tick/stateful.(*expression).EvalBool(0xc4206757a0, 0xc420a02080, 0xc420a02080, 0x4, 0x0)
/root/go/src/github.com/influxdata/kapacitor/tick/stateful/expr.go:68 +0x46
github.com/influxdata/kapacitor.EvalPredicate(0x2e3f540, 0xc4206757a0, 0x2e2c360, 0xc4211b7980, 0xed1bafe0c, 0xc400000000, 0x2e79fc0, 0xc4209a0000, 0xc420ef4030, 0xc4205c7500, ...)
/root/go/src/github.com/influxdata/kapacitor/expr.go:26 +0x1d9
github.com/influxdata/kapacitor.(*AlertNode).findFirstMatchLevel(0xc4205c7440, 0x3, 0x2, 0xed1bafe0c, 0xc400000000, 0x2e79fc0, 0xc4209a0000, 0xc420ef4030, 0x15, 0x7)
/root/go/src/github.com/influxdata/kapacitor/alert.go:848 +0x148
github.com/influxdata/kapacitor.(*AlertNode).determineLevel(0xc4205c7440, 0xed1bafe0c, 0x0, 0x2e79fc0, 0xc4209a0000, 0xc420ef4030, 0x3, 0xc420b6a000)
/root/go/src/github.com/influxdata/kapacitor/alert.go:822 +0xa9
github.com/influxdata/kapacitor.(*AlertNode).runAlert(0xc4205c7440, 0x0, 0x0, 0x0, 0xc4206b7758, 0xc4206b7768)
/root/go/src/github.com/influxdata/kapacitor/alert.go:524 +0x641
github.com/influxdata/kapacitor.(*AlertNode).(github.com/influxdata/kapacitor.runAlert)-fm(0x0, 0x0, 0x0, 0xc4206b7780, 0xc420bea1e0)
/root/go/src/github.com/influxdata/kapacitor/alert.go:92 +0x48
github.com/influxdata/kapacitor.(*node).start.func1(0xc4205c7440, 0x0, 0x0, 0x0)
/root/go/src/github.com/influxdata/kapacitor/node.go:140 +0x8e
created by github.com/influxdata/kapacitor.(*node).start
/root/go/src/github.com/influxdata/kapacitor/node.go:141 +0x5d
```
Contributor guide
Research direction
Start with the failing TICK script and the stack trace, then inspect tick/stateful/evaluation_funcs.go:1037 and eval_binary_node.go:249-307. Check how the where expression evaluates its operands when limit is zero, and use the existing evaluation path to reproduce the panic. Done means the supplied expression no longer raises division by zero when limit defaults to zero.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100