// ApplyAgent loads the toml config into the given interface func (c *Config) ApplyAgent(v interface{}) error { if c.agent != nil { return toml.UnmarshalTable(c.agent, v) } return nil }
func (c *Config) addOutput(name string, table *ast.Table) error { if len(c.OutputFilters) > 0 && !sliceContains(name, c.OutputFilters) { return nil } creator, ok := outputs.Outputs[name] if !ok { return fmt.Errorf("Undefined but requested output: %s", name) } output := creator() outputConfig, err := buildOutput(name, table) if err != nil { return err } if err := toml.UnmarshalTable(table, output); err != nil { return err } ro := models.NewRunningOutput(name, output, outputConfig) if c.Agent.MetricBufferLimit > 0 { ro.PointBufferLimit = c.Agent.MetricBufferLimit } ro.Quiet = c.Agent.Quiet c.Outputs = append(c.Outputs, ro) return nil }
func (c *Config) addPlugin(name string, table *ast.Table) error { if len(c.PluginFilters) > 0 && !sliceContains(name, c.PluginFilters) { return nil } creator, ok := plugins.Plugins[name] if !ok { return fmt.Errorf("Undefined but requested plugin: %s", name) } plugin := creator() pluginConfig, err := buildPlugin(name, table) if err != nil { return err } if err := toml.UnmarshalTable(table, plugin); err != nil { return err } rp := &RunningPlugin{ Name: name, Plugin: plugin, Config: pluginConfig, } c.Plugins = append(c.Plugins, rp) return nil }
// ApplyAgent loads the toml config into the given Agent object, overriding // defaults (such as collection duration) with the values from the toml config. func (c *Config) ApplyAgent(a *Agent) error { if c.agent != nil { return toml.UnmarshalTable(c.agent, a) } return nil }
func (c *Config) addInput(name string, table *ast.Table) error { if len(c.InputFilters) > 0 && !sliceContains(name, c.InputFilters) { return nil } // Legacy support renaming io input to diskio if name == "io" { name = "diskio" } creator, ok := inputs.Inputs[name] if !ok { return fmt.Errorf("Undefined but requested input: %s", name) } input := creator() pluginConfig, err := buildInput(name, table) if err != nil { return err } if err := toml.UnmarshalTable(table, input); err != nil { return err } rp := &RunningInput{ Name: name, Input: input, Config: pluginConfig, } c.Inputs = append(c.Inputs, rp) return nil }
func (c *Config) addOutput(name string, table *ast.Table) error { if len(c.OutputFilters) > 0 && !sliceContains(name, c.OutputFilters) { return nil } creator, ok := outputs.Outputs[name] if !ok { return fmt.Errorf("Undefined but requested output: %s", name) } output := creator() outputConfig, err := buildOutput(name, table) if err != nil { return err } if err := toml.UnmarshalTable(table, output); err != nil { return err } ro := &RunningOutput{ Name: name, Output: output, Config: outputConfig, } c.Outputs = append(c.Outputs, ro) return nil }
// LoadConfig loads the given config file and returns a *Config pointer 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{ Tags: make(map[string]string), plugins: make(map[string]plugins.Plugin), pluginConfigurations: make(map[string]*ConfiguredPlugin), outputs: make(map[string]outputs.Output), pluginFieldsSet: make(map[string][]string), pluginConfigurationFieldsSet: make(map[string][]string), outputFieldsSet: make(map[string][]string), } for name, val := range tbl.Fields { subtbl, ok := val.(*ast.Table) if !ok { return nil, errors.New("invalid configuration") } switch name { case "agent": err := c.parseAgent(subtbl) if err != nil { return nil, err } case "tags": if err = toml.UnmarshalTable(subtbl, c.Tags); err != nil { return nil, err } case "outputs": for outputName, outputVal := range subtbl.Fields { outputSubtbl, ok := outputVal.(*ast.Table) if !ok { return nil, err } err = c.parseOutput(outputName, outputSubtbl) if err != nil { return nil, err } } default: err = c.parsePlugin(name, subtbl) if err != nil { return nil, err } } } return c, nil }
// buildInput parses input specific items from the ast.Table, // builds the filter and returns a // InputConfig to be inserted into RunningInput func buildInput(name string, tbl *ast.Table) (*InputConfig, error) { cp := &InputConfig{Name: name} if node, ok := tbl.Fields["interval"]; ok { if kv, ok := node.(*ast.KeyValue); ok { if str, ok := kv.Value.(*ast.String); ok { dur, err := time.ParseDuration(str.Value) if err != nil { return nil, err } cp.Interval = dur } } } if node, ok := tbl.Fields["name_prefix"]; ok { if kv, ok := node.(*ast.KeyValue); ok { if str, ok := kv.Value.(*ast.String); ok { cp.MeasurementPrefix = str.Value } } } if node, ok := tbl.Fields["name_suffix"]; ok { if kv, ok := node.(*ast.KeyValue); ok { if str, ok := kv.Value.(*ast.String); ok { cp.MeasurementSuffix = str.Value } } } if node, ok := tbl.Fields["name_override"]; ok { if kv, ok := node.(*ast.KeyValue); ok { if str, ok := kv.Value.(*ast.String); ok { cp.NameOverride = str.Value } } } cp.Tags = make(map[string]string) if node, ok := tbl.Fields["tags"]; ok { if subtbl, ok := node.(*ast.Table); ok { if err := toml.UnmarshalTable(subtbl, cp.Tags); err != nil { log.Printf("Could not parse tags for input %s\n", name) } } } delete(tbl.Fields, "name_prefix") delete(tbl.Fields, "name_suffix") delete(tbl.Fields, "name_override") delete(tbl.Fields, "interval") delete(tbl.Fields, "tags") cp.Filter = buildFilter(tbl) return cp, nil }
// Parse the agent config out of the given *ast.Table. func (c *Config) parseAgent(agentAst *ast.Table) error { c.agentFieldsSet = extractFieldNames(agentAst) agent := &Agent{} err := toml.UnmarshalTable(agentAst, agent) if err != nil { return err } c.agent = agent return nil }
// Parse an output config out of the given *ast.Table. func (c *Config) parseOutput(name string, outputAst *ast.Table, id int) error { c.outputFieldsSet[name] = extractFieldNames(outputAst) creator, ok := outputs.Outputs[name] if !ok { return fmt.Errorf("Undefined but requested output: %s", name) } output := creator() err := toml.UnmarshalTable(outputAst, output) if err != nil { return err } c.outputs[fmt.Sprintf("%s-%d", name, id)] = output return nil }
func (c *Config) ApplyPlugin(name string, v interface{}) (*ConfiguredPlugin, error) { cp := &ConfiguredPlugin{Name: name} if tbl, ok := c.plugins[name]; ok { if node, ok := tbl.Fields["pass"]; ok { if kv, ok := node.(*ast.KeyValue); ok { if ary, ok := kv.Value.(*ast.Array); ok { for _, elem := range ary.Value { if str, ok := elem.(*ast.String); ok { cp.Pass = append(cp.Pass, str.Value) } } } } } if node, ok := tbl.Fields["drop"]; ok { if kv, ok := node.(*ast.KeyValue); ok { if ary, ok := kv.Value.(*ast.Array); ok { for _, elem := range ary.Value { if str, ok := elem.(*ast.String); ok { cp.Drop = append(cp.Drop, str.Value) } } } } } if node, ok := tbl.Fields["interval"]; ok { if kv, ok := node.(*ast.KeyValue); ok { if str, ok := kv.Value.(*ast.String); ok { dur, err := time.ParseDuration(str.Value) if err != nil { return nil, err } cp.Interval = dur } } } delete(tbl.Fields, "drop") delete(tbl.Fields, "pass") delete(tbl.Fields, "interval") return cp, toml.UnmarshalTable(tbl, v) } return cp, nil }
// LoadConfig loads the given config file and returns a *Config pointer 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{ Tags: make(map[string]string), plugins: make(map[string]*ast.Table), outputs: make(map[string]*ast.Table), } for name, val := range tbl.Fields { subtbl, ok := val.(*ast.Table) if !ok { return nil, errInvalidConfig } switch name { case "agent": c.agent = subtbl case "tags": if err := toml.UnmarshalTable(subtbl, c.Tags); err != nil { return nil, errInvalidConfig } case "outputs": for outputName, outputVal := range subtbl.Fields { outputSubtbl, ok := outputVal.(*ast.Table) if !ok { return nil, errInvalidConfig } c.outputs[outputName] = outputSubtbl } default: c.plugins[name] = subtbl } } return c, nil }
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 } switch name { case "influxdb": err := toml.UnmarshalTable(subtbl, c) if err != nil { return nil, err } case "agent": c.agent = subtbl default: c.plugins[name] = subtbl } } return c, nil }
// Parse a plugin config, plus plugin meta-config, out of the given *ast.Table. func (c *Config) parsePlugin(name string, pluginAst *ast.Table) error { creator, ok := plugins.Plugins[name] if !ok { return fmt.Errorf("Undefined but requested plugin: %s", name) } plugin := creator() cp := &ConfiguredPlugin{Name: name} cpFields := make([]string, 0, 5) if node, ok := pluginAst.Fields["pass"]; ok { if kv, ok := node.(*ast.KeyValue); ok { if ary, ok := kv.Value.(*ast.Array); ok { for _, elem := range ary.Value { if str, ok := elem.(*ast.String); ok { cp.Pass = append(cp.Pass, str.Value) } } cpFields = append(cpFields, "pass") } } } if node, ok := pluginAst.Fields["drop"]; ok { if kv, ok := node.(*ast.KeyValue); ok { if ary, ok := kv.Value.(*ast.Array); ok { for _, elem := range ary.Value { if str, ok := elem.(*ast.String); ok { cp.Drop = append(cp.Drop, str.Value) } } cpFields = append(cpFields, "drop") } } } if node, ok := pluginAst.Fields["interval"]; ok { if kv, ok := node.(*ast.KeyValue); ok { if str, ok := kv.Value.(*ast.String); ok { dur, err := time.ParseDuration(str.Value) if err != nil { return err } cp.Interval = dur cpFields = append(cpFields, "interval") } } } if node, ok := pluginAst.Fields["tagpass"]; ok { if subtbl, ok := node.(*ast.Table); ok { for name, val := range subtbl.Fields { if kv, ok := val.(*ast.KeyValue); ok { tagfilter := &TagFilter{Name: name} if ary, ok := kv.Value.(*ast.Array); ok { for _, elem := range ary.Value { if str, ok := elem.(*ast.String); ok { tagfilter.Filter = append(tagfilter.Filter, str.Value) } } } cp.TagPass = append(cp.TagPass, *tagfilter) cpFields = append(cpFields, "tagpass") } } } } if node, ok := pluginAst.Fields["tagdrop"]; ok { if subtbl, ok := node.(*ast.Table); ok { for name, val := range subtbl.Fields { if kv, ok := val.(*ast.KeyValue); ok { tagfilter := &TagFilter{Name: name} if ary, ok := kv.Value.(*ast.Array); ok { for _, elem := range ary.Value { if str, ok := elem.(*ast.String); ok { tagfilter.Filter = append(tagfilter.Filter, str.Value) } } } cp.TagDrop = append(cp.TagDrop, *tagfilter) cpFields = append(cpFields, "tagdrop") } } } } delete(pluginAst.Fields, "drop") delete(pluginAst.Fields, "pass") delete(pluginAst.Fields, "interval") delete(pluginAst.Fields, "tagdrop") delete(pluginAst.Fields, "tagpass") c.pluginFieldsSet[name] = extractFieldNames(pluginAst) c.pluginConfigurationFieldsSet[name] = cpFields err := toml.UnmarshalTable(pluginAst, plugin) if err != nil { return err } c.plugins[name] = plugin c.pluginConfigurations[name] = cp return nil }
// LoadConfig loads the given config file and returns a *Config pointer 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{ Tags: make(map[string]string), plugins: make(map[string]plugins.Plugin), pluginConfigurations: make(map[string]*ConfiguredPlugin), outputs: make(map[string]outputs.Output), pluginFieldsSet: make(map[string][]string), pluginConfigurationFieldsSet: make(map[string][]string), outputFieldsSet: make(map[string][]string), } for name, val := range tbl.Fields { subTable, ok := val.(*ast.Table) if !ok { return nil, errors.New("invalid configuration") } switch name { case "agent": err := c.parseAgent(subTable) if err != nil { log.Printf("Could not parse [agent] config\n") return nil, err } case "tags": if err = toml.UnmarshalTable(subTable, c.Tags); err != nil { log.Printf("Could not parse [tags] config\n") return nil, err } case "outputs": for outputName, outputVal := range subTable.Fields { switch outputSubTable := outputVal.(type) { case *ast.Table: err = c.parseOutput(outputName, outputSubTable, 0) if err != nil { log.Printf("Could not parse config for output: %s\n", outputName) return nil, err } case []*ast.Table: for id, t := range outputSubTable { err = c.parseOutput(outputName, t, id) if err != nil { log.Printf("Could not parse config for output: %s\n", outputName) return nil, err } } default: return nil, fmt.Errorf("Unsupported config format: %s", outputName) } } default: err = c.parsePlugin(name, subTable) if err != nil { return nil, err } } } return c, nil }
// ApplyOutput loads the toml config into the given interface func (c *Config) ApplyOutput(name string, v interface{}) error { if c.outputs[name] != nil { return toml.UnmarshalTable(c.outputs[name], v) } return nil }
// UnmarshalTable provides a mechanism to incrementally unmarshal an AST // produced by ParseFile. This method was originally provided by naoina/toml func UnmarshalTable(t *ast.Table, v interface{}) error { return toml.UnmarshalTable(t, v) }
// LoadConfig loads the given config file and applies it to c func (c *Config) LoadConfig(path string) error { data, err := ioutil.ReadFile(path) if err != nil { return err } tbl, err := toml.Parse(data) if err != nil { return err } for name, val := range tbl.Fields { subTable, ok := val.(*ast.Table) if !ok { return errors.New("invalid configuration") } switch name { case "agent": if err = toml.UnmarshalTable(subTable, c.Agent); err != nil { log.Printf("Could not parse [agent] config\n") return err } case "tags": if err = toml.UnmarshalTable(subTable, c.Tags); err != nil { log.Printf("Could not parse [tags] config\n") return err } case "outputs": for outputName, outputVal := range subTable.Fields { switch outputSubTable := outputVal.(type) { case *ast.Table: if err = c.addOutput(outputName, outputSubTable); err != nil { return err } case []*ast.Table: for _, t := range outputSubTable { if err = c.addOutput(outputName, t); err != nil { return err } } default: return fmt.Errorf("Unsupported config format: %s", outputName) } } case "plugins": for pluginName, pluginVal := range subTable.Fields { switch pluginSubTable := pluginVal.(type) { case *ast.Table: if err = c.addPlugin(pluginName, pluginSubTable); err != nil { return err } case []*ast.Table: for _, t := range pluginSubTable { if err = c.addPlugin(pluginName, t); err != nil { return err } } default: return fmt.Errorf("Unsupported config format: %s", pluginName) } } // Assume it's a plugin for legacy config file support if no other // identifiers are present default: if err = c.addPlugin(name, subTable); err != nil { return err } } } return nil }