django-restit 4.2.112__py3-none-any.whl → 4.2.114__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-restit
3
- Version: 4.2.112
3
+ Version: 4.2.114
4
4
  Summary: A Rest Framework for DJANGO
5
5
  License: MIT
6
6
  Author: Ian Starnes
@@ -113,7 +113,7 @@ incident/migrations/0014_event_group_alter_rulecheck_index.py,sha256=v3gm5k0LVoa
113
113
  incident/migrations/0015_rule_title_template_alter_incident_state.py,sha256=FPUDhFwqBC39EjeknRT7BPddEf6ExCjsXVb9LMqIn3U,687
114
114
  incident/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
115
115
  incident/models/__init__.py,sha256=NMphuhb0RTMf7Ov4QkNv7iv6_I8Wtr3xQ54yjX_a31M,209
116
- incident/models/event.py,sha256=Dw6fUi2tbLeA_ZRDcvGQNFkCkMGMBdtNeaLikXdAyE8,7769
116
+ incident/models/event.py,sha256=LNKYdqOj_CO4aGvc2dNmy3K-S52Udi_gZ4-wintbs1s,7901
117
117
  incident/models/incident.py,sha256=1uLkr7_QEKYsccO-OVmb7YcM8BA3Q6UCWWw2m935YKg,20030
118
118
  incident/models/ossec.py,sha256=eUDRGawzuLWobKEVGKfdZisDnyjS_Hlxi0T_GCSLCCI,2252
119
119
  incident/models/rules.py,sha256=aRkJ0ZnTv87nAUC1sHVkPExfb3OJ8fgHQIhnCIpIbhQ,7001
@@ -126,7 +126,7 @@ incident/templates/email/incident_change.html,sha256=tQYphypwLukkVdwH0TB2Szz2VEJ
126
126
  incident/templates/email/incident_msg.html,sha256=MZdKhTddUF2MpiH8Z3RTQEmW_ko1n3ajeZ11KLtiLlU,13780
127
127
  incident/templates/email/incident_new.html,sha256=W6nwFQROnyDfMlXub8s02ws4hGnJp16pfgp9xTm_aEc,15185
128
128
  incident/templates/email/incident_plain.html,sha256=AyTv_3ITUwHoAO7Tv_xCODzWQXTV61EdtlphFum0BnM,14739
129
- incident/tq.py,sha256=6KjeTFlWAlG_l8LWMlxUGdr8ULU0uE-DB5ex0ERW440,5226
129
+ incident/tq.py,sha256=BO8OjH5UzLB97vOatMmsuMDeQ1ZYhXWENoomoVJ9QlY,5235
130
130
  location/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
131
131
  location/admin.py,sha256=6S97Rlgjkk0jM15sbT1OJRPZbgvKn2rn7duCSazOXq4,297
132
132
  location/geolocate.py,sha256=UgV129vmSxnqYFBYJD2RQVOcC1-lJJ1zUaxDqOJRbG4,1694
@@ -333,7 +333,7 @@ medialib/youtube/upload.py,sha256=MTuPxm1ZC-y5pXAGtLNtp1hBSNZgCKYt1ewP5hwMQHI,28
333
333
  medialib/youtube/uritemplate/__init__.py,sha256=ONWR_KRz9au0O-XUUTrO_UN7GHTmZCTKyvflUQb8wxM,4996
334
334
  metrics/README.md,sha256=YwbCA2y6xJBlaO6yEtl1zWpqrQ4ZzkQSuQT-h6btET8,2307
335
335
  metrics/__init__.py,sha256=70sdDZGOwGIEFWgDkHWPMVODFelo206jp1g-BFV2u_4,90
336
- metrics/client.py,sha256=-cbOdOIJoE8Q5DH_sMv-Ia_tD7w15SXt3pBnNUGPNPo,25251
336
+ metrics/client.py,sha256=WXyyl4C4CUZECJHWrY154uTPMEoJTZoYocVK582i4co,25322
337
337
  metrics/eod.py,sha256=gnq-tNE7xfm2ah52e2TUyERgUQNwkFuT2rtDv8XOUVQ,9182
338
338
  metrics/examples/eod_example.py,sha256=gYtansjsKILVxe8XJD12XPaxmBJ-B6dOXGZG2JTGWA8,1664
339
339
  metrics/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -352,10 +352,10 @@ metrics/migrations/0004_eodmetrics.py,sha256=Ky6ZVMZqa0F_SUp_QFWY7ZKBgVhy9CS4wZc
352
352
  metrics/migrations/0005_alter_metrics_v1_alter_metrics_v10_alter_metrics_v11_and_more.py,sha256=pmwJfpPJ1RUX_CqM66l6vvV-nrAUPo_GIan0Pc9mQHs,2358
353
353
  metrics/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
354
354
  metrics/models.py,sha256=lD9nVzfwdav70ENulqJ8rE8Ui8EWlzdVp05rg8bAlMA,13444
355
- metrics/periodic.py,sha256=VmL0YG05D6k5fcNsF4QqPEU-BBPbZXjbOrp3b8EHZ-U,651
355
+ metrics/periodic.py,sha256=IayBLLat40D8FB-A3bYBW9lxm9-IzcugQunojThQ_OU,661
356
356
  metrics/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
357
357
  metrics/providers/aws.py,sha256=dIBGFE1Fvszy6rmVrn_Fm1zUDv345q4dBsg9Iit-XCc,8358
358
- metrics/rpc.py,sha256=LXZcYBtssSFmcaoIjaJ32S6Nv_mswDALtmUYm5ByDMQ,21667
358
+ metrics/rpc.py,sha256=gnyRFBW2KBA-TAiqVcwkoVviX4bPbZ2WZELlR9uEUlM,22213
359
359
  metrics/settings.py,sha256=wwHA9Z7BAHNeu3tFVn8Fh5j46KR-eGx0E8r5dzCFlAU,132
360
360
  metrics/tq.py,sha256=WHBRYSinmTuxF9l-_-lx0yfzEYkb0ffVMt_uvCj9bYo,825
361
361
  metrics/utils.py,sha256=PSydxeI983udULUTcbeWG-_ulPSOac6Q_t_8k_Vjn1I,12606
@@ -374,7 +374,7 @@ pushit/utils.py,sha256=IeTCGa-164nmB1jIsK1lu1O1QzUhS3BKfuXHGjCW-ck,2121
374
374
  rest/.gitignore,sha256=TbEvWRMnAiajCTOdhiNrd9eeCAaIjRp9PRjE_VkMM5g,118
375
375
  rest/README.md,sha256=V3ETc-cJu8PZIbKr9xSe_pA4JEUpC8Dhw4bQeVCDJPw,5460
376
376
  rest/RemoteEvents.py,sha256=nL46U7AuxIrlw2JunphR1tsXyqi-ep_gD9CYGpYbNgE,72
377
- rest/__init__.py,sha256=m3kqpu3YhcghJ-KrIUqDNZLIi6TS2MsL0ixv0h0LuPE,122
377
+ rest/__init__.py,sha256=I4M0vBLQ0dMaa7ccf6GrMzSczgRpGJKMpuC_hGglXKw,122
378
378
  rest/arc4.py,sha256=y644IbF1ec--e4cUJ3KEYsewTCITK0gmlwa5mJruFC0,1967
379
379
  rest/cache.py,sha256=1Qg0rkaCJCaVP0-l5hZg2CIblTdeBSlj_0fP6vlKUpU,83
380
380
  rest/crypto/__init__.py,sha256=Tl0U11rgj1eBYqd6OXJ2_XSdNLumW_JkBZnaJqI6Ldw,72
@@ -407,13 +407,13 @@ rest/middleware/request.py,sha256=JchRNy5L-bGd-7h-KFYekGRvREe2eCkZXKOYqIkP2hI,41
407
407
  rest/middleware/session.py,sha256=zHSoQpIzRLmpqr_JvW406wzpvU3W3gDbm5JhtzLAMlE,10240
408
408
  rest/middleware/session_store.py,sha256=1nSdeXK8PyuYgGgIufqrS6j6QpIrQ7zbMNT0ol75e6U,1901
409
409
  rest/models/__init__.py,sha256=M8pvFDq-WCF-QcM58X7pMufYYe0aaQ3U0PwGe9TKbbY,130
410
- rest/models/base.py,sha256=-NUKed_67o3eCZCknndQixSHU4pR-Lm2wxsb_h4rjVQ,70652
410
+ rest/models/base.py,sha256=6mqDcuVVFm610V5RLO8yfr0vY-I4sBN_QW69OkejsJQ,70655
411
411
  rest/models/cacher.py,sha256=eKz8TINVhWEqKhJGMsRkKZTtBUIv5rN3NHbZwOC56Uk,578
412
412
  rest/models/metadata.py,sha256=1nQ7CYo9bJHoaXE_hVNaj1-Y7yqhHlf2ZlaD1IfTzic,12904
413
413
  rest/net.py,sha256=LcB2QV6VNRtsSdmiQvYZgwQUDwOPMn_VBdRiZ6OpI-I,2974
414
414
  rest/regexes.yaml,sha256=VoGb4E-P_K9f82Yzcpltgzekpt9usRtwu9PYlo46nUw,149463
415
415
  rest/requestex.py,sha256=N56056vV3zWkAP-QrYsCu7SdpPzE5kLuPoxGIuZAKt0,16127
416
- rest/rpc.py,sha256=wCR22Ds4CgZ9q-ptWuIpc15J01tTRPpAYWEkAA9LDHM,2205
416
+ rest/rpc.py,sha256=xun-HuaEqm1Lwg-9Xm4Y2JwOf8wTdpoagHuIUNlqTlI,2891
417
417
  rest/search.py,sha256=QVjk2b5tZLgf1zM2MHvJTyRjwUbY5ZD7HXSTmSPXtvU,8362
418
418
  rest/serializers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
419
419
  rest/serializers/collection.py,sha256=V9O4qxw26VX9dSYdbsN0-RNnXEi347Ln8eFLZ003LhA,4646
@@ -456,8 +456,8 @@ taskqueue/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
456
456
  taskqueue/admin.py,sha256=E6zXoToS_ea3MdoGjZzF1JiepWFtDSoZUQdan8H-pXI,208
457
457
  taskqueue/migrations/0001_initial.py,sha256=JwYib8CK5ftSXlfxKZUcKEEVsXktNB5q3h-2tu9inGk,4738
458
458
  taskqueue/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
459
- taskqueue/models.py,sha256=i8v0vQqlz4X3rVFVJsUSldA-26NEPWnsMZF2Kly_1Qo,22398
460
- taskqueue/periodic.py,sha256=FMXEmAdTQwgBIlwwuFV-VfxMl8OKXYzHp9jJt57Qghk,3838
459
+ taskqueue/models.py,sha256=VQ8Slk6Cm3H7ZDCfFP_b83VL2mpSdOOGTxALTZxQdqo,23726
460
+ taskqueue/periodic.py,sha256=hpXnunJL_cuVQLAKpjTbABbsQ4fvdsV9_gyyK-_53Sk,3844
461
461
  taskqueue/rpc.py,sha256=Lf5VUoqCRkfWUAIvx_s508mjAtDPwpiWyxg0ryqWbQA,5793
462
462
  taskqueue/tq.py,sha256=PzSoDrawYcqZylruEgsK95gcJ4J_VhdM6rxg9V6_X8E,942
463
463
  taskqueue/transports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -498,7 +498,7 @@ wiki/rpc/wiki.py,sha256=RQY1gtqxdNhp13n3SkZL9WZ6RatrtCIh7QOYta6-UUU,1327
498
498
  wiki/tq.py,sha256=wvuBZ3OMV_D2o4kpJhVLIOwpEUfwlglqLJQvpncAwtk,313
499
499
  ws4redis/README.md,sha256=QvwdsauPKxx4qQqnJ991xeU8DgFQCj3CeQt-nCE4s-w,3624
500
500
  ws4redis/__init__.py,sha256=teNfv83A_ke1CBt9BB7NsnWCcFBhnUFPsPESjF554_k,46
501
- ws4redis/client.py,sha256=iuwygfy32rsSS8f1fWtgOgprWBa42LKbRpUTIXwKfGM,7013
501
+ ws4redis/client.py,sha256=kElPtVMVObLUXAfu32v_PHd0HyygrW-ukk37_Tuo7ZM,7062
502
502
  ws4redis/connection.py,sha256=QGjzalYrx1y4o6sb6P1akL-Y2fjf2qil0JCo-ona5F8,13431
503
503
  ws4redis/exceptions.py,sha256=EGLoRTdqJVwz900pwhciqPuSjBBd08hhLgFu6umHrI4,636
504
504
  ws4redis/redis.py,sha256=IfT4p3bUtlqso9rryNliH9Ebzlx8-Q2VJcs1kFioeGA,6093
@@ -509,7 +509,7 @@ ws4redis/servers/uwsgi.py,sha256=VyhoCI1DnVFqBiJYHoxqn5Idlf6uJPHvfBKgkjs34mo,172
509
509
  ws4redis/settings.py,sha256=K0yBiLUuY81iDM4Yr-k8hbvjn5VVHu5zQhmMK8Dtz0s,1536
510
510
  ws4redis/utf8validator.py,sha256=S0OlfjeGRP75aO6CzZsF4oTjRQAgR17OWE9rgZdMBZA,5122
511
511
  ws4redis/websocket.py,sha256=R0TUyPsoVRD7Y_oU7w2I6NL4fPwiz5Vl94-fUkZgLHA,14848
512
- django_restit-4.2.112.dist-info/LICENSE.md,sha256=VHN4hhEeVOoFjtG-5fVv4jesA4SWi0Z-KgOzzN6a1ps,1068
513
- django_restit-4.2.112.dist-info/METADATA,sha256=sb1cEMGTn30fqgEPa6eq2gPuta4N5nSVKh3WzcG5fec,7663
514
- django_restit-4.2.112.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
515
- django_restit-4.2.112.dist-info/RECORD,,
512
+ django_restit-4.2.114.dist-info/LICENSE.md,sha256=VHN4hhEeVOoFjtG-5fVv4jesA4SWi0Z-KgOzzN6a1ps,1068
513
+ django_restit-4.2.114.dist-info/METADATA,sha256=XRTxk70XLcfM04aM6GvDnMGuuQ5FoDyrYoVybJVrLNI,7663
514
+ django_restit-4.2.114.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
515
+ django_restit-4.2.114.dist-info/RECORD,,
incident/models/event.py CHANGED
@@ -14,6 +14,7 @@ from .rules import Rule
14
14
 
15
15
  INCIDENT_METRICS = settings.get("INCIDENT_METRICS", False)
16
16
  INCIDENT_EVENT_METRICS = settings.get("INCIDENT_EVENT_METRICS", False)
17
+ INCIDENT_EVENT_GRANULARITY = settings.get("INCIDENT_EVENT_GRANULARITY", "hourly")
17
18
  EVENT_TO_INCIDENT_LEVEL = settings.get("EVENT_TO_INCIDENT_LEVEL", 4)
18
19
  EVENT_DETAIL_TEMPLATES = settings.get("EVENT_DETAIL_TEMPLATES", None)
19
20
  EVENT_META_KEYWORDS = settings.get("EVENT_META_KEYWORDS", [
@@ -144,7 +145,7 @@ class Event(JSONMetaData, rm.RestModel):
144
145
  if INCIDENT_EVENT_METRICS:
145
146
  if self.hostname:
146
147
  metrics.metric(f"incident_evt_{self.hostname}", category="incident_events", min_granularity="hourly")
147
- metrics.metric("incident_evt", category="incident_events", min_granularity="hourly")
148
+ metrics.metric("incident_evt", min_granularity=INCIDENT_EVENT_GRANULARITY)
148
149
 
149
150
  self.setProperty("level", self.level)
150
151
  if request is not None:
@@ -199,9 +200,10 @@ class Event(JSONMetaData, rm.RestModel):
199
200
  self.incident = incident
200
201
  self.save()
201
202
  if INCIDENT_METRICS:
203
+ # we want to track any incidents, including bundles
202
204
  if self.hostname:
203
205
  metrics.metric(f"incidents_{self.hostname}", category="incidents", min_granularity="hourly")
204
- metrics.metric("incidents", category="incidents", min_granularity="hourly")
206
+ metrics.metric("incidents", min_granularity=INCIDENT_EVENT_GRANULARITY)
205
207
 
206
208
  try:
207
209
  incident.triggerAction()
incident/tq.py CHANGED
@@ -118,16 +118,16 @@ def on_incoming_email(task):
118
118
  def run_cleanup(task):
119
119
  stale = datetime.now() - timedelta(days=90)
120
120
  # delete all ossec alerts older then 90 days
121
- count = ia.ServerOssecAlert.objects.filter(created__lte=stale).delete()
121
+ count = ia.ServerOssecAlert.objects.filter(created__lte=stale).delete()[0]
122
122
  if count:
123
123
  task.log(f"deleted {count} old ServerOssecAlert")
124
124
  # delete all events older then 90 days
125
125
  count = ia.Event.objects.filter(created__lte=stale).filter(
126
- Q(incident__state=ia.INCIDENT_STATE_IGNORE) | Q(incident__isnull=True)).delete()
126
+ Q(incident__state=ia.INCIDENT_STATE_IGNORE) | Q(incident__isnull=True)).delete()[0]
127
127
  if count:
128
128
  task.log(f"deleted {count} old Events")
129
129
 
130
- count = ia.Incident.objects.filter(created__lte=stale).filter(state=ia.INCIDENT_STATE_IGNORE).delete()
130
+ count = ia.Incident.objects.filter(created__lte=stale).filter(state=ia.INCIDENT_STATE_IGNORE).delete()[0]
131
131
  if count:
132
132
  task.log(f"deleted {count} old Incidents")
133
133
 
metrics/client.py CHANGED
@@ -329,8 +329,12 @@ class R(object):
329
329
  for s in slug:
330
330
  self.metric(s, num, category, expire, date)
331
331
  return
332
+
332
333
  # Add the slug to the set of metric slugs
333
- self.r.sadd(self._metric_slugs_key, slug)
334
+ try:
335
+ self.r.sadd(self._metric_slugs_key, slug)
336
+ except Exception:
337
+ return
334
338
 
335
339
  if category:
336
340
  self._categorize(slug, category)
metrics/periodic.py CHANGED
@@ -1,13 +1,13 @@
1
1
  from datetime import datetime, timedelta
2
2
  from taskqueue.models import Task
3
- from .models import Metrics
3
+ from metrics.models import Metrics
4
4
  from rest import log
5
5
  from rest import decorators as rd
6
6
 
7
7
 
8
8
  @rd.periodic(minute=15, hour=10)
9
9
  def run_cleanup(force=False, verbose=False, now=None):
10
- count = Metrics.objects.filter(expires__lte=datetime.now()).delete()
10
+ count = Metrics.objects.filter(expires__lte=datetime.now()).delete()[0]
11
11
  if count > 0:
12
12
  logger = log.getLogger("auditlog", filename="auditlog.log")
13
13
  logger.info(f"METRICS.CLEANUP {count} expired records deleted")
metrics/rpc.py CHANGED
@@ -301,32 +301,44 @@ def rest_on_ec2_domains(request):
301
301
  @rd.urlGET('restit/servers')
302
302
  @rd.login_required
303
303
  def rest_on_ec2_restit_stats(request):
304
- hostname = settings.SERVER_ROOT
305
- if hostname is None:
306
- hostname = settings.SERVER_NAME
304
+ from concurrent.futures import ThreadPoolExecutor, as_completed
305
+ hostname = settings.SERVER_ROOT or settings.SERVER_NAME
307
306
  if hostname.count(".") == 2:
308
- hostname = hostname[hostname.find(".")]
307
+ hostname = hostname.split(".")[1] # Corrected to get the second part
308
+
309
309
  instances = aws.getAllEC2()
310
310
  hosts = [inst.name for inst in instances]
311
- data = []
312
- for name in hosts:
311
+ path = "versions"
312
+ params = {"detailed": 1}
313
+ if request.DATA.get("sysinfo"):
314
+ path = "system/info"
315
+ params["key"] = settings.SYS_INFO_KEY
316
+
317
+ def fetch_host_data(name):
313
318
  if settings.SERVER_NAME_MAP and name in settings.SERVER_NAME_MAP:
314
319
  host = settings.SERVER_NAME_MAP[name]
315
320
  if "." not in host:
316
321
  host = f"{name}.{hostname}"
317
322
  else:
318
323
  host = f"{name}.{hostname}"
319
- resp = net.REQUEST(
320
- "GET", host,
321
- f"/{REST_PREFIX}versions",
322
- params=dict(detailed=1),
323
- timeout=5.0)
324
- if resp.status:
325
- resp.data.id = host
326
- resp.data.hostname = host
327
- data.append(resp.data)
328
- else:
329
- data.append(dict(id=host, hostname=host))
324
+
325
+ try:
326
+ resp = net.REQUEST("GET", host, f"/{REST_PREFIX}{path}", params=params, timeout=5.0)
327
+ if resp.status:
328
+ resp.data.id = host
329
+ resp.data.hostname = host
330
+ return resp.data
331
+ else:
332
+ return dict(id=host, hostname=host)
333
+ except requests.RequestException:
334
+ return dict(id=host, hostname=host)
335
+
336
+ data = []
337
+ with ThreadPoolExecutor(max_workers=10) as executor: # Adjust max_workers as needed
338
+ futures = {executor.submit(fetch_host_data, name): name for name in hosts}
339
+ for future in as_completed(futures):
340
+ data.append(future.result())
341
+
330
342
  return rv.restReturn(request, dict(data=data))
331
343
 
332
344
 
rest/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  from .uberdict import UberDict # noqa: F401
2
2
  from .settings_helper import settings # noqa: F401
3
3
 
4
- __version__ = "4.2.112"
4
+ __version__ = "4.2.114"
rest/models/base.py CHANGED
@@ -1197,7 +1197,7 @@ class RestModel(object):
1197
1197
  can_delete = getattr(cls.RestMeta, "CAN_DELETE", False)
1198
1198
  if not can_delete:
1199
1199
  raise re.PermissionDeniedException(f"deletion not allowed for {cls.get_class_name()}", 438)
1200
- count = qset.delete()
1200
+ count = qset.delete()[0]
1201
1201
  return GRAPH_HELPERS.restStatus(request, True, error="delete {} items".format(count))
1202
1202
  elif action == "update":
1203
1203
  update_fields = request.DATA.get(["batch_data", "batch_update"])
rest/rpc.py CHANGED
@@ -10,6 +10,8 @@ from django.conf import settings
10
10
 
11
11
  from .decorators import url
12
12
  from rest.extra import hostinfo
13
+ from ws4redis import client as redis
14
+ from django.db import connections
13
15
 
14
16
 
15
17
  URL_PREFIX = ""
@@ -49,6 +51,27 @@ def on_get_joke(request):
49
51
  return views.restGet(request, {"joke": joke.getRandomJoke()})
50
52
 
51
53
 
54
+ @url('status')
55
+ def on_get_status(request):
56
+ flag = True
57
+ try:
58
+ flag = redis.ping()
59
+ except Exception:
60
+ flag = False
61
+ status = dict(redis=flag, database={})
62
+ for alias in settings.DATABASES.keys():
63
+ db_conn = connections[alias]
64
+ try:
65
+ # Ensure connection with a timeout
66
+ db_conn.ensure_connection()
67
+ status["database"][alias] = True
68
+ except Exception:
69
+ flag = False
70
+ status["database"][alias] = False
71
+ if flag:
72
+ return views.restGet(request, status)
73
+ return views.restResult(request, status, 417)
74
+
52
75
  @url('system/info')
53
76
  def on_get_system_info(request):
54
77
  key = request.DATA.get("key")
taskqueue/models.py CHANGED
@@ -8,6 +8,7 @@ from rest import crypto
8
8
  from ws4redis import client as redis
9
9
  from account.models import Member
10
10
  import importlib
11
+ import metrics
11
12
 
12
13
  import traceback
13
14
 
@@ -34,6 +35,12 @@ TASK_STATES = [
34
35
  TQ_RETRY_BACKOFF_FACTOR = settings.get("TQ_RETRY_BACKOFF_FACTOR", 2)
35
36
  TQ_RETRY_ATTEMPTS = settings.get("TQ_RETRY_ATTEMPTS", 5)
36
37
  TQ_RETRY_DELAY = settings.get("TQ_RETRY_DELAY", 60)
38
+ TQ_METRICS = settings.get("TQ_METRICS", True)
39
+ TQ_METRICS_GRANULARITY = settings.get("TQ_METRICS_GRANULARITY", "hourly")
40
+ TQ_METRICS_CREATED = settings.get("TQ_METRICS_CREATED", False)
41
+ TQ_METRICS_FUNCTION = settings.get("TQ_METRICS_FUNCTION", False)
42
+ TQ_METRICS_CHANNEL = settings.get("TQ_METRICS_CHANNEL", False)
43
+
37
44
 
38
45
  def getAppHandler(app_name, fname):
39
46
  try:
@@ -225,6 +232,12 @@ class Task(models.Model, RestModel):
225
232
  self.runtime = int(time.time() - self._started)
226
233
  self.state = TASK_STATE_COMPLETED
227
234
  self.save()
235
+ if TQ_METRICS:
236
+ metrics.metric("tq_task_completed", min_granularity=TQ_METRICS_GRANULARITY)
237
+ if TQ_METRICS_CHANNEL:
238
+ metrics.metric(f"tq_chan_done_{self.channel}", category="tq_chan_done", min_granularity=TQ_METRICS_GRANULARITY)
239
+ if TQ_METRICS_FUNCTION:
240
+ metrics.metric(f"tq_func_done_{self.fname}", category="tq_func_done", min_granularity=TQ_METRICS_GRANULARITY)
228
241
 
229
242
  def failed(self, reason=None, category="taskqueue_errors"):
230
243
  if reason and len(reason) > 250:
@@ -233,6 +246,12 @@ class Task(models.Model, RestModel):
233
246
  self.state = TASK_STATE_FAILED
234
247
  self.notifyError(category=category, reason=reason)
235
248
  self.save()
249
+ if TQ_METRICS:
250
+ metrics.metric("tq_task_failed", min_granularity=TQ_METRICS_GRANULARITY)
251
+ if TQ_METRICS_CHANNEL:
252
+ metrics.metric(f"tq_chan_fail_{self.channel}", category="tq_chan_fail", min_granularity=TQ_METRICS_GRANULARITY)
253
+ if TQ_METRICS_FUNCTION:
254
+ metrics.metric(f"tq_func_fail_{self.fname}", category="tq_func_fail", min_granularity=TQ_METRICS_GRANULARITY)
236
255
 
237
256
  def notifyError(self, category="taskqueue_errors", reason=None):
238
257
  handler = f"{self.model}.{self.fname}"
@@ -287,6 +306,8 @@ class Task(models.Model, RestModel):
287
306
  out.data = self.data
288
307
  if not channel:
289
308
  channel = self.channel
309
+ if TQ_METRICS and TQ_METRICS_CREATED:
310
+ metrics.metric("tq_task_created", min_granularity=TQ_METRICS_GRANULARITY)
290
311
  return redis.publish(channel, out)
291
312
 
292
313
  def getHandler(self):
taskqueue/periodic.py CHANGED
@@ -95,11 +95,11 @@ def run_cleanup(force=False, verbose=False, now=None):
95
95
  if not settings.TQ_MASTER:
96
96
  return
97
97
  stale = datetime.now() - timedelta(days=TQ_DELETE_AFTER)
98
- count = Task.objects.filter(created__lte=stale).delete()
98
+ count = Task.objects.filter(created__lte=stale).delete()[0]
99
99
  if count:
100
100
  logger.info("deleted {} old tasks".format(count))
101
101
  stale = datetime.now() - timedelta(days=TQ_DELETE_COMPLETED_AFTER)
102
- count = Task.objects.filter(created__lte=stale, state=TASK_STATE_COMPLETED).delete()
102
+ count = Task.objects.filter(created__lte=stale, state=TASK_STATE_COMPLETED).delete()[0]
103
103
  if count:
104
104
  logger.info("deleted {} old completed tasks".format(count))
105
105
 
ws4redis/client.py CHANGED
@@ -21,6 +21,10 @@ def buildEventMessage(name=None, message=None, priority=0, model=None, model_pk=
21
21
  return msg.toJSON(as_string=True)
22
22
 
23
23
 
24
+ def ping():
25
+ return getRedisClient().ping()
26
+
27
+
24
28
  def exists(key, default=None):
25
29
  c = getRedisClient()
26
30
  return c.exists(key)