forked from influxdata/telegraf
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add IPVS input plugin (influxdata#4890)
- Loading branch information
Showing
6 changed files
with
174 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# IPVS Input Plugin (Linux) | ||
|
||
The IPVS input plugin uses the linux kernel netlink socket interface to gather | ||
metrics about ipvs virtual and real servers. | ||
|
||
## Configuration | ||
|
||
[[inputs.ipvs]] | ||
# no configuration | ||
|
||
## Permissions | ||
|
||
Assuming you installed the telegraf package via one of the published packages, | ||
the process will be running as the `telegraf` user. However, in order for this | ||
plugin to communicate over netlink sockets it needs the telegraf process to be | ||
running as `root` (or some user with `CAP_NET_ADMIN` and `CAP_NET_RAW`). Be sure | ||
to ensure these permissions before running telegraf with this plugin included. | ||
|
||
## Sample Output | ||
|
||
This is what you can expect the emitted metrics to look like | ||
|
||
``` | ||
ipvs_virtual_server,address=172.18.64.234,address_family=inet,netmask=32,port=9000,protocol=tcp,sched=mh_418 bytes_out=0i,pps_in=0i,pps_out=0i,cps=0i,pkts_in=0i,pkts_out=0i,connections=0i,bytes_in=0i 1540407540000000000 | ||
ipvs_virtual_server,address_family=inet,fwmark=47,netmask=32,sched=mh_418 connections=0i,pkts_in=0i,bytes_out=0i,pps_in=0i,pps_out=0i,pkts_out=0i,bytes_in=0i,cps=0i 1540407540000000000 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// +build linux | ||
|
||
package ipvs | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"math/bits" | ||
"strconv" | ||
"syscall" | ||
|
||
"github.com/docker/libnetwork/ipvs" | ||
"github.com/influxdata/telegraf" | ||
"github.com/influxdata/telegraf/plugins/inputs" | ||
) | ||
|
||
// IPVS holds the state for this input plugin | ||
type IPVS struct { | ||
handle *ipvs.Handle | ||
} | ||
|
||
// Description returns a description string | ||
func (i *IPVS) Description() string { | ||
return "Collect virtual and real server stats from Linux IPVS" | ||
} | ||
|
||
// SampleConfig returns a sample configuration for this input plugin | ||
func (i *IPVS) SampleConfig() string { | ||
return `` | ||
} | ||
|
||
// Gather gathers the stats | ||
func (i *IPVS) Gather(acc telegraf.Accumulator) error { | ||
if i.handle == nil { | ||
h, err := ipvs.New("") // TODO: make the namespace configurable | ||
if err != nil { | ||
return errors.New("Unable to open IPVS handle") | ||
} | ||
i.handle = h | ||
} | ||
|
||
services, err := i.handle.GetServices() | ||
if err != nil { | ||
i.handle.Close() | ||
i.handle = nil // trigger a reopen on next call to gather | ||
return errors.New("Failed to list IPVS services") | ||
} | ||
for _, s := range services { | ||
fields := map[string]interface{}{ | ||
"connections": s.Stats.Connections, | ||
"pkts_in": s.Stats.PacketsIn, | ||
"pkts_out": s.Stats.PacketsOut, | ||
"bytes_in": s.Stats.BytesIn, | ||
"bytes_out": s.Stats.BytesOut, | ||
"pps_in": s.Stats.PPSIn, | ||
"pps_out": s.Stats.PPSOut, | ||
"cps": s.Stats.CPS, | ||
} | ||
acc.AddGauge("ipvs_virtual_server", fields, serviceTags(s)) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// helper: given a Service, return tags that identify it | ||
func serviceTags(s *ipvs.Service) map[string]string { | ||
ret := map[string]string{ | ||
"sched": s.SchedName, | ||
"netmask": fmt.Sprintf("%d", bits.OnesCount32(s.Netmask)), | ||
"address_family": addressFamilyToString(s.AddressFamily), | ||
} | ||
// Per the ipvsadm man page, a virtual service is defined "based on | ||
// protocol/addr/port or firewall mark" | ||
if s.FWMark > 0 { | ||
ret["fwmark"] = strconv.Itoa(int(s.FWMark)) | ||
} else { | ||
ret["protocol"] = protocolToString(s.Protocol) | ||
ret["address"] = s.Address.String() | ||
ret["port"] = strconv.Itoa(int(s.Port)) | ||
} | ||
return ret | ||
} | ||
|
||
// helper: convert protocol uint16 to human readable string (if possible) | ||
func protocolToString(p uint16) string { | ||
switch p { | ||
case syscall.IPPROTO_TCP: | ||
return "tcp" | ||
case syscall.IPPROTO_UDP: | ||
return "udp" | ||
case syscall.IPPROTO_SCTP: | ||
return "sctp" | ||
default: | ||
return fmt.Sprintf("%d", p) | ||
} | ||
} | ||
|
||
// helper: convert addressFamily to a human readable string | ||
func addressFamilyToString(af uint16) string { | ||
switch af { | ||
case syscall.AF_INET: | ||
return "inet" | ||
case syscall.AF_INET6: | ||
return "inet6" | ||
default: | ||
return fmt.Sprintf("%d", af) | ||
} | ||
} | ||
|
||
func init() { | ||
inputs.Add("ipvs", func() telegraf.Input { return &IPVS{} }) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
// +build !linux | ||
|
||
package ipvs |