Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e393c3af3f
commit
4978089aab
4963 changed files with 677545 additions and 0 deletions
291
plugins/processors/starlark/README.md
Normal file
291
plugins/processors/starlark/README.md
Normal file
|
@ -0,0 +1,291 @@
|
|||
# Starlark Processor Plugin
|
||||
|
||||
The `starlark` processor calls a Starlark function for each matched metric,
|
||||
allowing for custom programmatic metric processing.
|
||||
|
||||
The Starlark language is a dialect of Python, and will be familiar to those who
|
||||
have experience with the Python language. However, there are major
|
||||
[differences](#python-differences). Existing Python code is unlikely to work
|
||||
unmodified. The execution environment is sandboxed, and it is not possible to
|
||||
do I/O operations such as reading from files or sockets.
|
||||
|
||||
The **[Starlark specification][]** has details about the syntax and available
|
||||
functions.
|
||||
|
||||
Telegraf minimum version: Telegraf 1.15.0
|
||||
|
||||
## Global configuration options <!-- @/docs/includes/plugin_config.md -->
|
||||
|
||||
In addition to the plugin-specific configuration settings, plugins support
|
||||
additional global and plugin configuration settings. These settings are used to
|
||||
modify metrics, tags, and field or create aliases and configure ordering, etc.
|
||||
See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
|
||||
|
||||
[CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins
|
||||
|
||||
## Configuration
|
||||
|
||||
```toml @sample.conf
|
||||
# Process metrics using a Starlark script
|
||||
[[processors.starlark]]
|
||||
## The Starlark source can be set as a string in this configuration file, or
|
||||
## by referencing a file containing the script. Only one source or script
|
||||
## should be set at once.
|
||||
|
||||
## Source of the Starlark script.
|
||||
source = '''
|
||||
def apply(metric):
|
||||
return metric
|
||||
'''
|
||||
|
||||
## File containing a Starlark script.
|
||||
# script = "/usr/local/bin/myscript.star"
|
||||
|
||||
## The constants of the Starlark script.
|
||||
# [processors.starlark.constants]
|
||||
# max_size = 10
|
||||
# threshold = 0.75
|
||||
# default_name = "Julia"
|
||||
# debug_mode = true
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
The Starlark code should contain a function called `apply` that takes a metric
|
||||
as its single argument. The function will be called with each metric, and can
|
||||
return `None`, a single metric, or a list of metrics.
|
||||
|
||||
```python
|
||||
def apply(metric):
|
||||
return metric
|
||||
```
|
||||
|
||||
For a list of available types and functions that can be used in the code, see
|
||||
the [Starlark specification][].
|
||||
|
||||
In addition to these, the following InfluxDB-specific
|
||||
types and functions are exposed to the script.
|
||||
|
||||
- **Metric(*name*)**:
|
||||
Create a new metric with the given measurement name. The metric will have no
|
||||
tags or fields and defaults to the current time.
|
||||
|
||||
- **name**:
|
||||
The name is a [string][] containing the metric measurement name.
|
||||
|
||||
- **tags**:
|
||||
A [dict-like][dict] object containing the metric's tags.
|
||||
|
||||
- **fields**:
|
||||
A [dict-like][dict] object containing the metric's fields. The values may be
|
||||
of type int, float, string, or bool.
|
||||
|
||||
- **time**:
|
||||
The timestamp of the metric as an integer in nanoseconds since the Unix
|
||||
epoch.
|
||||
|
||||
- **deepcopy(*metric*, *track=false*)**:
|
||||
Copy an existing metric with or without tracking information. If `track` is set
|
||||
to `true`, the tracking information is copied.
|
||||
**Caution:** Make sure to always return *all* metrics with tracking information!
|
||||
Otherwise, the corresponding inputs will never receive the delivery information
|
||||
and potentially overrun!
|
||||
|
||||
### Python Differences
|
||||
|
||||
While Starlark is similar to Python, there are important differences to note:
|
||||
|
||||
- Starlark has limited support for error handling and no exceptions. If an
|
||||
error occurs the script will immediately end and Telegraf will drop the
|
||||
metric. Check the Telegraf logfile for details about the error.
|
||||
|
||||
- It is not possible to import other packages and the Python standard library
|
||||
is not available.
|
||||
|
||||
- It is not possible to open files or sockets.
|
||||
|
||||
- These common keywords are **not supported** in the Starlark grammar:
|
||||
|
||||
```text
|
||||
as finally nonlocal
|
||||
assert from raise
|
||||
class global try
|
||||
del import with
|
||||
except is yield
|
||||
```
|
||||
|
||||
### Libraries available
|
||||
|
||||
The ability to load external scripts other than your own is pretty limited. The
|
||||
following libraries are available for loading:
|
||||
|
||||
- json: `load("json.star", "json")` provides the following functions: `json.encode()`, `json.decode()`, `json.indent()`. See [json.star](testdata/json.star) for an example. For more details about the functions, please refer to [the documentation of this library](https://pkg.go.dev/go.starlark.net/lib/json).
|
||||
- log: `load("logging.star", "log")` provides the following functions: `log.debug()`, `log.info()`, `log.warn()`, `log.error()`. See [logging.star](testdata/logging.star) for an example.
|
||||
- math: `load("math.star", "math")` provides [the following functions and constants](https://pkg.go.dev/go.starlark.net/lib/math). See [math.star](testdata/math.star) for an example.
|
||||
- time: `load("time.star", "time")` provides the following functions: `time.from_timestamp()`, `time.is_valid_timezone()`, `time.now()`, `time.parse_duration()`, `time.parse_time()`, `time.time()`. See [time_date.star](testdata/time_date.star), [time_duration.star](testdata/time_duration.star) and/or [time_timestamp.star](testdata/time_timestamp.star) for an example. For more details about the functions, please refer to [the documentation of this library](https://pkg.go.dev/go.starlark.net/lib/time).
|
||||
|
||||
If you would like to see support for something else here, please open an issue.
|
||||
|
||||
### Common Questions
|
||||
|
||||
**What's the performance cost to using Starlark?**
|
||||
|
||||
In local tests, it takes about 1µs (1 microsecond) to run a modest script to
|
||||
process one metric. This is going to vary with the size of your script, but the
|
||||
total impact is minimal. At this pace, it's likely not going to be the
|
||||
bottleneck in your Telegraf setup.
|
||||
|
||||
**How can I drop/delete a metric?**
|
||||
|
||||
If you don't return the metric it will be deleted. Usually this means the
|
||||
function should `return None`.
|
||||
|
||||
**How should I make a copy of a metric?**
|
||||
|
||||
Use `deepcopy(metric)` to create a copy of the metric.
|
||||
|
||||
**How can I return multiple metrics?**
|
||||
|
||||
You can return a list of metrics:
|
||||
|
||||
```python
|
||||
def apply(metric):
|
||||
m2 = deepcopy(metric)
|
||||
return [metric, m2]
|
||||
```
|
||||
|
||||
**What happens to a tracking metric if an error occurs in the script?**
|
||||
|
||||
The metric is marked as undelivered.
|
||||
|
||||
**How do I create a new metric?**
|
||||
|
||||
Use the `Metric(name)` function and set at least one field.
|
||||
|
||||
**What is the fastest way to iterate over tags/fields?**
|
||||
|
||||
The fastest way to iterate is to use a for-loop on the tags or fields attribute:
|
||||
|
||||
```python
|
||||
def apply(metric):
|
||||
for k in metric.tags:
|
||||
pass
|
||||
return metric
|
||||
```
|
||||
|
||||
When you use this form, it is not possible to modify the tags inside the loop,
|
||||
if this is needed you should use one of the `.keys()`, `.values()`, or
|
||||
`.items()` methods:
|
||||
|
||||
```python
|
||||
def apply(metric):
|
||||
for k, v in metric.tags.items():
|
||||
pass
|
||||
return metric
|
||||
```
|
||||
|
||||
**How can I save values across multiple calls to the script?**
|
||||
|
||||
Telegraf freezes the global scope, which prevents it from being modified, except
|
||||
for a special shared global dictionary named `state`, this can be used by the
|
||||
`apply` function. See an example of this in [compare with previous
|
||||
metric](testdata/compare_metrics.star)
|
||||
|
||||
Other than the `state` variable, attempting to modify the global scope will fail
|
||||
with an error.
|
||||
|
||||
**How to manage errors that occur in the apply function?**
|
||||
|
||||
In case you need to call some code that may return an error, you can delegate
|
||||
the call to the built-in function `catch` which takes as argument a `Callable`
|
||||
and returns the error that occurred if any, `None` otherwise.
|
||||
|
||||
So for example:
|
||||
|
||||
```python
|
||||
load("json.star", "json")
|
||||
|
||||
def apply(metric):
|
||||
error = catch(lambda: failing(metric))
|
||||
if error != None:
|
||||
# Some code to execute in case of an error
|
||||
metric.fields["error"] = error
|
||||
return metric
|
||||
|
||||
def failing(metric):
|
||||
json.decode("non-json-content")
|
||||
```
|
||||
|
||||
**How to reuse the same script but with different parameters?**
|
||||
|
||||
In case you have a generic script that you would like to reuse for different
|
||||
instances of the plugin, you can use constants as input parameters of your
|
||||
script.
|
||||
|
||||
So for example, assuming that you have the next configuration:
|
||||
|
||||
```toml
|
||||
[[processors.starlark]]
|
||||
script = "/usr/local/bin/myscript.star"
|
||||
|
||||
[processors.starlark.constants]
|
||||
somecustomnum = 10
|
||||
somecustomstr = "mycustomfield"
|
||||
```
|
||||
|
||||
Your script could then use the constants defined in the configuration as
|
||||
follows:
|
||||
|
||||
```python
|
||||
def apply(metric):
|
||||
if metric.fields[somecustomstr] >= somecustomnum:
|
||||
metric.fields.clear()
|
||||
return metric
|
||||
```
|
||||
|
||||
**What does `cannot represent integer ...` mean?**
|
||||
|
||||
The error occurs if an integer value in starlark exceeds the signed 64 bit
|
||||
integer limit. This can occur if you are summing up large values in a starlark
|
||||
integer value or convert an unsigned 64 bit integer to starlark and then create
|
||||
a new metric field from it.
|
||||
|
||||
This is due to the fact that integer values in starlark are *always* signed and
|
||||
can grow beyond the 64-bit size. Therefore converting the value back fails in
|
||||
the cases mentioned above.
|
||||
|
||||
As a workaround you can either clip the field value at the signed 64-bit limit
|
||||
or return the value as a floating-point number.
|
||||
|
||||
### Examples
|
||||
|
||||
- [drop string fields](testdata/drop_string_fields.star) - Drop fields containing string values.
|
||||
- [drop fields with unexpected type](testdata/drop_fields_with_unexpected_type.star) - Drop fields containing unexpected value types.
|
||||
- [iops](testdata/iops.star) - obtain IOPS (to aggregate, to produce max_iops)
|
||||
- [json](testdata/json.star) - an example of processing JSON from a field in a metric
|
||||
- [math](testdata/math.star) - Use a math function to compute the value of a field. [The list of the supported math functions and constants](https://pkg.go.dev/go.starlark.net/lib/math).
|
||||
- [number logic](testdata/number_logic.star) - transform a numerical value to another numerical value
|
||||
- [pivot](testdata/pivot.star) - Pivots a key's value to be the key for another key.
|
||||
- [ratio](testdata/ratio.star) - Compute the ratio of two integer fields
|
||||
- [rename](testdata/rename.star) - Rename tags or fields using a name mapping.
|
||||
- [scale](testdata/scale.star) - Multiply any field by a number
|
||||
- [time date](testdata/time_date.star) - Parse a date and extract the year, month and day from it.
|
||||
- [time duration](testdata/time_duration.star) - Parse a duration and convert it into a total amount of seconds.
|
||||
- [time timestamp](testdata/time_timestamp.star) - Filter metrics based on the timestamp in seconds.
|
||||
- [time timestamp nanoseconds](testdata/time_timestamp_nanos.star) - Filter metrics based on the timestamp with nanoseconds.
|
||||
- [time timestamp current](testdata/time_set_timestamp.star) - Setting the metric timestamp to the current/local time.
|
||||
- [value filter](testdata/value_filter.star) - Remove a metric based on a field value.
|
||||
- [logging](testdata/logging.star) - Log messages with the logger of Telegraf
|
||||
- [multiple metrics](testdata/multiple_metrics.star) - Return multiple metrics by using [a list](https://docs.bazel.build/versions/master/skylark/lib/list.html) of metrics.
|
||||
- [multiple metrics from json array](testdata/multiple_metrics_with_json.star) - Builds a new metric from each element of a json array then returns all the created metrics.
|
||||
- [custom error](testdata/fail.star) - Return a custom error with [fail](https://docs.bazel.build/versions/master/skylark/lib/globals.html#fail).
|
||||
- [compare with previous metric](testdata/compare_metrics.star) - Compare the current metric with the previous one using the shared state.
|
||||
- [rename prometheus remote write](testdata/rename_prometheus_remote_write.star) - Rename prometheus remote write measurement name with fieldname and rename fieldname to value.
|
||||
|
||||
[All examples](testdata) are in the testdata folder.
|
||||
|
||||
Open a Pull Request to add any other useful Starlark examples.
|
||||
|
||||
[Starlark specification]: https://github.com/google/starlark-go/blob/d1966c6b9fcd/doc/spec.md
|
||||
[string]: https://github.com/google/starlark-go/blob/d1966c6b9fcd/doc/spec.md#strings
|
||||
[dict]: https://github.com/google/starlark-go/blob/d1966c6b9fcd/doc/spec.md#dictionaries
|
Loading…
Add table
Add a link
Reference in a new issue