diff --git a/cmd/config-translator/translator_test.go b/cmd/config-translator/translator_test.go index 5632c65bb2a..463c12e2a8f 100644 --- a/cmd/config-translator/translator_test.go +++ b/cmd/config-translator/translator_test.go @@ -156,6 +156,10 @@ func TestProcstatConfig(t *testing.T) { checkIfSchemaValidationAsExpected(t, "../../translator/config/sampleSchema/validProcstatConfig.json", true, map[string]int{}) } +func TestEthtoolConfig(t *testing.T) { + checkIfSchemaValidationAsExpected(t, "../../translator/config/sampleSchema/validEthtoolConfig.json", true, map[string]int{}) +} + // Validate all sampleConfig files schema func TestSampleConfigSchema(t *testing.T) { if files, err := ioutil.ReadDir("../../translator/totomlconfig/sampleConfig/"); err == nil { diff --git a/go.sum b/go.sum index 94cc5655196..0195fc873ed 100644 --- a/go.sum +++ b/go.sum @@ -132,6 +132,8 @@ github.com/aws/aws-sdk-go v1.30.9 h1:DntpBUKkchINPDbhEzDRin1eEn1TG9TZFlzWPf0i8to github.com/aws/aws-sdk-go v1.30.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aws/aws-sdk-go v1.30.15 h1:Sd8QDVzzE8Sl+xNccmdj0HwMrFowv6uVUx9tGsCE1ZE= github.com/aws/aws-sdk-go v1.30.15/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aws/telegraf-private-fork v0.0.0-20200608232200-b26dcc402df7 h1:lXrBzu+rfOG8D2tn7FtUcGyFFwGxthpwT8WE9bNBRDg= +github.com/aws/telegraf-private-fork v0.0.0-20200608232200-b26dcc402df7/go.mod h1:klLKIYh/pKoNn68ZgTyp2aGO+jigfkuUef4g7giWW/8= github.com/benbjohnson/clock v1.0.0 h1:78Jk/r6m4wCi6sndMpty7A//t4dw/RW5fV4ZgDVfX1w= github.com/benbjohnson/clock v1.0.0/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= diff --git a/plugins/plugins.go b/plugins/plugins.go index f80056a34c4..9d012501b6b 100644 --- a/plugins/plugins.go +++ b/plugins/plugins.go @@ -31,6 +31,7 @@ import ( _ "github.com/influxdata/telegraf/plugins/inputs/cpu" _ "github.com/influxdata/telegraf/plugins/inputs/disk" _ "github.com/influxdata/telegraf/plugins/inputs/diskio" + _ "github.com/influxdata/telegraf/plugins/inputs/ethtool" _ "github.com/influxdata/telegraf/plugins/inputs/mem" _ "github.com/influxdata/telegraf/plugins/inputs/net" _ "github.com/influxdata/telegraf/plugins/inputs/processes" diff --git a/translator/config/sampleSchema/validEthtoolConfig.json b/translator/config/sampleSchema/validEthtoolConfig.json new file mode 100644 index 00000000000..29d88d7cb4b --- /dev/null +++ b/translator/config/sampleSchema/validEthtoolConfig.json @@ -0,0 +1,27 @@ +{ + "metrics": { + "metrics_collected": { + "ethtool": { + "interface_include": [ + "eth0", + "eth1" + ], + "metrics_include": [ + "bw_in_allowance_exceeded", + "bw_out_allowance_exceeded", + "pps_allowance_exceeded", + "conntrack_allowance_exceeded", + "linklocal_allowance_exceeded" + ] + } + }, + "append_dimensions": { + "ImageId": "${aws:ImageId}", + "InstanceId": "${aws:InstanceId}", + "InstanceType": "${aws:InstanceType}", + "AutoScalingGroupName": "${aws:AutoScalingGroupName}" + }, + "aggregation_dimensions" : [["ImageId"], ["InstanceId", "InstanceType"], ["d1"],[]], + "force_flush_interval": 60 + } + } \ No newline at end of file diff --git a/translator/config/schema.go b/translator/config/schema.go index 48a6393b1ac..b4d7826fd3c 100644 --- a/translator/config/schema.go +++ b/translator/config/schema.go @@ -167,6 +167,9 @@ var schema = `{ }, "procstat": { "$ref": "#/definitions/metricsDefinition/definitions/procstatDefinitions" + }, + "ethtool": { + "$ref": "#/definitions/metricsDefinition/definitions/ethtoolDefinitions" } }, "minProperties": 1, @@ -426,7 +429,37 @@ var schema = `{ } ] } - }, + }, + "ethtoolDefinitions": { + "type": "object", + "properties": { + "interface_include": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 255 + } + }, + "interface_exclude": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 255 + } + }, + "metrics_include": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 255 + } + } + }, + "additionalProperties": false + }, "metricsMeasurementWithoutDecorationDefinition": { "type": "array", "items": { diff --git a/translator/config/schema.json b/translator/config/schema.json index 1bdd14767cd..4c89e3681ce 100644 --- a/translator/config/schema.json +++ b/translator/config/schema.json @@ -158,6 +158,9 @@ }, "procstat": { "$ref": "#/definitions/metricsDefinition/definitions/procstatDefinitions" + }, + "ethtool": { + "$ref": "#/definitions/metricsDefinition/definitions/ethtoolDefinitions" } }, "minProperties": 1, @@ -417,7 +420,37 @@ } ] } - }, + }, + "ethtoolDefinitions": { + "type": "object", + "properties": { + "interface_include": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 255 + } + }, + "interface_exclude": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 255 + } + }, + "metrics_include": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 255 + } + } + }, + "additionalProperties": false + }, "metricsMeasurementWithoutDecorationDefinition": { "type": "array", "items": { diff --git a/translator/totomlconfig/sampleConfig/advanced_config_linux.conf b/translator/totomlconfig/sampleConfig/advanced_config_linux.conf index 1d45467dc84..cd44630a064 100644 --- a/translator/totomlconfig/sampleConfig/advanced_config_linux.conf +++ b/translator/totomlconfig/sampleConfig/advanced_config_linux.conf @@ -34,6 +34,12 @@ metricPath = "metrics" report_deltas = "true" + [[inputs.ethtool]] + fieldpass = ["bw_in_allowance_exceeded", "bw_out_allowance_exceeded", "pps_allowance_exceeded", "conntrack_allowance_exceeded", "linklocal_allowance_exceeded"] + interface_include = ["eth0", "eth1"] + [inputs.ethtool.tags] + metricPath = "metrics" + [[inputs.mem]] fieldpass = ["used_percent"] [inputs.mem.tags] diff --git a/translator/totomlconfig/sampleConfig/advanced_config_linux.json b/translator/totomlconfig/sampleConfig/advanced_config_linux.json index 27b7fdc3706..367c6e00c15 100644 --- a/translator/totomlconfig/sampleConfig/advanced_config_linux.json +++ b/translator/totomlconfig/sampleConfig/advanced_config_linux.json @@ -52,6 +52,19 @@ "measurement": [ "swap_used_percent" ] + }, + "ethtool": { + "interface_include": [ + "eth0", + "eth1" + ], + "metrics_include": [ + "bw_in_allowance_exceeded", + "bw_out_allowance_exceeded", + "pps_allowance_exceeded", + "conntrack_allowance_exceeded", + "linklocal_allowance_exceeded" + ] } } } diff --git a/translator/totomlconfig/toTomlConfig.go b/translator/totomlconfig/toTomlConfig.go index befa44f537d..20b6d4d4c11 100755 --- a/translator/totomlconfig/toTomlConfig.go +++ b/translator/totomlconfig/toTomlConfig.go @@ -28,6 +28,7 @@ import ( _ "github.com/aws/amazon-cloudwatch-agent/translator/translate/metrics/metrics_collect/customizedmetrics" _ "github.com/aws/amazon-cloudwatch-agent/translator/translate/metrics/metrics_collect/disk" _ "github.com/aws/amazon-cloudwatch-agent/translator/translate/metrics/metrics_collect/diskio" + _ "github.com/aws/amazon-cloudwatch-agent/translator/translate/metrics/metrics_collect/ethtool" _ "github.com/aws/amazon-cloudwatch-agent/translator/translate/metrics/metrics_collect/mem" _ "github.com/aws/amazon-cloudwatch-agent/translator/translate/metrics/metrics_collect/net" _ "github.com/aws/amazon-cloudwatch-agent/translator/translate/metrics/metrics_collect/netstat" diff --git a/translator/translate/metrics/metrics_collect/ethtool/ethtool.go b/translator/translate/metrics/metrics_collect/ethtool/ethtool.go new file mode 100644 index 00000000000..08cfe31f969 --- /dev/null +++ b/translator/translate/metrics/metrics_collect/ethtool/ethtool.go @@ -0,0 +1,58 @@ +package ethtool + +import ( + "github.com/aws/amazon-cloudwatch-agent/translator" + parent "github.com/aws/amazon-cloudwatch-agent/translator/translate/metrics/metrics_collect" +) + +var ChildRule = map[string]translator.Rule{} + +// +// "ethtool" : { +// "interface_include": "*", +// "interface_exclude": "", +// "metrics_include": [ +// "bw_in_allowance_exceeded", +// "bw_out_allowance_exceeded" +// ] +// } +// +const SectionKey_Ethtool = "ethtool" + +func GetCurPath() string { + curPath := parent.GetCurPath() + SectionKey_Ethtool + "/" + return curPath +} + +func RegisterRule(fieldname string, r translator.Rule) { + ChildRule[fieldname] = r +} + +type Ethtool struct { +} + +func (n *Ethtool) ApplyRule(input interface{}) (returnKey string, returnVal interface{}) { + m := input.(map[string]interface{}) + //Generate the config file for monitoring system metrics on non-windows + resArr := []interface{}{} + result := map[string]interface{}{} + //Check if this plugin exist in the input instance + //If not, not process + if _, ok := m[SectionKey_Ethtool]; !ok { + returnKey = "" + returnVal = "" + } else { + //If exists, process it + //Check if there are some config entry with rules applied + result = translator.ProcessRuleToApply(m[SectionKey_Ethtool], ChildRule, result) + resArr = append(resArr, result) + returnKey = SectionKey_Ethtool + returnVal = resArr + } + return +} + +func init() { + n := new(Ethtool) + parent.RegisterLinuxRule(SectionKey_Ethtool, n) +} diff --git a/translator/translate/metrics/metrics_collect/ethtool/ethtool_test.go b/translator/translate/metrics/metrics_collect/ethtool/ethtool_test.go new file mode 100644 index 00000000000..d5a0849bcaa --- /dev/null +++ b/translator/translate/metrics/metrics_collect/ethtool/ethtool_test.go @@ -0,0 +1,53 @@ +package ethtool + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestDefaultConfig(t *testing.T) { + d := new(Ethtool) + var input interface{} + e := json.Unmarshal([]byte(`{"ethtool": { + }}`), &input) + if e == nil { + _, actual := d.ApplyRule(input) + + d := []interface{}{map[string]interface{}{ + "interface_include": []string{"*"}, + "fieldpass": []string{}, + }, + } + assert.Equal(t, d, actual, "Expected to be equal") + } +} + +func TestFullConfig(t *testing.T) { + d := new(Ethtool) + var input interface{} + e := json.Unmarshal([]byte(`{"ethtool": { + "interface_include": [ + "eth0" + ], + "interface_exclude": [ + "eth1" + ], + "metrics_include": [ + "bw_in_allowance_exceeded", + ], + }}`), &input) + if e == nil { + _, actual := d.ApplyRule(input) + + d := []interface{}{map[string]interface{}{ + "interface_include": []string{"eth0"}, + "interface_exclude": []string{"eth1"}, + "fieldpass": []string{"bw_in_allowance_exceeded"}, + }, + } + + assert.Equal(t, d, actual, "Expected to be equal") + } +} diff --git a/translator/translate/metrics/metrics_collect/ethtool/ruleInterfaceExclude.go b/translator/translate/metrics/metrics_collect/ethtool/ruleInterfaceExclude.go new file mode 100644 index 00000000000..dd66734deee --- /dev/null +++ b/translator/translate/metrics/metrics_collect/ethtool/ruleInterfaceExclude.go @@ -0,0 +1,23 @@ +package ethtool + +import ( + "github.com/aws/amazon-cloudwatch-agent/translator" +) + +type InterfaceExclude struct { +} + +const SectionKey_InterfaceExclude = "interface_exclude" + +func (obj *InterfaceExclude) ApplyRule(input interface{}) (returnKey string, returnVal interface{}) { + key, val := translator.DefaultCase(SectionKey_InterfaceExclude, "", input) + if val != "" { + return key, val + } + return +} + +func init() { + obj := new(InterfaceExclude) + RegisterRule(SectionKey_InterfaceExclude, obj) +} diff --git a/translator/translate/metrics/metrics_collect/ethtool/ruleInterfaceInclude.go b/translator/translate/metrics/metrics_collect/ethtool/ruleInterfaceInclude.go new file mode 100644 index 00000000000..bdd2f93eaec --- /dev/null +++ b/translator/translate/metrics/metrics_collect/ethtool/ruleInterfaceInclude.go @@ -0,0 +1,20 @@ +package ethtool + +import ( + "github.com/aws/amazon-cloudwatch-agent/translator" +) + +type InterfaceInclude struct { +} + +const SectionKey_InterfaceInclude = "interface_include" + +func (obj *InterfaceInclude) ApplyRule(input interface{}) (returnKey string, returnVal interface{}) { + returnKey, returnVal = translator.DefaultCase(SectionKey_InterfaceInclude, []string{"*"}, input) + return +} + +func init() { + obj := new(InterfaceInclude) + RegisterRule(SectionKey_InterfaceInclude, obj) +} diff --git a/translator/translate/metrics/metrics_collect/ethtool/ruleMetricsInclude.go b/translator/translate/metrics/metrics_collect/ethtool/ruleMetricsInclude.go new file mode 100644 index 00000000000..d47ce6be8a2 --- /dev/null +++ b/translator/translate/metrics/metrics_collect/ethtool/ruleMetricsInclude.go @@ -0,0 +1,21 @@ +package ethtool + +import ( + "github.com/aws/amazon-cloudwatch-agent/translator" +) + +type MetricsInclude struct { +} + +const SectionKey_MetricsInclude = "metrics_include" + +func (obj *MetricsInclude) ApplyRule(input interface{}) (returnKey string, returnVal interface{}) { + _, returnVal = translator.DefaultCase(SectionKey_MetricsInclude, []string{}, input) + returnKey = "fieldpass" + return +} + +func init() { + obj := new(MetricsInclude) + RegisterRule(SectionKey_MetricsInclude, obj) +}