Skip to content

Commit

Permalink
Add authentication and timeout options (#3214)
Browse files Browse the repository at this point in the history
  • Loading branch information
ofek authored Feb 27, 2019
1 parent f5e64b3 commit 295b5b2
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 9 deletions.
5 changes: 2 additions & 3 deletions aerospike/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ Get metrics from Aerospike Database in real time to:
* Visualize and monitor Aerospike states
* Be notified about Aerospike failovers and events.

Note: Authentication and TLS are not supported.

## Setup

### Installation
Expand All @@ -34,7 +32,8 @@ See [metadata.csv][5] for a list of metrics provided by this integration.

### Service Checks

Aerospike does not include any service checks.
- `aerospike.can_connect`
- `aerospike.cluster_up`

### Events

Expand Down
25 changes: 21 additions & 4 deletions aerospike/datadog_checks/aerospike/aerospike.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,20 @@ class AerospikeCheck(AgentCheck):
def __init__(self, name, init_config, instances):
super(AerospikeCheck, self).__init__(name, init_config, instances)

# https://www.aerospike.com/apidocs/python/aerospike.html#aerospike.client
host = self.instance.get('host', 'localhost')
port = int(self.instance.get('port', 3000))
tls_name = self.instance.get('tls_name')
self._host = (host, port, tls_name) if tls_name else (host, port)

# https://www.aerospike.com/apidocs/python/client.html#aerospike.Client.connect
self._username = self.instance.get('username')
self._password = self.instance.get('password')

# In milliseconds, see https://www.aerospike.com/apidocs/python/client.html#aerospike-info-policies
timeout = int(self.instance.get('timeout', 10)) * 1000
self._info_policies = {'timeout': timeout}

self._host = (host, port)
self._metrics = set(self.instance.get('metrics', []))
self._namespace_metrics = set(self.instance.get('namespace_metrics', []))
self._required_namespaces = self.instance.get('namespaces')
Expand All @@ -85,33 +95,39 @@ def check(self, instance):

self._client = client

# https://www.aerospike.com/docs/reference/info/#statistics
self.collect_info('statistics', CLUSTER_METRIC_TYPE, required_keys=self._metrics, tags=self._tags)

# https://www.aerospike.com/docs/reference/info/#namespaces
namespaces = self.get_namespaces()

for ns in namespaces:
namespace_tags = ['namespace:{}'.format(ns)]
namespace_tags.extend(self._tags)

# https://www.aerospike.com/docs/reference/info/#namespace
self.collect_info(
'namespace/{}'.format(ns),
NAMESPACE_METRIC_TYPE,
required_keys=self._namespace_metrics,
tags=namespace_tags
)

# https://www.aerospike.com/docs/reference/info/#sindex
sindex = self.get_info('sindex/{}'.format(ns))
for idx in parse_namespace(sindex[:-1], ns, 'indexname'):
sindex_tags = ['sindex:{}'.format(idx)]
sindex_tags.extend(namespace_tags)
self.collect_info('sindex/{}/{}'.format(ns, idx), SINDEX_METRIC_TYPE, tags=sindex_tags)

# https://www.aerospike.com/docs/reference/info/#sets
sets = self.get_info('sets/{}'.format(ns))
for s in parse_namespace(sets, ns, 'set'):
set_tags = ['set:{}'.format(s)]
set_tags.extend(namespace_tags)
self.collect_info('sets/{}/{}'.format(ns, s), SET_METRIC_TYPE, separator=':', tags=set_tags)

# https://www.aerospike.com/docs/reference/info/#throughput
self.collect_throughput(namespaces)

self.service_check(SERVICE_CHECK_UP, self.OK, tags=self._tags)
Expand Down Expand Up @@ -149,7 +165,7 @@ def get_namespaces(self):

def get_client(self):
try:
client = aerospike.client({'hosts': [self._host]}).connect()
client = aerospike.client({'hosts': [self._host]}).connect(self._username, self._password)
except Exception as e:
self.log.error('Unable to connect to database: {}'.format(e))
self.service_check(SERVICE_CHECK_CONNECT, self.CRITICAL, tags=self._tags)
Expand All @@ -158,8 +174,9 @@ def get_client(self):
return client

def get_info(self, command, separator=';'):
# command\tKEY=VALUE;KEY=VALUE;...
data = self._client.info_node(command, self._host)
# See https://www.aerospike.com/docs/reference/info/
# Example output: command\tKEY=VALUE;KEY=VALUE;...
data = self._client.info_node(command, self._host, self._info_policies)

# Get rid of command and whitespace
data = data[len(command):].strip()
Expand Down
25 changes: 23 additions & 2 deletions aerospike/datadog_checks/aerospike/data/conf.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,29 @@ instances:
#
port: 3000

## @param tags - list of key:value elements - optional
## List of tags to attach to every metric, event and service check emitted by this integration.
## @param username - string - optional
## The database user to authenticate as.
#
# username: <USERNAME>

## @param password - string - optional
## The password of `username`.
#
# password: <PASSWORD>

## @param tls_name - string - optional
## This must match the tls-name specified in the node’s server
## configuration file and match the server’s CA certificate.
#
# tls_name: <TLS_NAME>

## @param timeout - integer - optional - default: 10
## The read timeout in seconds.
#
# timeout: 10

## @param tags - list of key:value strings - optional
## List of tags to attach to every metric and service check emitted by this integration.
##
## Learn more about tagging: https://docs.datadoghq.com/tagging/
#
Expand Down

0 comments on commit 295b5b2

Please sign in to comment.