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
88
plugins/inputs/mock/README.md
Normal file
88
plugins/inputs/mock/README.md
Normal file
|
@ -0,0 +1,88 @@
|
|||
# Mock Data Input Plugin
|
||||
|
||||
The plugin generates mock-metrics based on different algorithms like sine-wave
|
||||
functions, random numbers and more with the configured names and tags. Those
|
||||
metrics are usefull during testing (e.g. processors) or if random data is
|
||||
required.
|
||||
|
||||
⭐ Telegraf v1.22.0
|
||||
🏷️ testing
|
||||
💻 all
|
||||
|
||||
## 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
|
||||
# Generate metrics for test and demonstration purposes
|
||||
[[inputs.mock]]
|
||||
## Set the metric name to use for reporting
|
||||
metric_name = "mock"
|
||||
|
||||
## Optional string key-value pairs of tags to add to all metrics
|
||||
# [inputs.mock.tags]
|
||||
# "key" = "value"
|
||||
|
||||
## One or more mock data fields *must* be defined.
|
||||
# [[inputs.mock.constant]]
|
||||
# name = "constant"
|
||||
# value = value_of_any_type
|
||||
# [[inputs.mock.random]]
|
||||
# name = "rand"
|
||||
# min = 1.0
|
||||
# max = 6.0
|
||||
# [[inputs.mock.sine_wave]]
|
||||
# name = "wave"
|
||||
# amplitude = 1.0
|
||||
# period = 0.5
|
||||
# phase = 20.0
|
||||
# base_line = 0.0
|
||||
# [[inputs.mock.step]]
|
||||
# name = "plus_one"
|
||||
# start = 0.0
|
||||
# step = 1.0
|
||||
# [[inputs.mock.stock]]
|
||||
# name = "abc"
|
||||
# price = 50.00
|
||||
# volatility = 0.2
|
||||
```
|
||||
|
||||
The mock plugin only requires that:
|
||||
|
||||
1) Metric name is set
|
||||
2) One of the data field algorithms is defined
|
||||
|
||||
## Available Algorithms
|
||||
|
||||
The available algorithms for generating mock data include:
|
||||
|
||||
* `constant`: generate a field with the given value of type string, float, int
|
||||
or bool
|
||||
* `random`: generate a random float, inclusive of min and max
|
||||
* `sine_wave`: produce a sine wave with a certain amplitude, period and baseline
|
||||
* `step`: always add the step value, negative values accepted
|
||||
* `stock`: generate fake, stock-like price values based on a volatility variable
|
||||
|
||||
## Metrics
|
||||
|
||||
Metrics are entirely based on the user's own configuration and settings.
|
||||
|
||||
## Example Output
|
||||
|
||||
The following example shows all available algorithms configured with an
|
||||
additional two tags as well:
|
||||
|
||||
```text
|
||||
mock_sensors,building=5A,site=FTC random=4.875966794516125,abc=50,wave=0,plus_one=0 1632170840000000000
|
||||
mock_sensors,building=5A,site=FTC random=5.738651873834452,abc=45.095549448434774,wave=5.877852522924732,plus_one=1 1632170850000000000
|
||||
mock_sensors,building=5A,site=FTC random=1.0429328917205203,abc=51.928560083072924,wave=9.510565162951535,plus_one=2 1632170860000000000
|
||||
mock_sensors,building=5A,site=FTC random=5.290188595384418,abc=44.41090520217027,wave=9.510565162951536,plus_one=3 1632170870000000000
|
||||
mock_sensors,building=5A,site=FTC random=2.0724967227069135,abc=47.212167806890314,wave=5.877852522924733,plus_one=4 1632170880000000000
|
||||
```
|
162
plugins/inputs/mock/mock.go
Normal file
162
plugins/inputs/mock/mock.go
Normal file
|
@ -0,0 +1,162 @@
|
|||
//go:generate ../../../tools/readme_config_includer/generator
|
||||
package mock
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"math"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
//go:embed sample.conf
|
||||
var sampleConfig string
|
||||
|
||||
type Mock struct {
|
||||
MetricName string `toml:"metric_name"`
|
||||
Tags map[string]string `toml:"tags"`
|
||||
|
||||
Constant []*constant `toml:"constant"`
|
||||
Random []*random `toml:"random"`
|
||||
Step []*step `toml:"step"`
|
||||
Stock []*stock `toml:"stock"`
|
||||
SineWave []*sineWave `toml:"sine_wave"`
|
||||
|
||||
counter int64
|
||||
rand *rand.Rand
|
||||
}
|
||||
|
||||
type constant struct {
|
||||
Name string `toml:"name"`
|
||||
Value interface{} `toml:"value"`
|
||||
}
|
||||
|
||||
type random struct {
|
||||
Name string `toml:"name"`
|
||||
Min float64 `toml:"min"`
|
||||
Max float64 `toml:"max"`
|
||||
}
|
||||
|
||||
type sineWave struct {
|
||||
Name string `toml:"name"`
|
||||
Amplitude float64 `toml:"amplitude"`
|
||||
Period float64 `toml:"period"`
|
||||
Phase float64 `toml:"phase"`
|
||||
BaseLine float64 `toml:"base_line"`
|
||||
}
|
||||
|
||||
type step struct {
|
||||
Name string `toml:"name"`
|
||||
Start float64 `toml:"start"`
|
||||
Step float64 `toml:"step"`
|
||||
|
||||
Min float64 `toml:"min" deprecated:"1.28.2;1.35.0;use 'start' instead"`
|
||||
Max float64 `toml:"max" deprecated:"1.28.2;1.35.0;use 'step' instead"`
|
||||
|
||||
latest float64
|
||||
}
|
||||
|
||||
type stock struct {
|
||||
Name string `toml:"name"`
|
||||
Price float64 `toml:"price"`
|
||||
Volatility float64 `toml:"volatility"`
|
||||
|
||||
latest float64
|
||||
}
|
||||
|
||||
func (*Mock) SampleConfig() string {
|
||||
return sampleConfig
|
||||
}
|
||||
|
||||
func (m *Mock) Init() error {
|
||||
m.rand = rand.New(rand.NewSource(time.Now().UnixNano())) //nolint:gosec // G404: not security critical
|
||||
|
||||
// backward compatibility
|
||||
for _, step := range m.Step {
|
||||
if step.Min != 0 && step.Start == 0 {
|
||||
step.Start = step.Min
|
||||
}
|
||||
if step.Max != 0 && step.Step == 0 {
|
||||
step.Step = step.Max
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Mock) Gather(acc telegraf.Accumulator) error {
|
||||
fields := make(map[string]interface{})
|
||||
m.generateRandomFloat64(fields)
|
||||
m.generateStockPrice(fields)
|
||||
m.generateSineWave(fields)
|
||||
m.generateStep(fields)
|
||||
|
||||
for _, c := range m.Constant {
|
||||
fields[c.Name] = c.Value
|
||||
}
|
||||
|
||||
tags := make(map[string]string)
|
||||
for key, value := range m.Tags {
|
||||
tags[key] = value
|
||||
}
|
||||
|
||||
acc.AddFields(m.MetricName, fields, tags)
|
||||
|
||||
m.counter++
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Generate random value between min and max, inclusively
|
||||
func (m *Mock) generateRandomFloat64(fields map[string]interface{}) {
|
||||
for _, random := range m.Random {
|
||||
fields[random.Name] = random.Min + m.rand.Float64()*(random.Max-random.Min)
|
||||
}
|
||||
}
|
||||
|
||||
// Create sine waves
|
||||
func (m *Mock) generateSineWave(fields map[string]interface{}) {
|
||||
for _, field := range m.SineWave {
|
||||
fields[field.Name] = math.Sin((float64(m.counter)+field.Phase)*field.Period*math.Pi)*field.Amplitude + field.BaseLine
|
||||
}
|
||||
}
|
||||
|
||||
// Begin at start value and then add step value every tick
|
||||
func (m *Mock) generateStep(fields map[string]interface{}) {
|
||||
for _, step := range m.Step {
|
||||
if m.counter == 0 {
|
||||
step.latest = step.Start
|
||||
} else {
|
||||
step.latest += step.Step
|
||||
}
|
||||
|
||||
fields[step.Name] = step.latest
|
||||
}
|
||||
}
|
||||
|
||||
// Begin at start price and then generate random value
|
||||
func (m *Mock) generateStockPrice(fields map[string]interface{}) {
|
||||
for _, stock := range m.Stock {
|
||||
if stock.latest == 0.0 {
|
||||
stock.latest = stock.Price
|
||||
} else {
|
||||
noise := 2 * (m.rand.Float64() - 0.5)
|
||||
stock.latest = stock.latest + (stock.latest * stock.Volatility * noise)
|
||||
|
||||
// avoid going below zero
|
||||
if stock.latest < 1.0 {
|
||||
stock.latest = 1.0
|
||||
}
|
||||
}
|
||||
|
||||
fields[stock.Name] = stock.latest
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
inputs.Add("mock", func() telegraf.Input {
|
||||
return &Mock{}
|
||||
})
|
||||
}
|
110
plugins/inputs/mock/mock_test.go
Normal file
110
plugins/inputs/mock/mock_test.go
Normal file
|
@ -0,0 +1,110 @@
|
|||
package mock
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
func TestGather(t *testing.T) {
|
||||
testConstantString := &constant{
|
||||
Name: "constant_string",
|
||||
Value: "a string",
|
||||
}
|
||||
testConstantFloat := &constant{
|
||||
Name: "constant_float",
|
||||
Value: 3.1415,
|
||||
}
|
||||
testConstantInt := &constant{
|
||||
Name: "constant_int",
|
||||
Value: 42,
|
||||
}
|
||||
testConstantBool := &constant{
|
||||
Name: "constant_bool",
|
||||
Value: true,
|
||||
}
|
||||
testRandom := &random{
|
||||
Name: "random",
|
||||
Min: 1.0,
|
||||
Max: 6.0,
|
||||
}
|
||||
testSineWave := &sineWave{
|
||||
Name: "sine",
|
||||
Amplitude: 1.0,
|
||||
Period: 0.5,
|
||||
BaseLine: 2.0,
|
||||
}
|
||||
testStep := &step{
|
||||
Name: "step",
|
||||
Start: 0.0,
|
||||
Step: 1.0,
|
||||
}
|
||||
testStock := &stock{
|
||||
Name: "abc",
|
||||
Price: 50.00,
|
||||
Volatility: 0.2,
|
||||
}
|
||||
|
||||
tags := map[string]string{
|
||||
"buildling": "tbd",
|
||||
"site": "nowhere",
|
||||
}
|
||||
|
||||
m := &Mock{
|
||||
MetricName: "test",
|
||||
Tags: tags,
|
||||
|
||||
Constant: []*constant{testConstantString, testConstantFloat, testConstantInt, testConstantBool},
|
||||
Random: []*random{testRandom},
|
||||
SineWave: []*sineWave{testSineWave},
|
||||
Step: []*step{testStep},
|
||||
Stock: []*stock{testStock},
|
||||
}
|
||||
|
||||
var acc testutil.Accumulator
|
||||
require.NoError(t, m.Init())
|
||||
require.NoError(t, m.Gather(&acc))
|
||||
|
||||
require.Len(t, acc.Metrics, 1)
|
||||
|
||||
metric := acc.Metrics[0]
|
||||
require.Equal(t, "test", metric.Measurement)
|
||||
require.Equal(t, tags, metric.Tags)
|
||||
for k, v := range metric.Fields {
|
||||
switch k {
|
||||
case "abc":
|
||||
require.InDelta(t, 50.0, v, testutil.DefaultDelta)
|
||||
case "constant_string":
|
||||
require.Equal(t, testConstantString.Value, v)
|
||||
case "constant_float":
|
||||
require.Equal(t, testConstantFloat.Value, v)
|
||||
case "constant_int":
|
||||
require.Equal(t, testConstantInt.Value, v)
|
||||
case "constant_bool":
|
||||
require.Equal(t, testConstantBool.Value, v)
|
||||
case "random":
|
||||
require.GreaterOrEqual(t, 6.0, v)
|
||||
require.LessOrEqual(t, 1.0, v)
|
||||
case "sine":
|
||||
require.InDelta(t, 2.0, v, testutil.DefaultDelta)
|
||||
case "step":
|
||||
require.InDelta(t, 0.0, v, testutil.DefaultDelta)
|
||||
default:
|
||||
require.Failf(t, "Unexpected field", "Extra field: %q", k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGatherEmpty(t *testing.T) {
|
||||
m := &Mock{
|
||||
MetricName: "test_empty",
|
||||
}
|
||||
|
||||
var acc testutil.Accumulator
|
||||
require.NoError(t, m.Init())
|
||||
require.NoError(t, m.Gather(&acc))
|
||||
|
||||
acc.AssertDoesNotContainMeasurement(t, "test_empty")
|
||||
}
|
31
plugins/inputs/mock/sample.conf
Normal file
31
plugins/inputs/mock/sample.conf
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Generate metrics for test and demonstration purposes
|
||||
[[inputs.mock]]
|
||||
## Set the metric name to use for reporting
|
||||
metric_name = "mock"
|
||||
|
||||
## Optional string key-value pairs of tags to add to all metrics
|
||||
# [inputs.mock.tags]
|
||||
# "key" = "value"
|
||||
|
||||
## One or more mock data fields *must* be defined.
|
||||
# [[inputs.mock.constant]]
|
||||
# name = "constant"
|
||||
# value = value_of_any_type
|
||||
# [[inputs.mock.random]]
|
||||
# name = "rand"
|
||||
# min = 1.0
|
||||
# max = 6.0
|
||||
# [[inputs.mock.sine_wave]]
|
||||
# name = "wave"
|
||||
# amplitude = 1.0
|
||||
# period = 0.5
|
||||
# phase = 20.0
|
||||
# base_line = 0.0
|
||||
# [[inputs.mock.step]]
|
||||
# name = "plus_one"
|
||||
# start = 0.0
|
||||
# step = 1.0
|
||||
# [[inputs.mock.stock]]
|
||||
# name = "abc"
|
||||
# price = 50.00
|
||||
# volatility = 0.2
|
Loading…
Add table
Add a link
Reference in a new issue