Skip to content

Commit 319a81e

Browse files
author
Matias Melograno
committed
solved issue on unknown instance-id and machine-ip
1 parent 37d9a56 commit 319a81e

10 files changed

Lines changed: 165 additions & 63 deletions

CHANGES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
6.3.0 ()
2+
- Stored Impressions in Queue.
3+
- Fixed bug related to Machine Name and Machine IP.
14
6.2.0 (Oct 5, 2018)
25
- Added get_treatments method.
36
6.1.0 (Sep 25, 2018)

splitio/brokers.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
AllKeysSplit, CacheBasedSplitFetcher
2727
from splitio.segments import ApiSegmentChangeFetcher, \
2828
SelfRefreshingSegmentFetcher, JSONFileSegmentFetcher
29-
from splitio.config import DEFAULT_CONFIG, MAX_INTERVAL, parse_config_file
29+
from splitio.config import DEFAULT_CONFIG, MAX_INTERVAL, parse_config_file, \
30+
set_machine_ip, set_machine_name
3031
from splitio.uwsgi import UWSGISplitCache, UWSGIImpressionsCache, \
3132
UWSGIMetricsCache, UWSGIEventsCache, get_uwsgi
3233
from splitio.tasks import EventsSyncTask
@@ -649,6 +650,9 @@ def _init_config(api_key, **kwargs):
649650
file_config.update(config)
650651
config = file_config
651652

653+
set_machine_ip(config.get('splitSdkMachineIp'))
654+
set_machine_name(config.get('splitSdkMachineName'))
655+
652656
return api_key, config, sdk_api_base_url, events_api_base_url
653657

654658

splitio/config.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import json
77

88
from .version import __version__
9+
from splitio.utils import get_hostname, get_ip
910

1011
logger = logging.getLogger(__name__)
1112

@@ -51,13 +52,34 @@
5152
'redisSslCertReqs': None,
5253
'redisSslCaCerts': None,
5354
'redisMaxConnections': None,
54-
'eventsPushRate' : 60,
55+
'eventsPushRate': 60,
5556
'eventsQueueSize': 500,
5657
}
5758

5859
MAX_INTERVAL = 180
5960

6061

62+
GLOBAL_KEY_PARAMETERS = {
63+
'sdk-language-version': SDK_VERSION,
64+
'instance-id': 'unknown',
65+
'ip-address': 'unknown',
66+
}
67+
68+
69+
def set_machine_ip(machine_ip):
70+
if machine_ip:
71+
GLOBAL_KEY_PARAMETERS['ip-address'] = machine_ip
72+
else:
73+
GLOBAL_KEY_PARAMETERS['ip-address'] = get_ip()
74+
75+
76+
def set_machine_name(machine_name):
77+
if machine_name:
78+
GLOBAL_KEY_PARAMETERS['instance-id'] = machine_name
79+
else:
80+
GLOBAL_KEY_PARAMETERS['instance-id'] = get_hostname()
81+
82+
6183
def parse_config_file(filename):
6284
"""Reads a Splitio JSON config file, like the following:
6385
@@ -92,7 +114,11 @@ def parse_config_file(filename):
92114
with open(filename) as fp:
93115
json_config = json.load(fp)
94116
config.update(json_config)
95-
except:
117+
if 'splitSdkMachineName' in config:
118+
set_machine_name(config['splitSdkMachineName'])
119+
if 'splitSdkMachineIp' in config:
120+
set_machine_ip(config['splitSdkMachineIp'])
121+
except Exception:
96122
logger.exception('There was a problem reading the config file: %s', filename)
97123
return DEFAULT_CONFIG.copy()
98124

splitio/impressions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from concurrent.futures import ThreadPoolExecutor
1111
from copy import deepcopy
1212
from threading import RLock, Timer
13-
from splitio.config import SDK_VERSION, DEFAULT_CONFIG
13+
from splitio.config import SDK_VERSION, GLOBAL_KEY_PARAMETERS
1414

1515

1616
Impression = namedtuple(
@@ -501,8 +501,8 @@ def log_impression(self, impression, attributes=None):
501501
data = {}
502502
data['impression'] = impression
503503
data['attributes'] = attributes
504-
data['instance-id'] = DEFAULT_CONFIG['splitSdkMachineIp']
505504
data['sdk-language-version'] = SDK_VERSION
505+
data['instance-id'] = GLOBAL_KEY_PARAMETERS['instance-id']
506506
try:
507507
self.impression_listener.log_impression(data)
508508
except Exception:

splitio/redis_support.py

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def missing_redis_dependencies(*args, **kwargs):
1919

2020
from six import iteritems
2121

22-
from splitio.config import import_from_string
22+
from splitio.config import import_from_string, GLOBAL_KEY_PARAMETERS
2323
from splitio.cache import SegmentCache, SplitCache, ImpressionsCache, \
2424
MetricsCache
2525
from splitio.matchers import UserDefinedSegmentMatcher
@@ -29,14 +29,9 @@ def missing_redis_dependencies(*args, **kwargs):
2929
from splitio.impressions import Impression
3030
from splitio.utils import bytes_to_string
3131
from splitio.prefix_decorator import PrefixDecorator
32-
from splitio.version import __version__ as _SDK_VERSION
3332
# Template for Split.io related Cache keys
3433
_SPLITIO_CACHE_KEY_TEMPLATE = 'SPLITIO.{suffix}'
35-
_GLOBAL_KEY_PARAMETERS = {
36-
'sdk-language-version': 'python-{version}'.format(version=_SDK_VERSION),
37-
'instance-id': 'unknown',
38-
'ip-address': 'unknown',
39-
}
34+
4035
IMPRESSIONS_QUEUE_KEY = 'SPLITIO.impressions'
4136
IMPRESSION_KEY_DEFAULT_TTL = 3600
4237

@@ -273,9 +268,9 @@ def log_event(self, event):
273268
to_store = {
274269
'e': dict(event._asdict()),
275270
'm': {
276-
's': _GLOBAL_KEY_PARAMETERS['sdk-language-version'],
277-
'n': _GLOBAL_KEY_PARAMETERS['instance-id'],
278-
'i': _GLOBAL_KEY_PARAMETERS['ip-address'],
271+
's': GLOBAL_KEY_PARAMETERS['sdk-language-version'],
272+
'n': GLOBAL_KEY_PARAMETERS['instance-id'],
273+
'i': GLOBAL_KEY_PARAMETERS['ip-address'],
279274
}
280275
}
281276
try:
@@ -296,7 +291,7 @@ def _get_impressions_key(cls, feature_name):
296291
'''
297292
'''
298293
return cls._KEY_TEMPLATE.format(
299-
**dict(_GLOBAL_KEY_PARAMETERS, feature=feature_name)
294+
**dict(GLOBAL_KEY_PARAMETERS, feature=feature_name)
300295
)
301296

302297
@classmethod
@@ -314,7 +309,7 @@ def __init__(self, redis):
314309
self._redis = redis
315310
self._logger = logging.getLogger(self.__class__.__name__)
316311

317-
key_params = _GLOBAL_KEY_PARAMETERS.copy()
312+
key_params = GLOBAL_KEY_PARAMETERS.copy()
318313
key_params['suffix'] = '{feature_name}'
319314

320315
def _build_impressions_dict(self, impressions):
@@ -397,9 +392,9 @@ def add_impressions(self, impressions):
397392
if isinstance(impression, Impression):
398393
to_store = {
399394
'm': { # METADATA PORTION
400-
's': _GLOBAL_KEY_PARAMETERS['sdk-language-version'],
401-
'n': _GLOBAL_KEY_PARAMETERS['instance-id'],
402-
'i': _GLOBAL_KEY_PARAMETERS['ip-address'],
395+
's': GLOBAL_KEY_PARAMETERS['sdk-language-version'],
396+
'n': GLOBAL_KEY_PARAMETERS['instance-id'],
397+
'i': GLOBAL_KEY_PARAMETERS['ip-address'],
403398
},
404399
'i': { # IMPRESSION PORTION
405400
'k': impression.matching_key,
@@ -503,7 +498,7 @@ def _get_latency_bucket_key(cls, metric_name, bucket_number):
503498
Returns the latency bucket
504499
'''
505500
return cls._KEY_LATENCY.format(**dict(
506-
_GLOBAL_KEY_PARAMETERS,
501+
GLOBAL_KEY_PARAMETERS,
507502
metric_name=metric_name,
508503
bucket_number=bucket_number
509504
))
@@ -514,7 +509,7 @@ def _get_count_key(cls, counter):
514509
Returns the count key
515510
'''
516511
return cls._KEY_COUNT.format(**dict(
517-
_GLOBAL_KEY_PARAMETERS,
512+
GLOBAL_KEY_PARAMETERS,
518513
counter=counter
519514
))
520515

@@ -524,7 +519,7 @@ def _get_gauge_key(cls, gauge):
524519
Returns the gauge key
525520
'''
526521
return cls._KEY_GAUGE.format(**dict(
527-
_GLOBAL_KEY_PARAMETERS,
522+
GLOBAL_KEY_PARAMETERS,
528523
gauge=gauge
529524
))
530525

@@ -534,21 +529,21 @@ def _get_latency_field_re(cls):
534529
.replace('.', '\.')
535530
.replace('{metric_name}', '(?P<operation>.+)')
536531
.replace('{bucket_number}', '(?P<bucket_index>.+)'))
537-
).format(**_GLOBAL_KEY_PARAMETERS)
532+
).format(**GLOBAL_KEY_PARAMETERS)
538533

539534
@classmethod
540535
def _get_count_field_re(cls):
541536
return ("^%s$" % (cls._KEY_COUNT
542537
.replace('.', '\.')
543538
.replace('{counter}', '(?P<counter>.+)'))
544-
).format(**_GLOBAL_KEY_PARAMETERS)
539+
).format(**GLOBAL_KEY_PARAMETERS)
545540

546541
@classmethod
547542
def _get_gauge_field_re(cls):
548543
return ("^%s$" % (cls._KEY_GAUGE
549544
.replace('.', '\.')
550545
.replace('{gauge}', '(?P<gauge>.+)'))
551-
).format(**_GLOBAL_KEY_PARAMETERS)
546+
).format(**GLOBAL_KEY_PARAMETERS)
552547

553548
def __init__(self, redis):
554549
'''
@@ -805,25 +800,13 @@ def contains(self, key):
805800
return self._split.segment_cache.is_in_segment(self.name, key)
806801

807802

808-
def setup_instance_id(instance_id):
809-
'''
810-
Setup the correct parameters once the redis-client has been instantiated
811-
with a configuration from the client
812-
'''
813-
if instance_id:
814-
_GLOBAL_KEY_PARAMETERS['instance-id'] = instance_id
815-
else:
816-
_GLOBAL_KEY_PARAMETERS['instance-id'] = 'unknown'
817-
818-
819803
def get_redis(config):
820804
'''
821805
Build a redis client based on the configuration.
822806
:param config: Dictionary with the contents of the config file.
823807
:type config: dict
824808
:return: A redis client
825809
'''
826-
setup_instance_id(config.get('instance-id'))
827810
if 'redisFactory' in config:
828811
redis_factory = import_from_string(
829812
config['redisFactory'], 'redisFactory'

splitio/tests/test_impression_listener.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# Python 2
55
import mock
66

7-
from splitio.config import SDK_VERSION, DEFAULT_CONFIG
7+
from splitio.config import SDK_VERSION, GLOBAL_KEY_PARAMETERS
88

99
from os.path import dirname, join
1010
from json import load
@@ -99,7 +99,7 @@ def test_send_data_to_client(self):
9999

100100
self.assertIn('instance-id', impression_client._data_logged)
101101
self.assertEqual(impression_client._data_logged['instance-id'],
102-
DEFAULT_CONFIG['splitSdkMachineIp'])
102+
GLOBAL_KEY_PARAMETERS['instance-id'])
103103

104104
self.assertIn('sdk-language-version', impression_client._data_logged)
105105
self.assertEqual(impression_client._data_logged['sdk-language-version'], SDK_VERSION)

splitio/tests/test_impressions.py

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from splitio.redis_support import (get_redis, IMPRESSIONS_QUEUE_KEY,
2222
RedisImpressionsCache, IMPRESSION_KEY_DEFAULT_TTL)
2323
from splitio import get_factory
24+
from splitio.config import GLOBAL_KEY_PARAMETERS
2425

2526

2627
class BuildImpressionsDataTests(TestCase):
@@ -38,7 +39,7 @@ def setUp(self):
3839
feature_name=self.some_other_feature,
3940
treatment=mock.MagicMock(),
4041
label=mock.MagicMock(),
41-
change_number=mock.MagicMock(),
42+
change_number=mock.MagicMock(),
4243
bucketing_key=mock.MagicMock(),
4344
time=mock.MagicMock())
4445
self.some_impression_2 = Impression(matching_key=mock.MagicMock(),
@@ -210,7 +211,7 @@ def setUp(self):
210211

211212
self.some_label = mock.MagicMock()
212213
self.some_change_number = mock.MagicMock()
213-
self.some_impression = Impression(matching_key=self.some_key,
214+
self.some_impression = Impression(matching_key=self.some_key,
214215
feature_name=self.some_feature_name,
215216
treatment=self.some_treatment,
216217
label=self.some_label,
@@ -589,9 +590,9 @@ def test_impression_added(self):
589590
self.assertGreaterEqual(int(ttl), IMPRESSION_KEY_DEFAULT_TTL - 10)
590591

591592
impression_stored = decode(self._redis.rpop(IMPRESSIONS_QUEUE_KEY))
592-
self.assertEqual(impression_stored['m']['i'], 'unknown')
593+
self.assertEqual(impression_stored['m']['i'], GLOBAL_KEY_PARAMETERS['ip-address'])
593594
self.assertEqual(impression_stored['m']['s'], SDK_VERSION)
594-
self.assertEqual(impression_stored['m']['n'], 'unknown')
595+
self.assertEqual(impression_stored['m']['n'], GLOBAL_KEY_PARAMETERS['instance-id'])
595596
self.assertEqual(impression_stored['i']['k'], 'some_matching_key')
596597
self.assertEqual(impression_stored['i']['f'], 'some_feature_name')
597598
self.assertEqual(impression_stored['i']['t'], 'on')
@@ -634,3 +635,57 @@ def test_ttl_called_once(self):
634635

635636
logger_debug \
636637
.assert_called_once_with("SET EXPIRE KEY FOR QUEUE")
638+
639+
def test_impression_added_custom_machine_name_and_ip(self):
640+
self._some_config = mock.MagicMock()
641+
642+
self._redis = get_redis({'redisPrefix': 'singleQueueTests2'})
643+
self._redis.delete(IMPRESSIONS_QUEUE_KEY)
644+
645+
self._config = {
646+
'ready': 180000,
647+
'redisDb': 0,
648+
'redisHost': 'localhost',
649+
'redisPosrt': 6379,
650+
'redisPrefix': 'singleQueueTests',
651+
'splitSdkMachineName': 'CustomMachineName',
652+
'splitSdkMachineIp': '1.2.3.4'
653+
}
654+
655+
self._factory = get_factory('asdqwe123456', config=self._config)
656+
657+
impression = Impression(matching_key='some_matching_key',
658+
feature_name='some_feature_name',
659+
treatment='on',
660+
label='label1',
661+
change_number=123456,
662+
bucketing_key='some_bucketing_key',
663+
time=123456)
664+
665+
self.an_impressions_cache = RedisImpressionsCache(self._redis)
666+
667+
self.an_impressions_cache._logger.debug = mock.MagicMock()
668+
logger_debug = self.an_impressions_cache._logger.debug
669+
670+
self.an_impressions_cache.add_impressions([impression])
671+
672+
logger_debug \
673+
.assert_called_once_with("SET EXPIRE KEY FOR QUEUE")
674+
675+
# Assert that the TTL is within a 10-second range (between it was set and retrieved).
676+
ttl = self._redis.ttl(IMPRESSIONS_QUEUE_KEY)
677+
678+
self.assertLessEqual(int(ttl), IMPRESSION_KEY_DEFAULT_TTL)
679+
self.assertGreaterEqual(int(ttl), IMPRESSION_KEY_DEFAULT_TTL - 10)
680+
681+
impression_stored = decode(self._redis.rpop(IMPRESSIONS_QUEUE_KEY))
682+
self.assertEqual(impression_stored['m']['i'], '1.2.3.4')
683+
self.assertEqual(impression_stored['m']['s'], SDK_VERSION)
684+
self.assertEqual(impression_stored['m']['n'], 'CustomMachineName')
685+
self.assertEqual(impression_stored['i']['k'], 'some_matching_key')
686+
self.assertEqual(impression_stored['i']['f'], 'some_feature_name')
687+
self.assertEqual(impression_stored['i']['t'], 'on')
688+
self.assertEqual(impression_stored['i']['r'], 'label1')
689+
self.assertEqual(impression_stored['i']['c'], 123456)
690+
self.assertEqual(impression_stored['i']['b'], 'some_bucketing_key')
691+
self.assertEqual(impression_stored['i']['m'], 123456)

0 commit comments

Comments
 (0)