1
0
Fork 0

Adding upstream version 1.34.4.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-05-24 07:26:29 +02:00
parent e393c3af3f
commit 4978089aab
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
4963 changed files with 677545 additions and 0 deletions

View 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
View 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{}
})
}

View 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")
}

View 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