Merge pull request #2 from KPACHbIuLLIAnO4/master

merge changes from influxdb
This commit is contained in:
KPACHbIuLLIAnO4 2015-09-13 18:00:38 +03:00
commit edf1336f8f
17 changed files with 285 additions and 169 deletions

View File

@ -1,4 +1,21 @@
## v0.1.8 [unreleased] ## v0.1.9 [unreleased]
### Release Notes
- InfluxDB output config change: `url` is now `urls`, and is a list. Config files
will still be backwards compatible if only `url` is specified.
### Features
- [#143](https://github.com/influxdb/telegraf/issues/143): InfluxDB clustering support
- [#181](https://github.com/influxdb/telegraf/issues/181): Makefile GOBIN support. Thanks @Vye!
### Bugfixes
- [#170](https://github.com/influxdb/telegraf/issues/170): Systemd support
- [#175](https://github.com/influxdb/telegraf/issues/175): Set write precision before gathering metrics
- [#178](https://github.com/influxdb/telegraf/issues/178): redis plugin, multiple server thread hang bug
- Fix net plugin on darwin
- [#84](https://github.com/influxdb/telegraf/issues/84): Fix docker plugin on CentOS. Thanks @neezgee!
## v0.1.8 [2015-09-04]
### Release Notes ### Release Notes
- Telegraf will now write data in UTC at second precision by default - Telegraf will now write data in UTC at second precision by default

View File

@ -128,3 +128,36 @@ func init() {
## Outputs ## Outputs
TODO: this section will describe requirements for contributing an output TODO: this section will describe requirements for contributing an output
## Unit Tests
### Execute short tests
execute `make test-short`
### Execute long tests
As Telegraf collects metrics from several third-party services it becomes a
difficult task to mock each service as some of them have complicated protocols
which would take some time to replicate.
To overcome this situation we've decided to use docker containers to provide a
fast and reproducible environment to test those services which require it.
For other situations
(i.e: https://github.com/influxdb/telegraf/blob/master/plugins/redis/redis_test.go )
a simple mock will suffice.
To execute Telegraf tests follow these simple steps:
- Install docker compose following [these](https://docs.docker.com/compose/install/)
instructions
- execute `make test`
**OSX users**: you will need to install `boot2docker` or `docker-machine`.
The Makefile will assume that you have a `docker-machine` box called `default` to
get the IP address.
### Unit test troubleshooting
Try cleaning up your test environment by executing `make test-cleanup` and
re-running

View File

@ -1,19 +1,22 @@
UNAME := $(shell sh -c 'uname') UNAME := $(shell sh -c 'uname')
VERSION := $(shell sh -c 'git describe --always --tags') VERSION := $(shell sh -c 'git describe --always --tags')
ifndef GOBIN
GOBIN = $(GOPATH)/bin
endif
build: prepare build: prepare
$(GOPATH)/bin/godep go build -o telegraf -ldflags \ $(GOBIN)/godep go build -o telegraf -ldflags \
"-X main.Version $(VERSION)" \ "-X main.Version $(VERSION)" \
./cmd/telegraf/telegraf.go ./cmd/telegraf/telegraf.go
build-linux-bins: prepare build-linux-bins: prepare
GOARCH=amd64 GOOS=linux $(GOPATH)/bin/godep go build -o telegraf_linux_amd64 \ GOARCH=amd64 GOOS=linux $(GOBIN)/godep go build -o telegraf_linux_amd64 \
-ldflags "-X main.Version $(VERSION)" \ -ldflags "-X main.Version $(VERSION)" \
./cmd/telegraf/telegraf.go ./cmd/telegraf/telegraf.go
GOARCH=386 GOOS=linux $(GOPATH)/bin/godep go build -o telegraf_linux_386 \ GOARCH=386 GOOS=linux $(GOBIN)/godep go build -o telegraf_linux_386 \
-ldflags "-X main.Version $(VERSION)" \ -ldflags "-X main.Version $(VERSION)" \
./cmd/telegraf/telegraf.go ./cmd/telegraf/telegraf.go
GOARCH=arm GOOS=linux $(GOPATH)/bin/godep go build -o telegraf_linux_arm \ GOARCH=arm GOOS=linux $(GOBIN)/godep go build -o telegraf_linux_arm \
-ldflags "-X main.Version $(VERSION)" \ -ldflags "-X main.Version $(VERSION)" \
./cmd/telegraf/telegraf.go ./cmd/telegraf/telegraf.go
@ -22,19 +25,20 @@ prepare:
docker-compose: docker-compose:
ifeq ($(UNAME), Darwin) ifeq ($(UNAME), Darwin)
ADVERTISED_HOST=$(shell sh -c 'boot2docker ip') docker-compose up -d ADVERTISED_HOST=$(shell sh -c 'boot2docker ip || docker-machine ip default') \
docker-compose --file scripts/docker-compose.yml up -d
endif endif
ifeq ($(UNAME), Linux) ifeq ($(UNAME), Linux)
ADVERTISED_HOST=localhost docker-compose up -d ADVERTISED_HOST=localhost docker-compose --file scripts/docker-compose.yml up -d
endif endif
test: prepare docker-compose test: prepare docker-compose
$(GOPATH)/bin/godep go test -v ./... $(GOBIN)/godep go test -v ./...
test-short: prepare test-short: prepare
$(GOPATH)/bin/godep go test -short ./... $(GOBIN)/godep go test -short ./...
test-cleanup: test-cleanup:
docker-compose kill docker-compose --file scripts/docker-compose.yml kill
.PHONY: test .PHONY: test

View File

@ -1,46 +1,58 @@
# Telegraf - A native agent for InfluxDB [![Circle CI](https://circleci.com/gh/influxdb/telegraf.svg?style=svg)](https://circleci.com/gh/influxdb/telegraf) # Telegraf - A native agent for InfluxDB [![Circle CI](https://circleci.com/gh/influxdb/telegraf.svg?style=svg)](https://circleci.com/gh/influxdb/telegraf)
Telegraf is an agent written in Go for collecting metrics from the system it's Telegraf is an agent written in Go for collecting metrics from the system it's
running on or from other services and writing them into InfluxDB. running on, or from other services, and writing them into InfluxDB.
Design goals are to have a minimal memory footprint with a plugin system so Design goals are to have a minimal memory footprint with a plugin system so
that developers in the community can easily add support for collecting metrics that developers in the community can easily add support for collecting metrics
from well known services (like Hadoop, or Postgres, or Redis) and third party from well known services (like Hadoop, Postgres, or Redis) and third party
APIs (like Mailchimp, AWS CloudWatch, or Google Analytics). APIs (like Mailchimp, AWS CloudWatch, or Google Analytics).
We'll eagerly accept pull requests for new plugins and will manage the set of We'll eagerly accept pull requests for new plugins and will manage the set of
plugins that Telegraf supports. See the bottom of this doc for instructions on plugins that Telegraf supports. See the
[contributing guide](CONTRIBUTING.md) for instructions on
writing new plugins. writing new plugins.
## Quickstart ## Installation:
* Build from source or download telegraf: Due to a breaking change to the InfluxDB integer line-protocol, there
### Linux packages for Debian/Ubuntu and RHEL/CentOS:
NOTE: version 0.1.4+ has introduced some breaking changes! A 0.1.4+ telegraf
agent is NOT backwards-compatible with a config file from 0.1.3 and below.
That being said, the difference is not huge, see below for an example on
how to setup the new config file.
As well, due to a breaking change to the InfluxDB integer line-protocol, there
are some InfluxDB compatibility requirements: are some InfluxDB compatibility requirements:
* InfluxDB 0.9.3+ (including nightly builds) requires Telegraf 0.1.5+ * InfluxDB 0.9.3+ requires Telegraf 0.1.5+
* InfluxDB 0.9.2 and prior requires Telegraf 0.1.4 * InfluxDB 0.9.2 and prior requires Telegraf 0.1.4
### Linux deb and rpm packages:
Latest: Latest:
* http://get.influxdb.org/telegraf/telegraf_0.1.8_amd64.deb * http://get.influxdb.org/telegraf/telegraf_0.1.8_amd64.deb
* http://get.influxdb.org/telegraf/telegraf-0.1.8-1.x86_64.rpm * http://get.influxdb.org/telegraf/telegraf-0.1.8-1.x86_64.rpm
Binaries: 0.1.4:
* http://get.influxdb.org/telegraf/telegraf_0.1.4_amd64.deb
* http://get.influxdb.org/telegraf/telegraf-0.1.4-1.x86_64.rpm
##### Package instructions:
* Telegraf binary is installed in `/opt/telegraf/telegraf`
* Telegraf daemon configuration file is in `/etc/opt/telegraf/telegraf.conf`
* On sysv systems, the telegraf daemon can be controlled via
`service telegraf [action]`
* On systemd systems (such as Ubuntu 15+), the telegraf daemon can be
controlled via `systemctl [action] telegraf`
### Linux binaries:
Latest:
* http://get.influxdb.org/telegraf/telegraf_linux_amd64_0.1.8.tar.gz * http://get.influxdb.org/telegraf/telegraf_linux_amd64_0.1.8.tar.gz
* http://get.influxdb.org/telegraf/telegraf_linux_386_0.1.8.tar.gz * http://get.influxdb.org/telegraf/telegraf_linux_386_0.1.8.tar.gz
* http://get.influxdb.org/telegraf/telegraf_linux_arm_0.1.8.tar.gz * http://get.influxdb.org/telegraf/telegraf_linux_arm_0.1.8.tar.gz
0.1.4: ##### Binary instructions:
* http://get.influxdb.org/telegraf/telegraf_0.1.4_amd64.deb
* http://get.influxdb.org/telegraf/telegraf-0.1.4-1.x86_64.rpm These are standalone binaries that can be unpacked and executed on any linux
system. They can be unpacked and renamed in a location such as
`/usr/local/bin` for convenience. A config file will need to be generated,
see "How to use it" below.
### OSX via Homebrew: ### OSX via Homebrew:
@ -62,19 +74,17 @@ if you don't have it already. You also must build with golang version 1.4+
### How to use it: ### How to use it:
* Run `telegraf -sample-config > telegraf.toml` to create an initial configuration * Run `telegraf -sample-config > telegraf.conf` to create an initial configuration
* Edit the configuration to match your needs * Edit the configuration to match your needs
* Run `telegraf -config telegraf.toml -test` to output one full measurement sample to STDOUT * Run `telegraf -config telegraf.conf -test` to output one full measurement sample to STDOUT
* Run `telegraf -config telegraf.toml` to gather and send metrics to configured outputs. * Run `telegraf -config telegraf.conf` to gather and send metrics to configured outputs.
* Run `telegraf -config telegraf.toml -filter system:swap` * Run `telegraf -config telegraf.conf -filter system:swap`
to enable only the system & swap plugins defined in the config. to enable only the system & swap plugins defined in the config.
## Telegraf Options ## Telegraf Options
Telegraf has a few options you can configure under the `agent` section of the Telegraf has a few options you can configure under the `agent` section of the
config. If you don't see an `agent` section run config.
`telegraf -sample-config > telegraf.toml` to create a valid initial
configuration:
* **hostname**: The hostname is passed as a tag. By default this will be * **hostname**: The hostname is passed as a tag. By default this will be
the value retured by `hostname` on the machine running Telegraf. the value retured by `hostname` on the machine running Telegraf.
@ -194,36 +204,5 @@ found by running `telegraf -sample-config`
## Contributing ## Contributing
Please see the Please see the
[contributing guide](https://github.com/influxdb/telegraf/blob/master/CONTRIBUTING.md) [contributing guide](CONTRIBUTING.md)
for details on contributing a plugin or output to Telegraf for details on contributing a plugin or output to Telegraf
## Testing
### Execute short tests
execute `make test-short`
### Execute long tests
As Telegraf collects metrics from several third-party services it becomes a
difficult task to mock each service as some of them have complicated protocols
which would take some time to replicate.
To overcome this situation we've decided to use docker containers to provide a
fast and reproducible environment to test those services which require it.
For other situations
(i.e: https://github.com/influxdb/telegraf/blob/master/plugins/redis/redis_test.go )
a simple mock will suffice.
To execute Telegraf tests follow these simple steps:
- Install docker compose following [these](https://docs.docker.com/compose/install/)
instructions
- mac users should be able to simply do `brew install boot2docker`
and `brew install docker-compose`
- execute `make test`
### Unit test troubleshooting
Try cleaning up your test environment by executing `make test-cleanup` and
re-running

View File

@ -25,7 +25,11 @@ type BatchPoints struct {
} }
// Add adds a measurement // Add adds a measurement
func (bp *BatchPoints) Add(measurement string, val interface{}, tags map[string]string) { func (bp *BatchPoints) Add(
measurement string,
val interface{},
tags map[string]string,
) {
bp.mu.Lock() bp.mu.Lock()
defer bp.mu.Unlock() defer bp.mu.Unlock()

View File

@ -84,6 +84,9 @@ func NewAgent(config *Config) (*Agent, error) {
// Connect connects to all configured outputs // Connect connects to all configured outputs
func (a *Agent) Connect() error { func (a *Agent) Connect() error {
for _, o := range a.outputs { for _, o := range a.outputs {
if a.Debug {
log.Printf("Attempting connection to output: %s\n", o.name)
}
err := o.output.Connect() err := o.output.Connect()
if err != nil { if err != nil {
return err return err
@ -193,16 +196,17 @@ func (a *Agent) crankParallel() error {
go func(plugin *runningPlugin) { go func(plugin *runningPlugin) {
defer wg.Done() defer wg.Done()
var acc BatchPoints var bp BatchPoints
acc.Debug = a.Debug bp.Debug = a.Debug
acc.Prefix = plugin.name + "_" bp.Prefix = plugin.name + "_"
acc.Config = plugin.config bp.Config = plugin.config
bp.Precision = a.Precision
if err := plugin.plugin.Gather(&acc); err != nil { if err := plugin.plugin.Gather(&bp); err != nil {
log.Printf("Error in plugin [%s]: %s", plugin.name, err) log.Printf("Error in plugin [%s]: %s", plugin.name, err)
} }
points <- &acc points <- &bp
}(plugin) }(plugin)
} }
@ -230,6 +234,7 @@ func (a *Agent) crank() error {
var bp BatchPoints var bp BatchPoints
bp.Debug = a.Debug bp.Debug = a.Debug
bp.Precision = a.Precision
for _, plugin := range a.plugins { for _, plugin := range a.plugins {
bp.Prefix = plugin.name + "_" bp.Prefix = plugin.name + "_"
@ -245,7 +250,6 @@ func (a *Agent) crank() error {
if a.UTC { if a.UTC {
bp.Time = bp.Time.UTC() bp.Time = bp.Time.UTC()
} }
bp.Precision = a.Precision
return a.flush(&bp) return a.flush(&bp)
} }
@ -263,6 +267,7 @@ func (a *Agent) crankSeparate(shutdown chan struct{}, plugin *runningPlugin) err
bp.Prefix = plugin.name + "_" bp.Prefix = plugin.name + "_"
bp.Config = plugin.config bp.Config = plugin.config
bp.Precision = a.Precision
if err := plugin.plugin.Gather(&bp); err != nil { if err := plugin.plugin.Gather(&bp); err != nil {
log.Printf("Error in plugin [%s]: %s", plugin.name, err) log.Printf("Error in plugin [%s]: %s", plugin.name, err)
@ -274,7 +279,6 @@ func (a *Agent) crankSeparate(shutdown chan struct{}, plugin *runningPlugin) err
if a.UTC { if a.UTC {
bp.Time = bp.Time.UTC() bp.Time = bp.Time.UTC()
} }
bp.Precision = a.Precision
if err := a.flush(&bp); err != nil { if err := a.flush(&bp); err != nil {
outerr = errors.New("Error encountered processing plugins & outputs") outerr = errors.New("Error encountered processing plugins & outputs")

View File

@ -4,5 +4,5 @@ dependencies:
test: test:
override: override:
- bash circle-test.sh - bash scripts/circle-test.sh

View File

@ -37,7 +37,7 @@
[outputs] [outputs]
[outputs.influxdb] [outputs.influxdb]
# The full HTTP endpoint URL for your InfluxDB instance # The full HTTP endpoint URL for your InfluxDB instance
url = "http://localhost:8086" # required. urls = ["http://localhost:8086"] # required.
# The target database for metrics. This database must already exist # The target database for metrics. This database must already exist
database = "telegraf" # required. database = "telegraf" # required.

View File

@ -1,8 +1,10 @@
package influxdb package influxdb
import ( import (
"errors"
"fmt" "fmt"
"log" "log"
"math/rand"
"net/url" "net/url"
"strings" "strings"
@ -12,19 +14,23 @@ import (
) )
type InfluxDB struct { type InfluxDB struct {
// URL is only for backwards compatability
URL string URL string
URLs []string `toml:"urls"`
Username string Username string
Password string Password string
Database string Database string
UserAgent string UserAgent string
Timeout t.Duration Timeout t.Duration
conn *client.Client conns []*client.Client
} }
var sampleConfig = ` var sampleConfig = `
# The full HTTP endpoint URL for your InfluxDB instance # The full HTTP endpoint URL for your InfluxDB instance
url = "http://localhost:8086" # required. # Multiple urls can be specified for InfluxDB cluster support. Server to
# write to will be randomly chosen each interval.
urls = ["http://localhost:8086"] # required.
# The target database for metrics. This database must already exist # The target database for metrics. This database must already exist
database = "telegraf" # required. database = "telegraf" # required.
@ -42,33 +48,58 @@ var sampleConfig = `
` `
func (i *InfluxDB) Connect() error { func (i *InfluxDB) Connect() error {
u, err := url.Parse(i.URL) var urls []*url.URL
if err != nil { for _, URL := range i.URLs {
return err u, err := url.Parse(URL)
if err != nil {
return err
}
urls = append(urls, u)
} }
c, err := client.NewClient(client.Config{ // Backward-compatability with single Influx URL config files
URL: *u, // This could eventually be removed in favor of specifying the urls as a list
Username: i.Username, if i.URL != "" {
Password: i.Password, u, err := url.Parse(i.URL)
UserAgent: i.UserAgent, if err != nil {
Timeout: i.Timeout.Duration, return err
}) }
urls = append(urls, u)
if err != nil {
return err
} }
_, err = c.Query(client.Query{ var conns []*client.Client
Command: fmt.Sprintf("CREATE DATABASE %s", i.Database), for _, parsed_url := range urls {
}) c, err := client.NewClient(client.Config{
URL: *parsed_url,
if err != nil && !strings.Contains(err.Error(), "database already exists") { Username: i.Username,
log.Fatal(err) Password: i.Password,
UserAgent: i.UserAgent,
Timeout: i.Timeout.Duration,
})
if err != nil {
return err
}
conns = append(conns, c)
} }
i.conn = c // This will get set to nil if a successful connection is made
return nil err := errors.New("Could not create database on any server")
for _, conn := range conns {
_, e := conn.Query(client.Query{
Command: fmt.Sprintf("CREATE DATABASE %s", i.Database),
})
if e != nil && !strings.Contains(e.Error(), "database already exists") {
log.Println("ERROR: " + e.Error())
} else {
err = nil
break
}
}
i.conns = conns
return err
} }
func (i *InfluxDB) Close() error { func (i *InfluxDB) Close() error {
@ -84,12 +115,24 @@ func (i *InfluxDB) Description() string {
return "Configuration for influxdb server to send metrics to" return "Configuration for influxdb server to send metrics to"
} }
// Choose a random server in the cluster to write to until a successful write
// occurs, logging each unsuccessful. If all servers fail, return error.
func (i *InfluxDB) Write(bp client.BatchPoints) error { func (i *InfluxDB) Write(bp client.BatchPoints) error {
bp.Database = i.Database bp.Database = i.Database
if _, err := i.conn.Write(bp); err != nil {
return err // This will get set to nil if a successful write occurs
err := errors.New("Could not write to any InfluxDB server in cluster")
p := rand.Perm(len(i.conns))
for _, n := range p {
if _, e := i.conns[n].Write(bp); e != nil {
log.Println("ERROR: " + e.Error())
} else {
err = nil
break
}
} }
return nil return err
} }
func init() { func init() {

View File

@ -15,9 +15,6 @@ import (
type Redis struct { type Redis struct {
Servers []string Servers []string
c net.Conn
buf []byte
} }
var sampleConfig = ` var sampleConfig = `
@ -112,41 +109,37 @@ func (r *Redis) Gather(acc plugins.Accumulator) error {
const defaultPort = "6379" const defaultPort = "6379"
func (r *Redis) gatherServer(addr *url.URL, acc plugins.Accumulator) error { func (r *Redis) gatherServer(addr *url.URL, acc plugins.Accumulator) error {
if r.c == nil { _, _, err := net.SplitHostPort(addr.Host)
if err != nil {
_, _, err := net.SplitHostPort(addr.Host) addr.Host = addr.Host + ":" + defaultPort
if err != nil {
addr.Host = addr.Host + ":" + defaultPort
}
c, err := net.Dial("tcp", addr.Host)
if err != nil {
return fmt.Errorf("Unable to connect to redis server '%s': %s", addr.Host, err)
}
if addr.User != nil {
pwd, set := addr.User.Password()
if set && pwd != "" {
c.Write([]byte(fmt.Sprintf("AUTH %s\r\n", pwd)))
rdr := bufio.NewReader(c)
line, err := rdr.ReadString('\n')
if err != nil {
return err
}
if line[0] != '+' {
return fmt.Errorf("%s", strings.TrimSpace(line)[1:])
}
}
}
r.c = c
} }
r.c.Write([]byte("info\r\n")) c, err := net.Dial("tcp", addr.Host)
if err != nil {
return fmt.Errorf("Unable to connect to redis server '%s': %s", addr.Host, err)
}
defer c.Close()
rdr := bufio.NewReader(r.c) if addr.User != nil {
pwd, set := addr.User.Password()
if set && pwd != "" {
c.Write([]byte(fmt.Sprintf("AUTH %s\r\n", pwd)))
rdr := bufio.NewReader(c)
line, err := rdr.ReadString('\n')
if err != nil {
return err
}
if line[0] != '+' {
return fmt.Errorf("%s", strings.TrimSpace(line)[1:])
}
}
}
c.Write([]byte("info\r\n"))
rdr := bufio.NewReader(c)
line, err := rdr.ReadString('\n') line, err := rdr.ReadString('\n')
if err != nil { if err != nil {

View File

@ -4,6 +4,7 @@ package docker
import ( import (
"encoding/json" "encoding/json"
"os"
"os/exec" "os/exec"
"path" "path"
"strconv" "strconv"
@ -48,9 +49,13 @@ func CgroupCPU(containerid string, base string) (*cpu.CPUTimesStat, error) {
if len(base) == 0 { if len(base) == 0 {
base = "/sys/fs/cgroup/cpuacct/docker" base = "/sys/fs/cgroup/cpuacct/docker"
} }
path := path.Join(base, containerid, "cpuacct.stat") statfile := path.Join(base, containerid, "cpuacct.stat")
lines, err := common.ReadLines(path) if _, err := os.Stat(statfile); os.IsNotExist(err) {
statfile = path.Join("/sys/fs/cgroup/cpuacct/system.slice", "docker-" + containerid + ".scope", "cpuacct.stat")
}
lines, err := common.ReadLines(statfile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -86,12 +91,17 @@ func CgroupMem(containerid string, base string) (*CgroupMemStat, error) {
if len(base) == 0 { if len(base) == 0 {
base = "/sys/fs/cgroup/memory/docker" base = "/sys/fs/cgroup/memory/docker"
} }
path := path.Join(base, containerid, "memory.stat") statfile := path.Join(base, containerid, "memory.stat")
if _, err := os.Stat(statfile); os.IsNotExist(err) {
statfile = path.Join("/sys/fs/cgroup/memory/system.slice", "docker-" + containerid + ".scope", "memory.stat")
}
// empty containerid means all cgroup // empty containerid means all cgroup
if len(containerid) == 0 { if len(containerid) == 0 {
containerid = "all" containerid = "all"
} }
lines, err := common.ReadLines(path) lines, err := common.ReadLines(statfile)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -7,7 +7,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/influxdb/telegraf/plugins/system/ps/common" "github.com/shirou/gopsutil/common"
) )
func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) { func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
@ -26,7 +26,7 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
// skip first line // skip first line
continue continue
} }
if common.StringContains(exists, values[0]) { if common.StringsHas(exists, values[0]) {
// skip if already get // skip if already get
continue continue
} }
@ -38,11 +38,14 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
base = 0 base = 0
} }
parsed := make([]uint64, 0, 3) parsed := make([]uint64, 0, 6)
vv := []string{ vv := []string{
values[base+3], // PacketsRecv values[base+3], // Ipkts == PacketsRecv
values[base+4], // Errin values[base+4], // Ierrs == Errin
values[base+5], // Dropin values[base+5], // Ibytes == BytesRecv
values[base+6], // Opkts == PacketsSent
values[base+7], // Oerrs == Errout
values[base+8], // Obytes == BytesSent
} }
for _, target := range vv { for _, target := range vv {
if target == "-" { if target == "-" {
@ -61,7 +64,10 @@ func NetIOCounters(pernic bool) ([]NetIOCountersStat, error) {
Name: values[0], Name: values[0],
PacketsRecv: parsed[0], PacketsRecv: parsed[0],
Errin: parsed[1], Errin: parsed[1],
Dropin: parsed[2], BytesRecv: parsed[2],
PacketsSent: parsed[3],
Errout: parsed[4],
BytesSent: parsed[5],
} }
ret = append(ret, n) ret = append(ret, n)
} }

View File

@ -7,7 +7,7 @@ VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "ubuntu/trusty64" config.vm.box = "ubuntu/trusty64"
config.vm.synced_folder ".", "/home/vagrant/go/src/github.com/influxdb/telegraf", config.vm.synced_folder "..", "/home/vagrant/go/src/github.com/influxdb/telegraf",
type: "rsync", type: "rsync",
rsync__args: ["--verbose", "--archive", "--delete", "-z", "--safe-links"], rsync__args: ["--verbose", "--archive", "--delete", "-z", "--safe-links"],
rsync__exclude: ["./telegraf", ".vagrant/"] rsync__exclude: ["./telegraf", ".vagrant/"]

View File

@ -39,6 +39,7 @@ LOGROTATE_DIR=/etc/logrotate.d
SAMPLE_CONFIGURATION=etc/config.sample.toml SAMPLE_CONFIGURATION=etc/config.sample.toml
LOGROTATE_CONFIGURATION=etc/logrotate.d/telegraf LOGROTATE_CONFIGURATION=etc/logrotate.d/telegraf
INITD_SCRIPT=scripts/init.sh INITD_SCRIPT=scripts/init.sh
SYSTEMD_SCRIPT=scripts/telegraf.service
TMP_WORK_DIR=`mktemp -d` TMP_WORK_DIR=`mktemp -d`
POST_INSTALL_PATH=`mktemp` POST_INSTALL_PATH=`mktemp`
@ -49,7 +50,7 @@ MAINTAINER=support@influxdb.com
VENDOR=InfluxDB VENDOR=InfluxDB
DESCRIPTION="InfluxDB Telegraf agent" DESCRIPTION="InfluxDB Telegraf agent"
PKG_DEPS=(coreutils) PKG_DEPS=(coreutils)
GO_VERSION="go1.4.2" GO_VERSION="go1.5"
GOPATH_INSTALL= GOPATH_INSTALL=
BINS=( BINS=(
telegraf telegraf
@ -156,27 +157,41 @@ generate_postinstall_script() {
cat <<EOF >$POST_INSTALL_PATH cat <<EOF >$POST_INSTALL_PATH
rm -f $INSTALL_ROOT_DIR/telegraf rm -f $INSTALL_ROOT_DIR/telegraf
rm -f $INSTALL_ROOT_DIR/init.sh rm -f $INSTALL_ROOT_DIR/init.sh
ln -s $INSTALL_ROOT_DIR/versions/$version/telegraf $INSTALL_ROOT_DIR/telegraf ln -sfn $INSTALL_ROOT_DIR/versions/$version/telegraf $INSTALL_ROOT_DIR/telegraf
ln -s $INSTALL_ROOT_DIR/versions/$version/scripts/init.sh $INSTALL_ROOT_DIR/init.sh
rm -f /etc/init.d/telegraf
ln -sfn $INSTALL_ROOT_DIR/init.sh /etc/init.d/telegraf
chmod +x /etc/init.d/telegraf
if which update-rc.d > /dev/null 2>&1 ; then
update-rc.d -f telegraf remove
update-rc.d telegraf defaults
else
chkconfig --add telegraf
fi
if ! id telegraf >/dev/null 2>&1; then if ! id telegraf >/dev/null 2>&1; then
useradd --system -U -M telegraf useradd --system -U -M telegraf
fi fi
# Systemd
if which systemctl > /dev/null 2>&1 ; then
cp $INSTALL_ROOT_DIR/versions/$version/scripts/telegraf.service \
/lib/systemd/system/telegraf.service
systemctl enable telegraf
# Sysv
else
ln -sfn $INSTALL_ROOT_DIR/versions/$version/scripts/init.sh \
$INSTALL_ROOT_DIR/init.sh
rm -f /etc/init.d/telegraf
ln -sfn $INSTALL_ROOT_DIR/init.sh /etc/init.d/telegraf
chmod +x /etc/init.d/telegraf
# update-rc.d sysv service:
if which update-rc.d > /dev/null 2>&1 ; then
update-rc.d -f telegraf remove
update-rc.d telegraf defaults
# CentOS-style sysv:
else
chkconfig --add telegraf
fi
mkdir -p $TELEGRAF_LOG_DIR
chown -R -L telegraf:telegraf $TELEGRAF_LOG_DIR
fi
chown -R -L telegraf:telegraf $INSTALL_ROOT_DIR chown -R -L telegraf:telegraf $INSTALL_ROOT_DIR
chmod -R a+rX $INSTALL_ROOT_DIR chmod -R a+rX $INSTALL_ROOT_DIR
mkdir -p $TELEGRAF_LOG_DIR
chown -R -L telegraf:telegraf $TELEGRAF_LOG_DIR
EOF EOF
echo "Post-install script created successfully at $POST_INSTALL_PATH" echo "Post-install script created successfully at $POST_INSTALL_PATH"
} }
@ -189,7 +204,7 @@ if [ "$1" == "-h" ]; then
fi fi
VERSION=`git describe --always --tags | tr -d v` VERSION=`git describe --always --tags | tr -d v`
cd `git rev-parse --show-toplevel`
echo -e "\nStarting package process, version: $VERSION\n" echo -e "\nStarting package process, version: $VERSION\n"
if [ "$CIRCLE_BRANCH" == "" ]; then if [ "$CIRCLE_BRANCH" == "" ]; then
@ -213,13 +228,19 @@ done
echo "${BINS[*]} copied to $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION" echo "${BINS[*]} copied to $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION"
cp $INITD_SCRIPT $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION/scripts cp $INITD_SCRIPT $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION/scripts
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "Failed to copy init.d script to packaging directory -- aborting." echo "Failed to copy init.d script to packaging directory -- aborting."
cleanup_exit 1 cleanup_exit 1
fi fi
echo "$INITD_SCRIPT copied to $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION/scripts" echo "$INITD_SCRIPT copied to $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION/scripts"
cp $SYSTEMD_SCRIPT $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION/scripts
if [ $? -ne 0 ]; then
echo "Failed to copy systemd file to packaging directory -- aborting."
cleanup_exit 1
fi
echo "$SYSTEMD_SCRIPT copied to $TMP_WORK_DIR/$INSTALL_ROOT_DIR/versions/$VERSION/scripts"
cp $SAMPLE_CONFIGURATION $TMP_WORK_DIR/$CONFIG_ROOT_DIR/telegraf.conf cp $SAMPLE_CONFIGURATION $TMP_WORK_DIR/$CONFIG_ROOT_DIR/telegraf.conf
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "Failed to copy $SAMPLE_CONFIGURATION to packaging directory -- aborting." echo "Failed to copy $SAMPLE_CONFIGURATION to packaging directory -- aborting."

View File

@ -8,6 +8,8 @@ EnvironmentFile=-/etc/default/telegraf
User=telegraf User=telegraf
ExecStart=/opt/telegraf/telegraf -config /etc/opt/telegraf/telegraf.conf $TELEGRAF_OPTS ExecStart=/opt/telegraf/telegraf -config /etc/opt/telegraf/telegraf.conf $TELEGRAF_OPTS
Restart=on-failure Restart=on-failure
KillMode=process
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
Alias=telegraf.service