Skip to content

Commit bdde49b

Browse files
committed
Merge branch 'fix/redis' into 'master'
Fix/redis See merge request grafolean/grafolean-collector-snmp!8
2 parents 0b95779 + a7989ce commit bdde49b

8 files changed

+41
-12
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
.env
22
.vscode
3+
.cache
4+
__pycache__

.gitlab-ci.yml

+3
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@ stages:
1313
pytest:
1414
stage: test
1515
image: python:3.6-slim-stretch
16+
services:
17+
- redis:5-alpine
1618
before_script:
1719
- apt-get update
1820
- apt-get install --no-install-recommends -q -y libsnmp-dev build-essential git
1921
- pip install --no-cache-dir pipenv
2022
- pipenv install --dev
2123
script:
24+
- export REDIS_HOST="redis"
2225
- pipenv run pytest -x test_snmpcollector.py
2326

2427
deploy to docker hub:

Pipfile

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ ansicolors = "*"
1515
easysnmp = {editable = true,git = "http://github.com/grafolean/easysnmp"}
1616
mathjspy = "*"
1717
numpy = "*"
18+
redis = "*"
1819

1920
[requires]
2021
python_version = "3.6"

Pipfile.lock

+9-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

collector.py

+1
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ def fetch_job_configs(self, protocol):
236236

237237
sensors.append({
238238
"sensor_details": sensor["details"],
239+
"sensor_id": sensor_id,
239240
"interval": interval,
240241
})
241242
# and hide all other protocols, saving just sensors for selected one: (not strictly necessary, just cleaner)

docker-compose.dev.yml

+9
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,12 @@ services:
3232
# on the same host, '127.0.0.1' translates to container, not host - this directive changes network mode
3333
# so that Docker networking is bypassed.
3434
network_mode: "host"
35+
36+
redis:
37+
image: redis:5-alpine
38+
container_name: grafolean-collector-snmp-redis
39+
ports:
40+
- "127.0.0.1:6379:6379"
41+
# We advise not to use `network_mode: "host"` in production, because it would expose Redis to host network
42+
# (even if access is limited to 127.0.0.1).
43+
network_mode: "host"

docker-compose.yml

+7-4
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@ services:
1616
environment:
1717
# Backend url must be set to the address of the Grafolean backend, for example this uses Grafolean hosted service:
1818
# - BACKEND_URL=https://grafolean.com/api
19+
# IMPORTANT: '127.0.0.1' and 'localhost' are _never_ correct addresses for Grafolean backend, because they translate
20+
# to container, not host.
1921
- BACKEND_URL=
2022
# To use SNMP Collector, a bot with the protocol "snmp" must be added via user interface, then the token needs to be copied here:
2123
- BOT_TOKEN=
2224
# Interval between fetching information about jobs:
2325
- JOBS_REFRESH_INTERVAL=60
26+
- REDIS_HOST=redis
2427
restart: always
25-
# Grafolean backend must be accessible on BACKEND_URL *from the point of view of container*. If running
26-
# on the same host, '127.0.0.1' translates to container, not host - this directive changes network mode
27-
# so that Docker networking is bypassed.
28-
network_mode: "host"
28+
29+
redis:
30+
image: redis:5-alpine
31+
container_name: grafolean-collector-snmp-redis

snmpcollector.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from pytz import utc
77
from colors import color
88
import requests
9+
import redis
910

1011
from easysnmp import Session, SNMPVariable
1112
from mathjspy import MathJS
@@ -26,18 +27,19 @@ class NoValueForOid(Exception):
2627
pass
2728

2829

29-
previous_counter_values = {}
30+
REDIS_HOST = os.environ.get('REDIS_HOST', '127.0.0.1')
31+
r = redis.Redis(host=REDIS_HOST)
3032

3133

3234
def _get_previous_counter_value(counter_ident):
33-
prev_value = previous_counter_values.get(counter_ident)
34-
if prev_value is None:
35+
prev_value = r.hgetall(counter_ident)
36+
if not prev_value: # empty dict
3537
return None, None
36-
return prev_value
38+
return int(prev_value[b'v']), float(prev_value[b't'])
3739

3840

3941
def _save_current_counter_value(new_value, now, counter_ident):
40-
previous_counter_values[counter_ident] = (new_value, now)
42+
r.hmset(counter_ident, {b'v': new_value, b't': now})
4143

4244

4345
def _convert_counters_to_values(results, now, counter_ident_prefix):
@@ -52,7 +54,7 @@ def _convert_counters_to_values(results, now, counter_ident_prefix):
5254
# counter - deal with it:
5355
counter_ident = counter_ident_prefix + f'/{i}/{v.oid}/{v.oid_index}'
5456
old_value, t = _get_previous_counter_value(counter_ident)
55-
new_value = float(v.value)
57+
new_value = int(float(v.value))
5658
_save_current_counter_value(new_value, now, counter_ident)
5759
if old_value is None:
5860
new_results.append(SNMPVariable(oid=v.oid, oid_index=v.oid_index, value=None, snmp_type='COUNTER_PER_S'))
@@ -233,7 +235,7 @@ def do_snmp(*args, **job_info):
233235
walk_indexes = [r.oid_index for r in result]
234236
log.info("Results: {}".format(list(zip(oids, methods, results))))
235237

236-
counter_ident_prefix = f'{job_info["entity_id"]}/{sensor["sensor_details"]["id"]}'
238+
counter_ident_prefix = f'{job_info["entity_id"]}/{sensor["sensor_id"]}'
237239
results_no_counters = _convert_counters_to_values(results, time.time(), counter_ident_prefix)
238240

239241
# We have SNMP results and expression - let's calculate value(s). The trick here is that

0 commit comments

Comments
 (0)