-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[cassandra_check] Add cassandra_check
- Loading branch information
Showing
11 changed files
with
272 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# CHANGELOG - Cassandra_check | ||
|
||
0.1.0/ Unreleased | ||
================== | ||
|
||
### Changes | ||
|
||
* [FEATURE] adds cassandra_check integration. |
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,29 @@ | ||
# Cassandra Check | ||
|
||
## Overview | ||
|
||
Get metrics from cassandra databases that are not available through the [jmx integration](https://github.com/DataDog/integrations-core/tree/master/cassandra) | ||
|
||
## Installation | ||
|
||
Install the `dd-check-cassandra_check` package manually or with your favorite configuration manager | ||
|
||
## Configuration | ||
|
||
Edit the `cassandra_check.yaml` file to point to your server and port and set the keyspaces to monitor | ||
|
||
## Validation | ||
|
||
When you run `datadog-agent info` you should see something like the following: | ||
|
||
Checks | ||
====== | ||
|
||
cassandra_check | ||
----------- | ||
- instance #0 [OK] | ||
- Collected 39 metrics, 0 events & 7 service checks | ||
|
||
## Compatibility | ||
|
||
The cassandra_check check is compatible with all major platforms |
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,58 @@ | ||
# (C) Datadog, Inc. 2010-2016 | ||
# All rights reserved | ||
# Licensed under Simplified BSD License (see LICENSE) | ||
|
||
# 3rd party | ||
from cassandra.cluster import Cluster, NoHostAvailable | ||
from cassandra.auth import PlainTextAuthProvider | ||
|
||
# project | ||
from checks import AgentCheck | ||
|
||
EVENT_TYPE = SOURCE_TYPE_NAME = 'cassandra_check' | ||
DEFAULT_NODE_IP = 'localhost' | ||
DEFAULT_NODE_PORT = 9042 | ||
|
||
|
||
class CassandraCheck(AgentCheck): | ||
|
||
def __init__(self, name, init_config, agentConfig, instances=None): | ||
AgentCheck.__init__(self, name, init_config, agentConfig, instances) | ||
|
||
def check(self, instance): | ||
# Get the node IP address to connect Cassandra | ||
node_ip = instance.get("node_ip", DEFAULT_NODE_IP) | ||
node_port = instance.get("node_port", DEFAULT_NODE_PORT) | ||
keyspaces = instance.get("keyspaces", []) | ||
tags = instance.get("tags", []) | ||
connect_timeout = instance.get("connect_timeout", 5) | ||
|
||
username = instance.get("username", "") | ||
password = instance.get("password", "") | ||
auth_provider = PlainTextAuthProvider(username, password) | ||
|
||
# Try to connect to the node | ||
cluster = Cluster([node_ip], port=node_port, auth_provider=auth_provider, connect_timeout=connect_timeout) | ||
try: | ||
cluster.connect(wait_for_all_pools=True) | ||
if keyspaces: | ||
for keyspace in keyspaces: | ||
token_map = cluster.metadata.token_map | ||
down_replicas = 0 | ||
for token in token_map.ring: | ||
replicas = token_map.get_replicas(keyspace, token) | ||
down_replicas = max(down_replicas, len([r for r in replicas if not r.is_up])) | ||
|
||
self.gauge("cassandra.replication_failures", down_replicas, | ||
tags=["keyspace:%s" % keyspace, "cluster:%s" % cluster.metadata.cluster_name] + tags) | ||
|
||
|
||
except NoHostAvailable as e: | ||
self.log.error('Could not connect to node %s:%s : %s' % (node_ip, node_port, e)) | ||
node_status = AgentCheck.CRITICAL | ||
else: | ||
node_status = AgentCheck.OK | ||
finally: | ||
cluster.shutdown() | ||
|
||
self.service_check('cassandra.can_connect', node_status, tags=tags) |
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,99 @@ | ||
require 'ci/common' | ||
|
||
def cassandra_check_version | ||
ENV['FLAVOR_VERSION'] || '2.1.14' # '2.0.17' | ||
end | ||
|
||
def cassandra_check_rootdir | ||
"#{ENV['INTEGRATIONS_DIR']}/cassandra_check_#{cassandra_check_version}" | ||
end | ||
|
||
container_name = 'dd-test-cassandra' | ||
container_name2 = 'dd-test-cassandra2' | ||
|
||
namespace :ci do | ||
namespace :cassandra_check do |flavor| | ||
task before_install: ['ci:common:before_install'] do | ||
sh %(docker kill #{container_name} 2>/dev/null || true) | ||
sh %(docker rm #{container_name} 2>/dev/null || true) | ||
sh %(docker kill #{container_name2} 2>/dev/null || true) | ||
sh %(docker rm #{container_name2} 2>/dev/null || true) | ||
end | ||
|
||
task :install do | ||
Rake::Task['ci:common:install'].invoke('cassandra_check') | ||
sh %(docker create --expose 9042 --expose 7000 --expose 7001 --expose 9160 \ | ||
-p 9042:9042 -p 7000:7000 -p 7001:7001 -p 9160:9160 --name #{container_name} cassandra:#{cassandra_check_version}) | ||
sh %(docker start #{container_name}) | ||
sh %(docker create --name #{container_name2} \ | ||
-e CASSANDRA_SEEDS="$(docker inspect --format='{{ .NetworkSettings.IPAddress }}' #{container_name})" cassandra:#{cassandra_check_version}) | ||
sh %(docker start #{container_name2}) | ||
end | ||
|
||
task before_script: ['ci:common:before_script'] do | ||
# Wait.for container_port | ||
count = 0 | ||
logs = `docker logs #{container_name} 2>&1` | ||
logs2 = `docker logs #{container_name2} 2>&1` | ||
puts 'Waiting for Cassandra to come up' | ||
until count == 20 || ((logs.include?('Listening for thrift clients') || logs.include?('Starting listening for CQL clients')) && \ | ||
(logs2.include?('Listening for thrift clients') || logs2.include?('Starting listening for CQL clients'))) | ||
sleep_for 4 | ||
logs = `docker logs #{container_name} 2>&1` | ||
logs2 = `docker logs #{container_name2} 2>&1` | ||
count += 1 | ||
end | ||
if (logs.include?('Listening for thrift clients') || logs.include?('Starting listening for CQL clients')) && \ | ||
(logs2.include?('Listening for thrift clients') || logs2.include?('Starting listening for CQL clients')) | ||
puts 'Cassandra is up!' | ||
else | ||
puts 'Logs of container 1' | ||
sh %(docker logs #{container_name} 2>&1) | ||
puts 'Logs of container 2' | ||
sh %(docker logs #{container_name2} 2>&1) | ||
raise | ||
end | ||
end | ||
|
||
task script: ['ci:common:script'] do | ||
this_provides = [ | ||
'cassandra_check' | ||
] | ||
Rake::Task['ci:common:run_tests'].invoke(this_provides) | ||
end | ||
|
||
task before_cache: ['ci:common:before_cache'] | ||
|
||
task cleanup: ['ci:common:cleanup'] do | ||
sh %(docker kill #{container_name} 2>/dev/null || true) | ||
sh %(docker rm #{container_name} 2>/dev/null || true) | ||
sh %(docker kill #{container_name2} 2>/dev/null || true) | ||
sh %(docker rm #{container_name2} 2>/dev/null || true) | ||
end | ||
|
||
task :execute do | ||
exception = nil | ||
begin | ||
%w(before_install install before_script).each do |u| | ||
Rake::Task["#{flavor.scope.path}:#{u}"].invoke | ||
end | ||
if !ENV['SKIP_TEST'] | ||
Rake::Task["#{flavor.scope.path}:script"].invoke | ||
else | ||
puts 'Skipping tests'.yellow | ||
end | ||
Rake::Task["#{flavor.scope.path}:before_cache"].invoke | ||
rescue => e | ||
exception = e | ||
puts "Failed task: #{e.class} #{e.message}".red | ||
end | ||
if ENV['SKIP_CLEANUP'] | ||
puts 'Skipping cleanup, disposable environments are great'.yellow | ||
else | ||
puts 'Cleaning up' | ||
Rake::Task["#{flavor.scope.path}:cleanup"].invoke | ||
end | ||
raise exception if exception | ||
end | ||
end | ||
end |
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,15 @@ | ||
init_config: | ||
|
||
instances: | ||
# Configuration options: | ||
# keyspaces: a list of keyspaces to monitor | ||
# node_ip: the IP of the cassandra node to connect to. The rest of the nodes in the cluster will be auto discovered by the cassandra driver | ||
# For more information, see https://datastax.github.io/python-driver/api/index.html | ||
# Default to localhost. | ||
# node_port: the port cassandra is listening for connections. | ||
# Default to 9042 | ||
# username/password: a set of credentials to connect to the cassandra cluster. | ||
# tags: optional, a list of tags to be sent with the metrics | ||
# connect_timeout: timeout, in seconds, for creating new connections. Default to 5. | ||
|
||
- keyspaces: ["foo"] |
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,12 @@ | ||
{ | ||
"maintainer": "help@datadoghq.com", | ||
"manifest_version": "0.1.0", | ||
"max_agent_version": "6.0.0", | ||
"min_agent_version": "5.6.3", | ||
"name": "cassandra_check", | ||
"short_description": "cassandra_check description.", | ||
"guid": "00e4a8bd-8ec2-4bb4-b725-6aaa91618d13", | ||
"support": "contrib", | ||
"supported_os": ["linux","mac_os","windows"], | ||
"version": "0.1.0" | ||
} |
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,2 @@ | ||
metric_name,metric_type,interval,unit_name,per_unit_name,description,orientation,integration,short_name | ||
cassandra.replication_failures,gauge,,,,Number of replica nodes down per keyspace,-1,cassandra_check,replication failures |
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,2 @@ | ||
# integration pip requirements | ||
cassandra-driver==3.10.0 |
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,43 @@ | ||
# (C) Datadog, Inc. 2010-2016 | ||
# All rights reserved | ||
# Licensed under Simplified BSD License (see LICENSE) | ||
|
||
# stdlib | ||
from nose.plugins.attrib import attr | ||
|
||
# 3p | ||
from cassandra.cluster import Cluster | ||
|
||
# project | ||
from tests.checks.common import AgentCheckTest | ||
|
||
|
||
@attr(requires='cassandra_check') | ||
class TestCassandraCheck(AgentCheckTest): | ||
"""Basic Test for cassandra_check integration.""" | ||
CHECK_NAME = 'cassandra_check' | ||
|
||
def test_check(self): | ||
|
||
# Create a keyspace with replication factor 2 | ||
cluster = Cluster(connect_timeout=1) | ||
session = cluster.connect() | ||
session.execute("CREATE KEYSPACE IF NOT EXISTS test WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 2}") | ||
cluster.shutdown() | ||
|
||
config = { | ||
'instances': [ | ||
{'host': '127.0.0.1', | ||
'port': 9042, | ||
'keyspaces': ['test'], | ||
'tags': ['foo','bar'], | ||
'connect_timeout': 1} | ||
] | ||
} | ||
|
||
self.run_check(config) | ||
# We should have the value 1 since the driver won't be able to connect to one of the container (port not exposed) | ||
self.assertMetric('cassandra.replication_failures', value=1, tags=['keyspace:test', 'cluster:Test Cluster', 'foo', 'bar']) | ||
self.assertServiceCheckOK('cassandra.can_connect', tags=['foo', 'bar']) | ||
# Raises when COVERAGE=true and coverage < 100% | ||
self.coverage_report() |
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