-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0193cbe
commit 2c98e5a
Showing
12 changed files
with
592 additions
and
4 deletions.
There are no files selected for viewing
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
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
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
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,165 @@ | ||
package collectd | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"log" | ||
"os" | ||
|
||
"collectd.org/api" | ||
"collectd.org/network" | ||
|
||
"github.com/influxdata/telegraf" | ||
"github.com/influxdata/telegraf/metric" | ||
) | ||
|
||
const ( | ||
DefaultAuthFile = "/etc/collectd/auth_file" | ||
) | ||
|
||
type CollectdParser struct { | ||
// DefaultTags will be added to every parsed metric | ||
DefaultTags map[string]string | ||
|
||
popts network.ParseOpts | ||
} | ||
|
||
func (p *CollectdParser) SetParseOpts(popts *network.ParseOpts) { | ||
p.popts = *popts | ||
} | ||
|
||
func NewCollectdParser( | ||
authFile string, | ||
securityLevel string, | ||
typesDB []string, | ||
) (*CollectdParser, error) { | ||
popts := network.ParseOpts{} | ||
|
||
switch securityLevel { | ||
case "none": | ||
popts.SecurityLevel = network.None | ||
case "sign": | ||
popts.SecurityLevel = network.Sign | ||
case "encrypt": | ||
popts.SecurityLevel = network.Encrypt | ||
default: | ||
popts.SecurityLevel = network.None | ||
} | ||
|
||
if authFile == "" { | ||
authFile = DefaultAuthFile | ||
} | ||
popts.PasswordLookup = network.NewAuthFile(authFile) | ||
|
||
for _, path := range typesDB { | ||
db, err := LoadTypesDB(path) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if popts.TypesDB != nil { | ||
popts.TypesDB.Merge(db) | ||
} else { | ||
popts.TypesDB = db | ||
} | ||
} | ||
|
||
parser := CollectdParser{popts: popts} | ||
return &parser, nil | ||
} | ||
|
||
func (p *CollectdParser) Parse(buf []byte) ([]telegraf.Metric, error) { | ||
valueLists, err := network.Parse(buf, p.popts) | ||
if err != nil { | ||
return nil, fmt.Errorf("Collectd parser error: %s", err) | ||
} | ||
|
||
metrics := []telegraf.Metric{} | ||
for _, valueList := range valueLists { | ||
metrics = append(metrics, UnmarshalValueList(valueList)...) | ||
} | ||
|
||
if len(p.DefaultTags) > 0 { | ||
for _, m := range metrics { | ||
for k, v := range p.DefaultTags { | ||
// only set the default tag if it doesn't already exist: | ||
if !m.HasTag(k) { | ||
m.AddTag(k, v) | ||
} | ||
} | ||
} | ||
} | ||
|
||
return metrics, nil | ||
} | ||
|
||
func (p *CollectdParser) ParseLine(line string) (telegraf.Metric, error) { | ||
metrics, err := p.Parse([]byte(line)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if len(metrics) != 1 { | ||
return nil, errors.New("Line contains multiple metrics") | ||
} | ||
|
||
return metrics[0], nil | ||
} | ||
|
||
func (p *CollectdParser) SetDefaultTags(tags map[string]string) { | ||
p.DefaultTags = tags | ||
} | ||
|
||
// UnmarshalValueList translates a ValueList into a Telegraf metric. | ||
func UnmarshalValueList(vl *api.ValueList) []telegraf.Metric { | ||
timestamp := vl.Time.UTC() | ||
|
||
var metrics []telegraf.Metric | ||
for i := range vl.Values { | ||
var name string | ||
name = fmt.Sprintf("%s_%s", vl.Identifier.Plugin, vl.DSName(i)) | ||
tags := make(map[string]string) | ||
fields := make(map[string]interface{}) | ||
|
||
// Convert interface back to actual type, then to float64 | ||
switch value := vl.Values[i].(type) { | ||
case api.Gauge: | ||
fields["value"] = float64(value) | ||
case api.Derive: | ||
fields["value"] = float64(value) | ||
case api.Counter: | ||
fields["value"] = float64(value) | ||
} | ||
|
||
if vl.Identifier.Host != "" { | ||
tags["host"] = vl.Identifier.Host | ||
} | ||
if vl.Identifier.PluginInstance != "" { | ||
tags["instance"] = vl.Identifier.PluginInstance | ||
} | ||
if vl.Identifier.Type != "" { | ||
tags["type"] = vl.Identifier.Type | ||
} | ||
if vl.Identifier.TypeInstance != "" { | ||
tags["type_instance"] = vl.Identifier.TypeInstance | ||
} | ||
|
||
// Drop invalid points | ||
m, err := metric.New(name, tags, fields, timestamp) | ||
if err != nil { | ||
log.Printf("E! Dropping metric %v: %v", name, err) | ||
continue | ||
} | ||
|
||
metrics = append(metrics, m) | ||
} | ||
return metrics | ||
} | ||
|
||
func LoadTypesDB(path string) (*api.TypesDB, error) { | ||
reader, err := os.Open(path) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return api.NewTypesDB(reader) | ||
} |
Oops, something went wrong.