Skip to content

Commit

Permalink
feat: add support to default alias in producers/consumers configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
sigilioso committed Jun 27, 2022
1 parent 1e89e11 commit bd0b261
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 5 deletions.
9 changes: 6 additions & 3 deletions kafka-config.yml.sample
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ integrations:
# In order to collect Java producer and consumer metrics the "producers" and "consumers" fields should be filled out.
# Both fields are JSON arrays with each entry being a separate JAVA producer or consumer, in it's respective field.
# Each entry should have the following fields:
# - name: This is the client.id of the producer/consumer as it appears in Kafka.
# - host: The IP or Hostname of the producer/consumser. If omitted, will use the value of the "default_jmx_host" field
# - name: This is the client.id of the producer/consumer as it appears in Kafka. If omitted, metrics from all clients in the JMX host:port will be reported.
# - host: The IP or Hostname of the producer/consumer. If omitted, will use the value of the "default_jmx_host" field
# - port: The port in which JMX is setup for on the producer/consumer. If omitted will, use the value of the "default_jmx_port" field
# - username: The username used to connect to JMX. If omitted, will use the value of the "default_jmx_user" field
# - password: The password used to connect to JMX. If omitted, will use the value of the "default_jmx_password" field
Expand All @@ -175,7 +175,10 @@ integrations:
CONSUMERS: '[{"name": "myConsumer", "host": "localhost", "port": 24, "username": "me", "password": "secret"}]'
# If several producers/consumers are on the same host an agent can be installed on that host and the
# "default_jmx_host" and "default_jmx_port" field can be set once and used for all producers/consumers that
# do not have the "host" or "port" field repsectively.
# do not have the "host" or "port" field respectively.
# When defaults are set it is also possible to use the string "default" to gather metrics from all producers /
# consumers in the "default_jmx_host:default_jmx_port". Example:
# PRODUCERS: default
# These fields can be removed if each producer/consumer has it's own "host" and/or "port" field filled out.
DEFAULT_JMX_HOST: "localhost"
DEFAULT_JMX_PORT: "9999"
Expand Down
91 changes: 91 additions & 0 deletions src/args/args_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
sdkArgs "github.com/newrelic/infra-integrations-sdk/args"
"github.com/newrelic/infra-integrations-sdk/integration"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestParseArgs(t *testing.T) {
Expand Down Expand Up @@ -217,3 +218,93 @@ func Test_unmarshalConsumerGroups_NoTopics(t *testing.T) {
t.Error("Expected error")
}
}

func TestUnMarshalJMXHosts(t *testing.T) {
arguments := &ArgumentList{
DefaultJMXUser: "user",
DefaultJMXPassword: "password",
DefaultJMXPort: 42,
DefaultJMXHost: "host",
}
cases := []struct {
Name string
Input string
Expected []*JMXHost
}{
{
Name: "Empty",
Input: `[]`,
Expected: []*JMXHost{},
},
{
Name: "Default with no alias",
Input: `[{}]`,
Expected: []*JMXHost{
{
User: arguments.DefaultJMXUser,
Password: arguments.DefaultJMXPassword,
Port: arguments.DefaultJMXPort,
Host: arguments.DefaultJMXHost,
},
},
},
{
Name: "Default with alias",
Input: `default`,
Expected: []*JMXHost{
{
User: arguments.DefaultJMXUser,
Password: arguments.DefaultJMXPassword,
Port: arguments.DefaultJMXPort,
Host: arguments.DefaultJMXHost,
},
},
},
{
Name: "Only name set",
Input: `[{"name": "client.id"}]`,
Expected: []*JMXHost{
{
Name: "client.id",
User: arguments.DefaultJMXUser,
Password: arguments.DefaultJMXPassword,
Port: arguments.DefaultJMXPort,
Host: arguments.DefaultJMXHost,
},
},
},
{
Name: "No name set",
Input: `[{"user": "my.user", "password": "my.pass", "port": 1088, "host": "localhost"}]`,
Expected: []*JMXHost{
{
User: "my.user",
Password: "my.pass",
Port: 1088,
Host: "localhost",
},
},
},
{
Name: "All values set",
Input: `[{"name": "my.name", "user": "my.user", "password": "my.pass", "port": 1088, "host": "localhost"}]`,
Expected: []*JMXHost{
{
Name: "my.name",
User: "my.user",
Password: "my.pass",
Port: 1088,
Host: "localhost",
},
},
},
}

for _, c := range cases {
t.Run(c.Name, func(t *testing.T) {
parsed, err := unmarshalJMXHosts([]byte(c.Input), arguments)
require.NoError(t, err)
require.Equal(t, c.Expected, parsed)
})
}
}
7 changes: 5 additions & 2 deletions src/args/parsed_args.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ var GlobalArgs *ParsedArguments
const (
defaultZookeeperPort = 2181
defaultJMXPort = 9999

jmxHostDefaultAlias = "default"
)

// ParsedArguments is an special version of the config arguments that has advanced parsing
Expand Down Expand Up @@ -313,10 +315,11 @@ func ParseArgs(a ArgumentList) (*ParsedArguments, error) {
// unmarshalJMXHosts parses the user-provided JSON map for a producer
// or consumers into a jmxHost structs and sets default values
func unmarshalJMXHosts(data []byte, a *ArgumentList) ([]*JMXHost, error) {

// Parse the producer or consumer
var v []*JMXHost
if err := json.Unmarshal([]byte(data), &v); err != nil {
if string(data) == jmxHostDefaultAlias {
v = []*JMXHost{{}}
} else if err := json.Unmarshal(data, &v); err != nil {
return nil, err
}

Expand Down

0 comments on commit bd0b261

Please sign in to comment.