Skip to content

Commit 0474b67

Browse files
committed
fixed some issues, added sample collectd.conf
1 parent 4e0a58c commit 0474b67

File tree

4 files changed

+97
-30
lines changed

4 files changed

+97
-30
lines changed

memsql/collectd/__init__.py

+11-4
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ def memsql_config(config):
1414
password='',
1515
database='dashboard',
1616
typesdb={},
17-
previous_values={},
18-
pool=RandomAggregatorPool()
17+
previous_values={}
1918
)
2019

2120
for child in config.children:
@@ -35,6 +34,15 @@ def memsql_config(config):
3534
for v in child.values:
3635
memsql_parse_types_file(v, data)
3736

37+
# initialize the aggregator pool
38+
data['pool'] = RandomAggregatorPool(
39+
host=data['host'],
40+
port=data['port'],
41+
user=data['user'],
42+
password=data['password'],
43+
database=data['database']
44+
)
45+
3846
assert 'host' in data, 'MemSQL host is not defined'
3947
assert 'port' in data, 'MemSQL port is not defined'
4048

@@ -82,7 +90,7 @@ def memsql_parse_types_file(path, data):
8290

8391
def memsql_connect(data):
8492
""" Returns a live MemSQL connection. """
85-
return data['pool'].connect(data['host'], data['port'], data['user'], data['password'], data['database'])
93+
return data['pool'].connect()
8694

8795
def memsql_write(collectd_sample, data=None):
8896
""" Write handler for collectd.
@@ -167,4 +175,3 @@ def persist_value(new_value, data_source_name, data_source_type, collectd_sample
167175
(created, host, plugin, type, instance, category, value_name, value)
168176
VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
169177
""", *query_params)
170-

memsql/common/random_aggregator_pool.py

+47-21
Original file line numberDiff line numberDiff line change
@@ -13,55 +13,81 @@ class RandomAggregatorPool:
1313
aggregators by periodically calling `SHOW AGGREGATORS`.
1414
"""
1515

16-
def __init__(self):
16+
def __init__(self, host, port, user='root', password='', database='information_schema'):
17+
""" Initialize the RandomAggregatorPool with connection
18+
information for an aggregator in a MemSQL Distributed System.
19+
20+
All aggregator connections will share the same user/password/database.
21+
"""
1722
self.logger = logging.getLogger('memsql.random_aggregator_pool')
1823
self._pool = ConnectionPool()
19-
self._aggregators = []
20-
self._aggregator = None
2124
self._refresh_aggregator_list = memoize(30)(self._update_aggregator_list)
2225
self._lock = threading.Lock()
2326

24-
def connect(self, host, port, user, password, database):
25-
conn = self._connect(host, port, user, password, database)
27+
self._primary_aggregator = (host, port)
28+
self._user = user
29+
self._password = password
30+
self._database = database
31+
self._aggregators = []
32+
self._aggregator = None
33+
34+
def connect(self):
35+
""" Returns an aggregator connection, and periodically updates the aggregator list. """
36+
conn = self._connect()
2637
self._refresh_aggregator_list(conn)
2738
return conn
2839

29-
def _connect(self, host, port, user, password, database):
40+
def _pool_connect(self, agg):
41+
""" `agg` should be (host, port)
42+
Returns a live connection from the connection pool
43+
"""
44+
return self._pool.connect(agg[0], agg[1], self._user, self._password, self._database)
45+
46+
def _connect(self):
47+
""" Returns an aggregator connection. """
3048
if self._aggregator:
3149
try:
32-
return self._pool.connect(self._aggregator[0], self._aggregator[1], user, password, database)
50+
return self._pool_connect(self._aggregator)
3351
except PoolConnectionException:
3452
self._aggregator = None
35-
pass
3653

37-
if not self._aggregators:
38-
with self._pool.connect(host, port, user, password, database) as conn:
54+
if not len(self._aggregators):
55+
with self._pool_connect(self._primary_aggregator) as conn:
3956
self._update_aggregator_list(conn)
4057
conn.expire()
4158

42-
assert self._aggregators, "Failed to retrieve a list of aggregators"
59+
with self._lock:
60+
random.shuffle(self._aggregators)
4361

44-
# we will run a few attempts of connecting to an
45-
# aggregator
4662
last_exception = None
47-
for i in range(10):
48-
with self._lock:
49-
self._aggregator = random.choice(self._aggregators)
50-
51-
self.logger.debug('Connecting to %s:%s' % (self._aggregator[0], self._aggregator[1]))
63+
for aggregator in self._aggregators:
64+
self.logger.debug('Attempting connection with %s:%s' % (aggregator[0], aggregator[1]))
5265

5366
try:
54-
return self._pool.connect(self._aggregator[0], self._aggregator[1], user, password, database)
67+
conn = self._pool_connect(aggregator)
68+
# connection successful!
69+
self._aggregator = aggregator
70+
return conn
5571
except PoolConnectionException as e:
72+
# connection error
5673
last_exception = e
5774
else:
5875
with self._lock:
76+
# bad news bears... try again later
5977
self._aggregator = None
6078
self._aggregators = []
6179

6280
raise last_exception
6381

6482
def _update_aggregator_list(self, conn):
83+
rows = conn.query('SHOW AGGREGATORS')
6584
with self._lock:
66-
self._aggregators = [(r['Host'], r['Port']) for r in conn.query('SHOW AGGREGATORS')]
67-
self.logger.debug('Aggregator list is updated to %s. Current aggregator is %s.' % (self._aggregators, self._aggregator))
85+
self._aggregators = []
86+
for row in rows:
87+
if row.Host == '127.0.0.1':
88+
# this is the aggregator we are connecting to
89+
row['Host'] = conn.connection_info()[0]
90+
self._aggregators.append((row.Host, row.Port))
91+
92+
assert self._aggregators, "Failed to retrieve a list of aggregators"
93+
self.logger.debug('Aggregator list is updated to %s. Current aggregator is %s.' % (self._aggregators, self._aggregator))

sample_collectd.conf

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
FQDNLookup true
2+
Interval 1
3+
4+
LoadPlugin logfile
5+
LoadPlugin syslog
6+
7+
<Plugin logfile>
8+
LogLevel "info"
9+
File STDOUT
10+
Timestamp true
11+
PrintSeverity false
12+
</Plugin>
13+
14+
<Plugin syslog>
15+
LogLevel info
16+
</Plugin>
17+
18+
<LoadPlugin python>
19+
Globals true
20+
</LoadPlugin>
21+
22+
<Plugin python>
23+
Import "memsql.collectd"
24+
<Module "memsql.collectd">
25+
TypesDB "/usr/share/collectd/types.db"
26+
Host "MASTER AGGREGATOR HOSTNAME/IP_ADDRESS"
27+
Port "3306"
28+
</Module>
29+
</Plugin>
30+
31+
LoadPlugin cpu
32+
LoadPlugin memory
33+
LoadPlugin processes

setup.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
#!/usr/bin/env python
22

3-
from distribute_setup import use_setuptools
4-
use_setuptools()
5-
6-
from setuptools import setup, find_packages
3+
from setuptools import setup
74
from setuptools.command.test import test as TestCommand
85

96
# get version
@@ -32,7 +29,11 @@ def run_tests(self):
3229
description='Useful utilities and plugins for MemSQL integration.',
3330
long_description=open('README.rst').read(),
3431

35-
packages=find_packages(),
32+
packages=[
33+
'memsql',
34+
'memsql.collectd',
35+
'memsql.common',
36+
],
3637
install_requires=['MySQL-python>=1.2.4', 'wraptor'],
3738
tests_require=['pytest', 'mock'],
3839
cmdclass={ 'test': PyTest },

0 commit comments

Comments
 (0)