Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[sqlserver] Close database connections #1997

Merged
merged 1 commit into from
Oct 26, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
[sqlserver] Open/close database connections
JohnLZeller committed Oct 26, 2015

Verified

This commit was signed with the committer’s verified signature.
addaleax Anna Henningsen
commit 9f9b60706efb85b40ddb72af0a2a9ba0ccc1e1c3
56 changes: 46 additions & 10 deletions checks.d/sqlserver.py
Original file line number Diff line number Diff line change
@@ -88,6 +88,8 @@ def __init__(self, name, init_config, agentConfig, instances=None):
self.log.exception("Skipping SQL Server instance")
continue

self.close_db_connections()

def _make_metric_list_to_collect(self, instance, custom_metrics):
"""
Store the list of metrics to collect by instance_key.
@@ -176,10 +178,13 @@ def _conn_key(self, instance):
host, username, password, database = self._get_access_info(instance)
return '%s:%s:%s:%s' % (host, username, password, database)

def _conn_string(self, instance):
def _conn_string(self, instance=None, conn_key=None):
''' Return a connection string to use with adodbapi
'''
host, username, password, database = self._get_access_info(instance)
if instance:
host, username, password, database = self._get_access_info(instance)
elif conn_key:
host, username, password, database = conn_key.split(":")
conn_str = 'Provider=SQLOLEDB;Data Source=%s;Initial Catalog=%s;' \
% (host, database)
if username:
@@ -208,13 +213,13 @@ def get_cursor(self, instance, cache_failure=False):

if conn_key not in self.connections:
try:
conn = adodbapi.connect(
self._conn_string(instance),
timeout=int(instance.get('command_timeout',
self.DEFAULT_COMMAND_TIMEOUT))
)
self.connections[conn_key] = conn
self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.OK, tags=service_check_tags)
timeout = int(instance.get('command_timeout',
self.DEFAULT_COMMAND_TIMEOUT))
conn = adodbapi.connect(self._conn_string(instance=instance),
timeout=timeout)
self.connections[conn_key] = {'conn': conn, 'timeout': timeout}
self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.OK,
tags=service_check_tags)
except Exception:
cx = "%s - %s" % (host, database)
message = "Unable to connect to SQL Server for instance %s." % cx
@@ -233,7 +238,7 @@ def get_cursor(self, instance, cache_failure=False):
self.failed_connections[conn_key] = cxn_failure_exp
raise cxn_failure_exp

conn = self.connections[conn_key]
conn = self.connections[conn_key]['conn']
cursor = conn.cursor()
return cursor

@@ -275,6 +280,7 @@ def check(self, instance):
"""
Fetch the metrics from the sys.dm_os_performance_counters table
"""
self.open_db_connections()
cursor = self.get_cursor(instance)

custom_tags = instance.get('tags', [])
@@ -288,6 +294,7 @@ def check(self, instance):
self.log.warning("Could not fetch metric %s: %s" % (metric.datadog_name, e))

self.close_cursor(cursor)
self.close_db_connections()

def close_cursor(self, cursor):
"""
@@ -300,6 +307,35 @@ def close_cursor(self, cursor):
except Exception as e:
self.log.warning("Could not close adodbapi cursor\n{0}".format(e))

def close_db_connections(self):
"""
We close the db connections explicitly b/c when we don't they keep
locks on the db. This presents as issues such as the SQL Server Agent
being unable to stop.
"""
for _, connection in self.connections.iteritems():
try:
connection['conn'].close()
except Exception as e:
self.log.warning("Could not close adodbapi db connection\n{0}".format(e))

def open_db_connections(self):
"""
We open the db connections explicitly, so we can ensure they are open
before we use them, and are closable, once we are finished. Open db
connections keep locks on the db, presenting issues such as the SQL
Server Agent being unable to stop.
"""
for conn_key, connection in self.connections.iteritems():
conn = connection['conn']
timeout = connection['timeout']
conn_dict = {'connection_string': self._conn_string(conn_key=conn_key),
'timeout': timeout}
try:
conn.connect(conn_dict)
except Exception as e:
self.log.warning("Could not connect to SQL Server\n{0}".format(e))


class SqlServerMetric(object):
'''General class for common methods, should never be instantiated directly