Skip to content

Commit

Permalink
[change] Timeseries data is deleted when device is deleted #419
Browse files Browse the repository at this point in the history
Closes #419
  • Loading branch information
pandafy committed Aug 18, 2022
1 parent e563520 commit 52cf287
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 2 deletions.
23 changes: 23 additions & 0 deletions openwisp_monitoring/device/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,29 @@ def test_unknown_critical(self):
dm.refresh_from_db()
self.assertEqual(dm.status, 'critical')

def test_deleting_device_deletes_tsdb(self):
dm1, ping1, _, _ = self._create_env()
device2 = self._create_device(
name='default.test.device2',
mac_address='22:33:44:55:66:77',
organization=dm1.device.organization,
)
dm2 = device2.monitoring
dm2.status = 'ok'
dm2.save()
ping2 = self._create_object_metric(
name='ping', key='ping', field_name='reachable', content_object=device2
)
ping1.write(0)
ping2.write(0)
self.assertNotEqual(ping1.read(), [])
self.assertNotEqual(ping2.read(), [])
dm1.device.delete()
# Only the metric related to the deleted device
# is deleted
self.assertEqual(ping1.read(), [])
self.assertNotEqual(ping2.read(), [])


class TestWifiClientSession(TestWifiClientSessionMixin, TestCase):
wifi_client_model = WifiClient
Expand Down
12 changes: 11 additions & 1 deletion openwisp_monitoring/monitoring/apps.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from django.apps import AppConfig
from django.conf import settings
from django.db.models.signals import post_delete
from django.utils.translation import gettext_lazy as _
from swapper import get_model_name
from swapper import get_model_name, load_model

from openwisp_utils.admin_theme.menu import register_menu_group

Expand All @@ -21,6 +22,7 @@ def ready(self):
for metric_name, metric_config in metrics.items():
register_metric_notifications(metric_name, metric_config)
self.register_menu_groups()
self.connect_metric_signals()

def register_menu_groups(self):
register_menu_group(
Expand All @@ -44,3 +46,11 @@ def register_menu_groups(self):
'icon': 'ow-monitoring',
},
)

def connect_metric_signals(self):
Metric = load_model('monitoring', 'Metric')
post_delete.connect(
Metric.post_delete_receiver,
sender=Metric,
dispatch_uid='metric_post_delete_receiver',
)
6 changes: 5 additions & 1 deletion openwisp_monitoring/monitoring/base/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
)
from ..exceptions import InvalidChartConfigException, InvalidMetricConfigException
from ..signals import pre_metric_write, threshold_crossed
from ..tasks import timeseries_write
from ..tasks import delete_timeseries, timeseries_write

User = get_user_model()
logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -115,6 +115,10 @@ def full_clean(self, *args, **kwargs):
self.key = self._makekey(self.key)
return super().full_clean(*args, **kwargs)

@classmethod
def post_delete_receiver(cls, instance, *args, **kwargs):
delete_timeseries.delay(instance.key, instance.tags)

@classmethod
def _get_or_create(cls, **kwargs):
"""
Expand Down
5 changes: 5 additions & 0 deletions openwisp_monitoring/monitoring/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ def timeseries_write(
post_metric_write.send(**signal_kwargs)


@shared_task
def delete_timeseries(key, tags):
timeseries_db.delete_series(key=key, tags=tags)


@shared_task
def migrate_timeseries_database():
"""
Expand Down
13 changes: 13 additions & 0 deletions openwisp_monitoring/monitoring/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,3 +349,16 @@ def test_get_time_str(self):
m = self._create_general_metric(name='load')
now = timezone.now()
self.assertEqual(m._get_time(now.isoformat()), now)

def test_deleting_metric_deletes_timeseries(self):
metric1 = self._create_general_metric(name='load')
metric2 = self._create_general_metric(name='traffic')
metric1.write(99)
metric2.write(5000)
self.assertNotEqual(metric1.read(), [])
self.assertNotEqual(metric2.read(), [])
metric1.delete()
self.assertEqual(metric1.read(), [])
# Only the timeseries data related to the deleted metric
# should be deleted
self.assertNotEqual(metric2.read(), [])

0 comments on commit 52cf287

Please sign in to comment.