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
68
plugins/inputs/hddtemp/README.md
Normal file
68
plugins/inputs/hddtemp/README.md
Normal file
|
@ -0,0 +1,68 @@
|
|||
# HDDtemp Input Plugin
|
||||
|
||||
This plugin reads data from a [hddtemp][hddtemp] daemon.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This plugin requires `hddtemp` to be installed and running as a daemon.
|
||||
|
||||
As the upstream project is not activly maintained anymore and various
|
||||
distributions (e.g. Debian Bookwork and later) don't ship packages for `hddtemp`
|
||||
anymore, the binary might not be available (e.g. in Ubuntu 22.04 or later).
|
||||
|
||||
> [!TIP]
|
||||
> As an alternative consider using the [smartctl][smartctl] relying on
|
||||
> SMART information or [sensors][sensors] plugins to retrieve temperature data
|
||||
> of your hard-drive.
|
||||
|
||||
⭐ Telegraf v1.0.0
|
||||
🏷️ hardware, system
|
||||
💻 all
|
||||
|
||||
[hddtemp]: https://savannah.nongnu.org/projects/hddtemp/
|
||||
[smartctl]: /plugins/inputs/smartctl/README.md
|
||||
[sensors]: /plugins/inputs/sensors/README.md
|
||||
|
||||
## 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
|
||||
# Monitor disks' temperatures using hddtemp
|
||||
[[inputs.hddtemp]]
|
||||
## By default, telegraf gathers temps data from all disks detected by the
|
||||
## hddtemp.
|
||||
##
|
||||
## Only collect temps from the selected disks.
|
||||
##
|
||||
## A * as the device name will return the temperature values of all disks.
|
||||
##
|
||||
# address = "127.0.0.1:7634"
|
||||
# devices = ["sda", "*"]
|
||||
```
|
||||
|
||||
## Metrics
|
||||
|
||||
- hddtemp
|
||||
- tags:
|
||||
- device
|
||||
- model
|
||||
- unit
|
||||
- status
|
||||
- source
|
||||
- fields:
|
||||
- temperature
|
||||
|
||||
## Example Output
|
||||
|
||||
```text
|
||||
hddtemp,source=server1,unit=C,status=,device=sdb,model=WDC\ WD740GD-00FLA1 temperature=43i 1481655647000000000
|
||||
hddtemp,device=sdc,model=SAMSUNG\ HD103UI,unit=C,source=server1,status= temperature=38i 148165564700000000
|
||||
hddtemp,device=sdd,model=SAMSUNG\ HD103UI,unit=C,source=server1,status= temperature=36i 1481655647000000000
|
||||
```
|
21
plugins/inputs/hddtemp/go-hddtemp/LICENSE
Normal file
21
plugins/inputs/hddtemp/go-hddtemp/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Mendelson Gusmão
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
71
plugins/inputs/hddtemp/go-hddtemp/hddtemp.go
Normal file
71
plugins/inputs/hddtemp/go-hddtemp/hddtemp.go
Normal file
|
@ -0,0 +1,71 @@
|
|||
package hddtemp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Disk contains disk data gathered from hddtemp
|
||||
type Disk struct {
|
||||
DeviceName string
|
||||
Model string
|
||||
Temperature int32
|
||||
Unit string
|
||||
Status string
|
||||
}
|
||||
|
||||
type hddtemp struct{}
|
||||
|
||||
// New creates hddtemp
|
||||
func New() *hddtemp {
|
||||
return &hddtemp{}
|
||||
}
|
||||
|
||||
// Fetch gathers disks data from hddtemp daemon.
|
||||
func (*hddtemp) Fetch(address string) ([]Disk, error) {
|
||||
var (
|
||||
err error
|
||||
conn net.Conn
|
||||
buffer bytes.Buffer
|
||||
)
|
||||
|
||||
if conn, err = net.Dial("tcp", address); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err = io.Copy(&buffer, conn); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fields := strings.Split(buffer.String(), "|")
|
||||
|
||||
size := len(fields) / 5
|
||||
disks := make([]Disk, 0, size)
|
||||
for index := 0; index < size; index++ {
|
||||
status := ""
|
||||
offset := index * 5
|
||||
device := fields[offset+1]
|
||||
device = device[strings.LastIndex(device, "/")+1:]
|
||||
|
||||
temperatureField := fields[offset+3]
|
||||
temperature, err := strconv.ParseInt(temperatureField, 10, 32)
|
||||
|
||||
if err != nil {
|
||||
temperature = 0
|
||||
status = temperatureField
|
||||
}
|
||||
|
||||
disks = append(disks, Disk{
|
||||
DeviceName: device,
|
||||
Model: fields[offset+2],
|
||||
Temperature: int32(temperature),
|
||||
Unit: fields[offset+4],
|
||||
Status: status,
|
||||
})
|
||||
}
|
||||
|
||||
return disks, nil
|
||||
}
|
99
plugins/inputs/hddtemp/go-hddtemp/hddtemp_test.go
Normal file
99
plugins/inputs/hddtemp/go-hddtemp/hddtemp_test.go
Normal file
|
@ -0,0 +1,99 @@
|
|||
package hddtemp
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestFetch(t *testing.T) {
|
||||
l := serve(t, []byte("|/dev/sda|foobar|36|C|"))
|
||||
defer l.Close()
|
||||
|
||||
disks, err := New().Fetch(l.Addr().String())
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := []Disk{
|
||||
{
|
||||
DeviceName: "sda",
|
||||
Model: "foobar",
|
||||
Temperature: 36,
|
||||
Unit: "C",
|
||||
},
|
||||
}
|
||||
require.Equal(t, expected, disks, "disks' slice is different from expected")
|
||||
}
|
||||
|
||||
func TestFetchWrongAddress(t *testing.T) {
|
||||
_, err := New().Fetch("127.0.0.1:1")
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestFetchStatus(t *testing.T) {
|
||||
l := serve(t, []byte("|/dev/sda|foobar|SLP|C|"))
|
||||
defer l.Close()
|
||||
|
||||
disks, err := New().Fetch(l.Addr().String())
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := []Disk{
|
||||
{
|
||||
DeviceName: "sda",
|
||||
Model: "foobar",
|
||||
Temperature: 0,
|
||||
Unit: "C",
|
||||
Status: "SLP",
|
||||
},
|
||||
}
|
||||
require.Equal(t, expected, disks, "disks' slice is different from expected")
|
||||
}
|
||||
|
||||
func TestFetchTwoDisks(t *testing.T) {
|
||||
l := serve(t, []byte("|/dev/hda|ST380011A|46|C||/dev/hdd|ST340016A|SLP|*|"))
|
||||
defer l.Close()
|
||||
|
||||
disks, err := New().Fetch(l.Addr().String())
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := []Disk{
|
||||
{
|
||||
DeviceName: "hda",
|
||||
Model: "ST380011A",
|
||||
Temperature: 46,
|
||||
Unit: "C",
|
||||
},
|
||||
{
|
||||
DeviceName: "hdd",
|
||||
Model: "ST340016A",
|
||||
Temperature: 0,
|
||||
Unit: "*",
|
||||
Status: "SLP",
|
||||
},
|
||||
}
|
||||
require.Equal(t, expected, disks, "disks' slice is different from expected")
|
||||
}
|
||||
|
||||
func serve(t *testing.T, data []byte) net.Listener {
|
||||
l, err := net.Listen("tcp", "127.0.0.1:0")
|
||||
require.NoError(t, err)
|
||||
|
||||
go func(t *testing.T) {
|
||||
conn, err := l.Accept()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = conn.Write(data); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if err = conn.Close(); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
}(t)
|
||||
|
||||
return l
|
||||
}
|
77
plugins/inputs/hddtemp/hddtemp.go
Normal file
77
plugins/inputs/hddtemp/hddtemp.go
Normal file
|
@ -0,0 +1,77 @@
|
|||
//go:generate ../../../tools/readme_config_includer/generator
|
||||
package hddtemp
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"net"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
gohddtemp "github.com/influxdata/telegraf/plugins/inputs/hddtemp/go-hddtemp"
|
||||
)
|
||||
|
||||
//go:embed sample.conf
|
||||
var sampleConfig string
|
||||
|
||||
const defaultAddress = "127.0.0.1:7634"
|
||||
|
||||
type HDDTemp struct {
|
||||
Address string `toml:"address"`
|
||||
Devices []string `toml:"devices"`
|
||||
|
||||
fetcher fetcher
|
||||
}
|
||||
|
||||
type fetcher interface {
|
||||
Fetch(address string) ([]gohddtemp.Disk, error)
|
||||
}
|
||||
|
||||
func (*HDDTemp) SampleConfig() string {
|
||||
return sampleConfig
|
||||
}
|
||||
|
||||
func (h *HDDTemp) Gather(acc telegraf.Accumulator) error {
|
||||
if h.fetcher == nil {
|
||||
h.fetcher = gohddtemp.New()
|
||||
}
|
||||
source, _, err := net.SplitHostPort(h.Address)
|
||||
if err != nil {
|
||||
source = h.Address
|
||||
}
|
||||
|
||||
disks, err := h.fetcher.Fetch(h.Address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, disk := range disks {
|
||||
for _, chosenDevice := range h.Devices {
|
||||
if chosenDevice == "*" || chosenDevice == disk.DeviceName {
|
||||
tags := map[string]string{
|
||||
"device": disk.DeviceName,
|
||||
"model": disk.Model,
|
||||
"unit": disk.Unit,
|
||||
"status": disk.Status,
|
||||
"source": source,
|
||||
}
|
||||
|
||||
fields := map[string]interface{}{
|
||||
"temperature": disk.Temperature,
|
||||
}
|
||||
|
||||
acc.AddFields("hddtemp", fields, tags)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
inputs.Add("hddtemp", func() telegraf.Input {
|
||||
return &HDDTemp{
|
||||
Address: defaultAddress,
|
||||
Devices: []string{"*"},
|
||||
}
|
||||
})
|
||||
}
|
82
plugins/inputs/hddtemp/hddtemp_test.go
Normal file
82
plugins/inputs/hddtemp/hddtemp_test.go
Normal file
|
@ -0,0 +1,82 @@
|
|||
package hddtemp
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/influxdata/telegraf/plugins/inputs/hddtemp/go-hddtemp"
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
type mockFetcher struct {
|
||||
}
|
||||
|
||||
func (*mockFetcher) Fetch(string) ([]hddtemp.Disk, error) {
|
||||
return []hddtemp.Disk{
|
||||
{
|
||||
DeviceName: "Disk1",
|
||||
Model: "Model1",
|
||||
Temperature: 13,
|
||||
Unit: "C",
|
||||
},
|
||||
{
|
||||
DeviceName: "Disk2",
|
||||
Model: "Model2",
|
||||
Temperature: 14,
|
||||
Unit: "C",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func newMockFetcher() *mockFetcher {
|
||||
return &mockFetcher{}
|
||||
}
|
||||
|
||||
func TestFetch(t *testing.T) {
|
||||
hddTemp := &HDDTemp{
|
||||
fetcher: newMockFetcher(),
|
||||
Address: "localhost",
|
||||
Devices: []string{"*"},
|
||||
}
|
||||
|
||||
acc := &testutil.Accumulator{}
|
||||
err := hddTemp.Gather(acc)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 2, acc.NFields())
|
||||
|
||||
var tests = []struct {
|
||||
fields map[string]interface{}
|
||||
tags map[string]string
|
||||
}{
|
||||
{
|
||||
map[string]interface{}{
|
||||
"temperature": int32(13),
|
||||
},
|
||||
map[string]string{
|
||||
"device": "Disk1",
|
||||
"model": "Model1",
|
||||
"unit": "C",
|
||||
"status": "",
|
||||
"source": "localhost",
|
||||
},
|
||||
},
|
||||
{
|
||||
map[string]interface{}{
|
||||
"temperature": int32(14),
|
||||
},
|
||||
map[string]string{
|
||||
"device": "Disk2",
|
||||
"model": "Model2",
|
||||
"unit": "C",
|
||||
"status": "",
|
||||
"source": "localhost",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
acc.AssertContainsTaggedFields(t, "hddtemp", test.fields, test.tags)
|
||||
}
|
||||
}
|
11
plugins/inputs/hddtemp/sample.conf
Normal file
11
plugins/inputs/hddtemp/sample.conf
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Monitor disks' temperatures using hddtemp
|
||||
[[inputs.hddtemp]]
|
||||
## By default, telegraf gathers temps data from all disks detected by the
|
||||
## hddtemp.
|
||||
##
|
||||
## Only collect temps from the selected disks.
|
||||
##
|
||||
## A * as the device name will return the temperature values of all disks.
|
||||
##
|
||||
# address = "127.0.0.1:7634"
|
||||
# devices = ["sda", "*"]
|
Loading…
Add table
Add a link
Reference in a new issue