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
44
plugins/outputs/amon/README.md
Normal file
44
plugins/outputs/amon/README.md
Normal 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
|
151
plugins/outputs/amon/amon.go
Normal file
151
plugins/outputs/amon/amon.go
Normal 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{}
|
||||
})
|
||||
}
|
89
plugins/outputs/amon/amon_test.go
Normal file
89
plugins/outputs/amon/amon_test.go
Normal 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"])
|
||||
}
|
||||
}
|
||||
}
|
10
plugins/outputs/amon/sample.conf
Normal file
10
plugins/outputs/amon/sample.conf
Normal 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"
|
Loading…
Add table
Add a link
Reference in a new issue