Initial spike
This is mostly to solidify the overall structure with the agent, plugins, and testing philosphy.
This commit is contained in:
parent
b8e13890a9
commit
db74acb86d
|
@ -0,0 +1,132 @@
|
||||||
|
package tivan
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/influxdb/tivan/plugins"
|
||||||
|
"github.com/vektra/cypress"
|
||||||
|
"github.com/vektra/cypress/plugins/metrics"
|
||||||
|
)
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Metrics interface {
|
||||||
|
Receive(*cypress.Message) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type Agent struct {
|
||||||
|
Interval Duration
|
||||||
|
Debug bool
|
||||||
|
HTTP string
|
||||||
|
|
||||||
|
Config *Config
|
||||||
|
|
||||||
|
plugins []plugins.Plugin
|
||||||
|
metrics Metrics
|
||||||
|
|
||||||
|
eachInternal []func()
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAgent(config *Config) *Agent {
|
||||||
|
m := metrics.NewMetricSink()
|
||||||
|
|
||||||
|
agent := &Agent{Config: config, metrics: m}
|
||||||
|
|
||||||
|
err := config.Apply("agent", agent)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.URL != "" {
|
||||||
|
icfg := metrics.DefaultInfluxConfig()
|
||||||
|
icfg.URL = config.URL
|
||||||
|
icfg.Username = config.Username
|
||||||
|
icfg.Password = config.Password
|
||||||
|
icfg.Database = config.Database
|
||||||
|
icfg.UserAgent = config.UserAgent
|
||||||
|
|
||||||
|
agent.eachInternal = append(agent.eachInternal, func() {
|
||||||
|
if agent.Debug {
|
||||||
|
log.Printf("flushing to influxdb")
|
||||||
|
}
|
||||||
|
|
||||||
|
m.FlushInflux(icfg)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return agent
|
||||||
|
}
|
||||||
|
|
||||||
|
type HTTPInterface interface {
|
||||||
|
RunHTTP(string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Agent) RunHTTP(addr string) {
|
||||||
|
a.metrics.(HTTPInterface).RunHTTP(addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Agent) LoadPlugins() ([]string, error) {
|
||||||
|
var names []string
|
||||||
|
|
||||||
|
for name, creator := range plugins.Plugins {
|
||||||
|
a.plugins = append(a.plugins, creator())
|
||||||
|
names = append(names, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(names)
|
||||||
|
|
||||||
|
return names, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Agent) crank() error {
|
||||||
|
for _, plugin := range a.plugins {
|
||||||
|
msgs, err := plugin.Read()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, m := range msgs {
|
||||||
|
for k, v := range a.Config.Tags {
|
||||||
|
m.AddTag(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
if a.Debug {
|
||||||
|
fmt.Println(m.KVString())
|
||||||
|
}
|
||||||
|
|
||||||
|
err = a.metrics.Receive(m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Agent) Run(shutdown chan struct{}) {
|
||||||
|
if a.HTTP != "" {
|
||||||
|
go a.RunHTTP(a.HTTP)
|
||||||
|
}
|
||||||
|
|
||||||
|
ticker := time.NewTicker(a.Interval.Duration)
|
||||||
|
|
||||||
|
for {
|
||||||
|
err := a.crank()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error in plugins: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range a.eachInternal {
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-shutdown:
|
||||||
|
return
|
||||||
|
case <-ticker.C:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
package tivan
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/influxdb/tivan/plugins"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/vektra/cypress"
|
||||||
|
"github.com/vektra/neko"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAgent(t *testing.T) {
|
||||||
|
n := neko.Start(t)
|
||||||
|
|
||||||
|
var (
|
||||||
|
plugin plugins.MockPlugin
|
||||||
|
metrics MockMetrics
|
||||||
|
)
|
||||||
|
|
||||||
|
n.CheckMock(&plugin.Mock)
|
||||||
|
n.CheckMock(&metrics.Mock)
|
||||||
|
|
||||||
|
n.It("drives the plugins and sends them to the metrics", func() {
|
||||||
|
a := &Agent{
|
||||||
|
plugins: []plugins.Plugin{&plugin},
|
||||||
|
metrics: &metrics,
|
||||||
|
Config: &Config{},
|
||||||
|
}
|
||||||
|
|
||||||
|
m1 := cypress.Metric()
|
||||||
|
m1.Add("name", "foo")
|
||||||
|
m1.Add("value", 1.2)
|
||||||
|
|
||||||
|
m2 := cypress.Metric()
|
||||||
|
m2.Add("name", "bar")
|
||||||
|
m2.Add("value", 888)
|
||||||
|
|
||||||
|
msgs := []*cypress.Message{m1, m2}
|
||||||
|
|
||||||
|
plugin.On("Read").Return(msgs, nil)
|
||||||
|
metrics.On("Receive", m1).Return(nil)
|
||||||
|
metrics.On("Receive", m2).Return(nil)
|
||||||
|
|
||||||
|
err := a.crank()
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
n.It("applies tags as the messages pass through", func() {
|
||||||
|
a := &Agent{
|
||||||
|
plugins: []plugins.Plugin{&plugin},
|
||||||
|
metrics: &metrics,
|
||||||
|
Config: &Config{
|
||||||
|
Tags: map[string]string{
|
||||||
|
"dc": "us-west-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
m1 := cypress.Metric()
|
||||||
|
m1.Add("name", "foo")
|
||||||
|
m1.Add("value", 1.2)
|
||||||
|
|
||||||
|
msgs := []*cypress.Message{m1}
|
||||||
|
|
||||||
|
m2 := cypress.Metric()
|
||||||
|
m2.Timestamp = m1.Timestamp
|
||||||
|
m2.Add("name", "foo")
|
||||||
|
m2.Add("value", 1.2)
|
||||||
|
m2.AddTag("dc", "us-west-1")
|
||||||
|
|
||||||
|
plugin.On("Read").Return(msgs, nil)
|
||||||
|
metrics.On("Receive", m2).Return(nil)
|
||||||
|
|
||||||
|
err := a.crank()
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
n.Meow()
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/influxdb/tivan"
|
||||||
|
_ "github.com/influxdb/tivan/plugins/all"
|
||||||
|
)
|
||||||
|
|
||||||
|
var fDebug = flag.Bool("debug", false, "show metrics as they're generated to stdout")
|
||||||
|
|
||||||
|
var fConfig = flag.String("config", "", "configuration file to load")
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
var (
|
||||||
|
config *tivan.Config
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
if *fConfig != "" {
|
||||||
|
config, err = tivan.LoadConfig(*fConfig)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
config = tivan.DefaultConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
ag := tivan.NewAgent(config)
|
||||||
|
|
||||||
|
if *fDebug {
|
||||||
|
ag.Debug = true
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins, err := ag.LoadPlugins()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
shutdown := make(chan struct{})
|
||||||
|
|
||||||
|
signals := make(chan os.Signal)
|
||||||
|
|
||||||
|
signal.Notify(signals, os.Interrupt)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
<-signals
|
||||||
|
close(shutdown)
|
||||||
|
}()
|
||||||
|
|
||||||
|
log.Print("InfluxDB Agent running")
|
||||||
|
log.Printf("Loaded plugins: %s", strings.Join(plugins, " "))
|
||||||
|
if ag.Debug {
|
||||||
|
log.Printf("Debug: enabled")
|
||||||
|
log.Printf("Agent Config: %#v", ag)
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.URL != "" {
|
||||||
|
log.Printf("Sending metrics to: %s", config.URL)
|
||||||
|
log.Printf("Tags enabled: %v", config.ListTags())
|
||||||
|
}
|
||||||
|
|
||||||
|
ag.Run(shutdown)
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
package tivan
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/naoina/toml"
|
||||||
|
"github.com/naoina/toml/ast"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Duration struct {
|
||||||
|
time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Duration) UnmarshalTOML(b []byte) error {
|
||||||
|
dur, err := time.ParseDuration(string(b[1 : len(b)-1]))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Duration = dur
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
URL string
|
||||||
|
Username string
|
||||||
|
Password string
|
||||||
|
Database string
|
||||||
|
UserAgent string
|
||||||
|
Tags map[string]string
|
||||||
|
|
||||||
|
plugins map[string]*ast.Table
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) Plugins() map[string]*ast.Table {
|
||||||
|
return c.plugins
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) Apply(name string, v interface{}) error {
|
||||||
|
if tbl, ok := c.plugins[name]; ok {
|
||||||
|
return toml.UnmarshalTable(tbl, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DefaultConfig() *Config {
|
||||||
|
return &Config{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ErrInvalidConfig = errors.New("invalid configuration")
|
||||||
|
|
||||||
|
func LoadConfig(path string) (*Config, error) {
|
||||||
|
data, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tbl, err := toml.Parse(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c := &Config{
|
||||||
|
plugins: make(map[string]*ast.Table),
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, val := range tbl.Fields {
|
||||||
|
subtbl, ok := val.(*ast.Table)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrInvalidConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
if name == "influxdb" {
|
||||||
|
err := toml.UnmarshalTable(subtbl, c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c.plugins[name] = subtbl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) ListTags() string {
|
||||||
|
var tags []string
|
||||||
|
|
||||||
|
for k, v := range c.Tags {
|
||||||
|
tags = append(tags, fmt.Sprintf("%s=%s", k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(tags)
|
||||||
|
|
||||||
|
return strings.Join(tags, " ")
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package tivan
|
||||||
|
|
||||||
|
import "github.com/stretchr/testify/mock"
|
||||||
|
|
||||||
|
import "github.com/vektra/cypress"
|
||||||
|
|
||||||
|
type MockMetrics struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockMetrics) Receive(_a0 *cypress.Message) error {
|
||||||
|
ret := m.Called(_a0)
|
||||||
|
|
||||||
|
r0 := ret.Error(0)
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package tivan
|
||||||
|
|
||||||
|
import "github.com/stretchr/testify/mock"
|
||||||
|
|
||||||
|
import "github.com/vektra/cypress"
|
||||||
|
|
||||||
|
type MockPlugin struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockPlugin) Read() ([]*cypress.Message, error) {
|
||||||
|
ret := m.Called()
|
||||||
|
|
||||||
|
r0 := ret.Get(0).([]*cypress.Message)
|
||||||
|
r1 := ret.Error(1)
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package all
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/influxdb/tivan/plugins/system"
|
||||||
|
)
|
|
@ -0,0 +1,18 @@
|
||||||
|
package plugins
|
||||||
|
|
||||||
|
import "github.com/stretchr/testify/mock"
|
||||||
|
|
||||||
|
import "github.com/vektra/cypress"
|
||||||
|
|
||||||
|
type MockPlugin struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockPlugin) Read() ([]*cypress.Message, error) {
|
||||||
|
ret := m.Called()
|
||||||
|
|
||||||
|
r0 := ret.Get(0).([]*cypress.Message)
|
||||||
|
r1 := ret.Error(1)
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package plugins
|
||||||
|
|
||||||
|
import "github.com/vektra/cypress"
|
||||||
|
|
||||||
|
type Plugin interface {
|
||||||
|
Read() ([]*cypress.Message, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Creator func() Plugin
|
||||||
|
|
||||||
|
var Plugins = map[string]Creator{}
|
||||||
|
|
||||||
|
func Add(name string, creator Creator) {
|
||||||
|
Plugins[name] = creator
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package system
|
||||||
|
|
||||||
|
import "github.com/stretchr/testify/mock"
|
||||||
|
|
||||||
|
import "github.com/shirou/gopsutil/load"
|
||||||
|
|
||||||
|
type MockPS struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockPS) LoadAvg() (*load.LoadAvgStat, error) {
|
||||||
|
ret := m.Called()
|
||||||
|
|
||||||
|
r0 := ret.Get(0).(*load.LoadAvgStat)
|
||||||
|
r1 := ret.Error(1)
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/influxdb/tivan/plugins"
|
||||||
|
"github.com/shirou/gopsutil/load"
|
||||||
|
"github.com/vektra/cypress"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PS interface {
|
||||||
|
LoadAvg() (*load.LoadAvgStat, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type SystemStats struct {
|
||||||
|
ps PS
|
||||||
|
tags map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SystemStats) Read() ([]*cypress.Message, error) {
|
||||||
|
lv, err := s.ps.LoadAvg()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
m1 := cypress.Metric()
|
||||||
|
m1.Add("type", "gauge")
|
||||||
|
m1.Add("name", "load1")
|
||||||
|
m1.Add("value", lv.Load1)
|
||||||
|
|
||||||
|
for k, v := range s.tags {
|
||||||
|
m1.AddTag(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
m2 := cypress.Metric()
|
||||||
|
m2.Add("type", "gauge")
|
||||||
|
m2.Add("name", "load5")
|
||||||
|
m2.Add("value", lv.Load5)
|
||||||
|
|
||||||
|
for k, v := range s.tags {
|
||||||
|
m2.AddTag(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
m3 := cypress.Metric()
|
||||||
|
m3.Add("type", "gauge")
|
||||||
|
m3.Add("name", "load15")
|
||||||
|
m3.Add("value", lv.Load15)
|
||||||
|
|
||||||
|
for k, v := range s.tags {
|
||||||
|
m3.AddTag(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return []*cypress.Message{m1, m2, m3}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type systemPS struct{}
|
||||||
|
|
||||||
|
func (s *systemPS) LoadAvg() (*load.LoadAvgStat, error) {
|
||||||
|
return load.LoadAvg()
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
plugins.Add("system", func() plugins.Plugin {
|
||||||
|
return &SystemStats{ps: &systemPS{}}
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/load"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/vektra/neko"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSystemStats(t *testing.T) {
|
||||||
|
n := neko.Start(t)
|
||||||
|
|
||||||
|
var mps MockPS
|
||||||
|
|
||||||
|
n.CheckMock(&mps.Mock)
|
||||||
|
|
||||||
|
n.It("generates metrics from the system information", func() {
|
||||||
|
ss := &SystemStats{ps: &mps}
|
||||||
|
|
||||||
|
lv := &load.LoadAvgStat{
|
||||||
|
Load1: 0.3,
|
||||||
|
Load5: 1.5,
|
||||||
|
Load15: 0.8,
|
||||||
|
}
|
||||||
|
|
||||||
|
mps.On("LoadAvg").Return(lv, nil)
|
||||||
|
|
||||||
|
msgs, err := ss.Read()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
name, ok := msgs[0].GetString("name")
|
||||||
|
require.True(t, ok)
|
||||||
|
|
||||||
|
assert.Equal(t, "load1", name)
|
||||||
|
|
||||||
|
val, ok := msgs[0].GetFloat("value")
|
||||||
|
require.True(t, ok)
|
||||||
|
|
||||||
|
assert.Equal(t, 0.3, val)
|
||||||
|
|
||||||
|
name, ok = msgs[1].GetString("name")
|
||||||
|
require.True(t, ok)
|
||||||
|
|
||||||
|
assert.Equal(t, "load5", name)
|
||||||
|
|
||||||
|
val, ok = msgs[1].GetFloat("value")
|
||||||
|
require.True(t, ok)
|
||||||
|
|
||||||
|
assert.Equal(t, 1.5, val)
|
||||||
|
|
||||||
|
name, ok = msgs[2].GetString("name")
|
||||||
|
require.True(t, ok)
|
||||||
|
|
||||||
|
assert.Equal(t, "load15", name)
|
||||||
|
|
||||||
|
val, ok = msgs[2].GetFloat("value")
|
||||||
|
require.True(t, ok)
|
||||||
|
|
||||||
|
assert.Equal(t, 0.8, val)
|
||||||
|
})
|
||||||
|
|
||||||
|
n.It("adds any tags registered", func() {
|
||||||
|
ss := &SystemStats{
|
||||||
|
ps: &mps,
|
||||||
|
tags: map[string]string{
|
||||||
|
"host": "my.test",
|
||||||
|
"dc": "us-west-1",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
lv := &load.LoadAvgStat{
|
||||||
|
Load1: 0.3,
|
||||||
|
Load5: 1.5,
|
||||||
|
Load15: 0.8,
|
||||||
|
}
|
||||||
|
|
||||||
|
mps.On("LoadAvg").Return(lv, nil)
|
||||||
|
|
||||||
|
msgs, err := ss.Read()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
for _, m := range msgs {
|
||||||
|
val, ok := m.GetTag("host")
|
||||||
|
require.True(t, ok)
|
||||||
|
|
||||||
|
assert.Equal(t, val, "my.test")
|
||||||
|
|
||||||
|
val, ok = m.GetTag("dc")
|
||||||
|
require.True(t, ok)
|
||||||
|
|
||||||
|
assert.Equal(t, val, "us-west-1")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
n.Meow()
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
[agent]
|
||||||
|
interval = "5s"
|
||||||
|
http = ":11213"
|
||||||
|
debug = true
|
||||||
|
|
||||||
|
[influxdb]
|
||||||
|
url = "http://localhost:8086"
|
||||||
|
username = "root"
|
||||||
|
password = "root"
|
||||||
|
database = "cypress"
|
||||||
|
tags = { dc = "us-phx-1" }
|
||||||
|
|
Loading…
Reference in New Issue