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,44 @@
# Amon Output Plugin
This plugin writes metrics to [Amon monitoring platform][amon]. It requires a
`serverkey` and `amoninstance` URL which can be obtained [here][amon_monitoring]
for your account.
> [!IMPORTANT]
> If point values being sent cannot be converted to a `float64`, the metric is
> skipped.
⭐ Telegraf v0.2.1
🏷️ datastore
💻 all
[amon]: https://www.amon.cx
[amon_monitoring]:https://www.amon.cx/docs/monitoring/
## 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
# Configuration for Amon Server to send metrics to.
[[outputs.amon]]
## Amon Server Key
server_key = "my-server-key" # required.
## Amon Instance URL
amon_instance = "https://youramoninstance" # required
## Connection timeout.
# timeout = "5s"
```
## Conversions
Metrics are grouped by converting any `_` characters to `.` in the point name

View file

@ -0,0 +1,151 @@
//go:generate ../../../tools/readme_config_includer/generator
package amon
import (
"bytes"
_ "embed"
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/config"
"github.com/influxdata/telegraf/plugins/outputs"
)
//go:embed sample.conf
var sampleConfig string
type Amon struct {
ServerKey string `toml:"server_key"`
AmonInstance string `toml:"amon_instance"`
Timeout config.Duration `toml:"timeout"`
Log telegraf.Logger `toml:"-"`
client *http.Client
}
type TimeSeries struct {
Series []*Metric `json:"series"`
}
type Metric struct {
Metric string `json:"metric"`
Points [1]Point `json:"metrics"`
}
type Point [2]float64
func (*Amon) SampleConfig() string {
return sampleConfig
}
func (a *Amon) Connect() error {
if a.ServerKey == "" || a.AmonInstance == "" {
return errors.New("serverkey and amon_instance are required fields for amon output")
}
a.client = &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
},
Timeout: time.Duration(a.Timeout),
}
return nil
}
func (a *Amon) Write(metrics []telegraf.Metric) error {
if len(metrics) == 0 {
return nil
}
metricCounter := 0
tempSeries := make([]*Metric, 0, len(metrics))
for _, m := range metrics {
mname := strings.ReplaceAll(m.Name(), "_", ".")
if amonPts, err := buildMetrics(m); err == nil {
for fieldName, amonPt := range amonPts {
metric := &Metric{
Metric: mname + "_" + strings.ReplaceAll(fieldName, "_", "."),
}
metric.Points[0] = amonPt
tempSeries = append(tempSeries, metric)
metricCounter++
}
} else {
a.Log.Infof("Unable to build Metric for %s, skipping", m.Name())
}
}
ts := TimeSeries{}
ts.Series = make([]*Metric, metricCounter)
copy(ts.Series, tempSeries[0:])
tsBytes, err := json.Marshal(ts)
if err != nil {
return fmt.Errorf("unable to marshal TimeSeries: %w", err)
}
req, err := http.NewRequest("POST", a.authenticatedURL(), bytes.NewBuffer(tsBytes))
if err != nil {
return fmt.Errorf("unable to create http.Request: %w", err)
}
req.Header.Add("Content-Type", "application/json")
resp, err := a.client.Do(req)
if err != nil {
return fmt.Errorf("error POSTing metrics: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode > 209 {
return fmt.Errorf("received bad status code, %d", resp.StatusCode)
}
return nil
}
func (a *Amon) authenticatedURL() string {
return fmt.Sprintf("%s/api/system/%s", a.AmonInstance, a.ServerKey)
}
func buildMetrics(m telegraf.Metric) (map[string]Point, error) {
ms := make(map[string]Point)
for k, v := range m.Fields() {
var p Point
if err := p.setValue(v); err != nil {
return ms, fmt.Errorf("unable to extract value from Fields: %w", err)
}
p[0] = float64(m.Time().Unix())
ms[k] = p
}
return ms, nil
}
func (p *Point) setValue(v interface{}) error {
switch d := v.(type) {
case int:
p[1] = float64(d)
case int32:
p[1] = float64(d)
case int64:
p[1] = float64(d)
case float32:
p[1] = float64(d)
case float64:
p[1] = d
default:
return errors.New("undeterminable type")
}
return nil
}
func (*Amon) Close() error {
return nil
}
func init() {
outputs.Add("amon", func() telegraf.Output {
return &Amon{}
})
}

View file

@ -0,0 +1,89 @@
package amon
import (
"errors"
"reflect"
"testing"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/testutil"
)
func TestBuildPoint(t *testing.T) {
var tagtests = []struct {
ptIn telegraf.Metric
outPt Point
err error
}{
{
testutil.TestMetric(float64(0.0), "testpt"),
Point{
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
0.0,
},
nil,
},
{
testutil.TestMetric(float64(1.0), "testpt"),
Point{
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
1.0,
},
nil,
},
{
testutil.TestMetric(int(10), "testpt"),
Point{
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
10.0,
},
nil,
},
{
testutil.TestMetric(int32(112345), "testpt"),
Point{
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
112345.0,
},
nil,
},
{
testutil.TestMetric(int64(112345), "testpt"),
Point{
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
112345.0,
},
nil,
},
{
testutil.TestMetric(float32(11234.5), "testpt"),
Point{
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
11234.5,
},
nil,
},
{
testutil.TestMetric("11234.5", "testpt"),
Point{
float64(time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()),
11234.5,
},
errors.New("unable to extract value from Fields, undeterminable type"),
},
}
for _, tt := range tagtests {
pt, err := buildMetrics(tt.ptIn)
if err != nil && tt.err == nil {
t.Errorf("%s: unexpected error, %+v\n", tt.ptIn.Name(), err)
}
if tt.err != nil && err == nil {
t.Errorf("%s: expected an error (%s) but none returned", tt.ptIn.Name(), tt.err.Error())
}
if !reflect.DeepEqual(pt["value"], tt.outPt) && tt.err == nil {
t.Errorf("%s: \nexpected %+v\ngot %+v\n",
tt.ptIn.Name(), tt.outPt, pt["value"])
}
}
}

View file

@ -0,0 +1,10 @@
# Configuration for Amon Server to send metrics to.
[[outputs.amon]]
## Amon Server Key
server_key = "my-server-key" # required.
## Amon Instance URL
amon_instance = "https://youramoninstance" # required
## Connection timeout.
# timeout = "5s"