master
md 115 lines 3.39 KB
Rendered Raw
1 # Netdata Expression Evaluator
2
3 This directory contains Netdata's Expression Evaluator, a component for evaluating mathematical and logical expressions in Netdata's health monitoring, alerts, and data processing pipelines.
4
5 ## Overview
6
7 The expression evaluator is a parser and interpreter for mathematical, logical, and comparison expressions. It supports:
8
9 - Arithmetic operations (`+`, `-`, `*`, `/`, `%`)
10 - Logical operations (`AND`/`&&`, `OR`/`||`, `NOT`/`!`)
11 - Comparison operations (`==`, `!=`, `>`, `>=`, `<`, `<=`)
12 - Ternary conditional operator (`? :`)
13 - Function calls (e.g., `abs()`)
14 - Variables (e.g., `$var1`)
15
16 Expressions are used in Netdata's alert definitions, and other areas that require dynamic computation.
17
18 ## Implementation
19
20 The expression evaluator has two parser implementations:
21
22 1. **Original Recursive Descent Parser** - A handwritten parser in `eval-parser-legacy.c`
23 2. **re2c/Lemon Parser** - A more efficient parser using re2c for lexical analysis and Lemon for grammar parsing in the `re2c_lemon/` subdirectory
24
25 The implementation can be switched between these two parsers using the `USE_RE2C_LEMON_PARSER` define in `eval-internal.h`.
26
27 ## Key Components
28
29 - **eval.h** - Public API for the expression evaluator
30 - **eval-internal.h** - Internal structures and parser selection switch
31 - **eval-parser.c** - Original recursive descent parser implementation
32 - **eval-execute.c** - Expression evaluation engine
33 - **eval-utils.c** - Helper functions for working with expression nodes
34 - **eval-unittest.c** - Comprehensive test suite for the evaluator
35 - **re2c_lemon/** - Subdirectory containing the re2c/Lemon-based parser implementation
36
37 ## Expression Syntax
38
39 The evaluator supports a C-like syntax:
40
41 ```
42 # Arithmetic
43 42 + 24
44 5 * (3 + 2)
45
46 # Comparisons
47 $temp > 80
48 $load >= $threshold
49
50 # Logical operations
51 $cpu_util > 90 && $mem_usage > 80
52 $disk_full || $inode_usage > 95
53
54 # Ternary operator
55 $status == $WARNING ? 90 : 75
56
57 # Functions
58 abs($value)
59 ```
60
61 Variables are prefixed with `$` and can be either simple names (`$var`) or use braces for complex names (`${variable name with spaces}`).
62
63 ## Special Features
64
65 - Case-insensitive handling of logical operators: `AND`/`and`/`&&` are equivalent
66 - Support for special numeric literals: `nan` and `inf` (any capitalization)
67 - Short-circuit evaluation of logical operators
68 - NaN and Infinity handling in calculations
69
70 ## Usage
71
72 To use the expression evaluator in Netdata code:
73
74 ```c
75 #include "libnetdata/eval/eval.h"
76
77 // Parse an expression
78 const char *expr = "$value > 100 && $status != 0";
79 const char *failed_at = NULL;
80 int error = 0;
81 EVAL_EXPRESSION *exp = expression_parse(expr, &failed_at, &error);
82
83 if (!exp) {
84 // Handle parsing error
85 printf("Error parsing expression at: %s\n", failed_at);
86 printf("Error code: %d (%s)\n", error, expression_strerror(error));
87 return;
88 }
89
90 // Set up variable lookup callback
91 expression_set_variable_lookup_callback(exp, my_variable_lookup_function, my_data);
92
93 // Evaluate the expression
94 if (expression_evaluate(exp)) {
95 // Get the result
96 NETDATA_DOUBLE result = expression_result(exp);
97 printf("Result: %f\n", result);
98 } else {
99 // Handle evaluation error
100 printf("Evaluation error: %s\n", expression_error_msg(exp));
101 }
102
103 // Free the expression
104 expression_free(exp);
105 ```
106
107 ## Testing
108
109 The evaluator includes a comprehensive test suite in `eval-unittest.c`. Run it using:
110
111 ```
112 netdata -W evaltest
113 ```
114
115 All these tests run also at CI.