188 lines
3.1 KiB
Go
188 lines
3.1 KiB
Go
package tivan
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/influxdb/tivan/plugins"
|
|
"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 (c *Config) PluginsDeclared() []string {
|
|
var plugins []string
|
|
|
|
for name, _ := range c.plugins {
|
|
plugins = append(plugins, name)
|
|
}
|
|
|
|
sort.Strings(plugins)
|
|
|
|
return plugins
|
|
}
|
|
|
|
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, " ")
|
|
}
|
|
|
|
type hasConfig interface {
|
|
BasicConfig() string
|
|
}
|
|
|
|
type hasDescr interface {
|
|
Description() string
|
|
}
|
|
|
|
var header = `# Tivan configuration
|
|
|
|
# Tivan is entirely plugin driven. All metrics are gathered from the
|
|
# declared plugins.
|
|
|
|
# Even if a plugin has no configuration, it must be declared in here
|
|
# to be active. Declaring a plugin means just specifying the name
|
|
# as a section with no variables.
|
|
|
|
# Configuration for influxdb server to send metrics to
|
|
# [influxdb]
|
|
# url = "http://10.20.2.4"
|
|
# username = "tivan"
|
|
# password = "metricsmetricsmetricsmetrics"
|
|
# database = "tivan"
|
|
# user_agent = "tivan"
|
|
# tags = { "dc": "us-east-1" }
|
|
|
|
# Tags can also be specified via a normal map, but only one form at a time:
|
|
|
|
# [influxdb.tags]
|
|
# dc = "us-east-1"
|
|
|
|
# PLUGINS
|
|
|
|
`
|
|
|
|
func PrintSampleConfig() {
|
|
fmt.Printf(header)
|
|
|
|
var names []string
|
|
|
|
for name, _ := range plugins.Plugins {
|
|
names = append(names, name)
|
|
}
|
|
|
|
sort.Strings(names)
|
|
|
|
for _, name := range names {
|
|
creator := plugins.Plugins[name]
|
|
|
|
plugin := creator()
|
|
|
|
fmt.Printf("# %s\n[%s]\n", plugin.Description(), name)
|
|
|
|
var config string
|
|
|
|
config = strings.TrimSpace(plugin.SampleConfig())
|
|
|
|
if config == "" {
|
|
fmt.Printf(" # no configuration\n\n")
|
|
} else {
|
|
fmt.Printf("\n")
|
|
lines := strings.Split(config, "\n")
|
|
for _, line := range lines {
|
|
fmt.Printf("%s\n", line)
|
|
}
|
|
|
|
fmt.Printf("\n")
|
|
}
|
|
}
|
|
}
|