forked from GithubBackups/healthchecks
Second interation of this
This commit is contained in:
parent
4b1b232959
commit
90d4246848
@ -207,7 +207,7 @@ class Check(models.Model):
|
||||
code_half = self.code.hex[:16]
|
||||
return hashlib.sha1(code_half.encode()).hexdigest()
|
||||
|
||||
def to_dict(self, readonly=False, history=None):
|
||||
def to_dict(self, readonly=False):
|
||||
|
||||
result = {
|
||||
"name": self.name,
|
||||
@ -224,24 +224,6 @@ class Check(models.Model):
|
||||
if self.last_duration:
|
||||
result["last_duration"] = int(self.last_duration.total_seconds())
|
||||
|
||||
if history:
|
||||
split = re.split(r'(h|d|w)$',history,maxsplit=0)
|
||||
if len(split) == 3: # re.split should return a list of 3 items if the parameter is set correctly
|
||||
zone = pytz.timezone(self.tz)
|
||||
current_now = datetime.now(tz=zone)
|
||||
|
||||
if split[1] == 'd':
|
||||
cutoff = current_now - td(days=int(split[0]))
|
||||
elif split[1] == 'h':
|
||||
cutoff = current_now - td(hours=int(split[0]))
|
||||
elif split[1] == 'w':
|
||||
cutoff = current_now - td(weeks=int(split[0]))
|
||||
|
||||
flips = Flip.objects.select_related("owner").filter(
|
||||
owner=self, new_status__in=("down","up"), created__gt=cutoff
|
||||
).order_by("created")
|
||||
dictStatus = {"up":1,"down":0}
|
||||
result['history'] = list(map(lambda x: {'timestamp':x.created,'up':dictStatus[x.new_status]}, flips))
|
||||
if readonly:
|
||||
result["unique_key"] = self.unique_key
|
||||
else:
|
||||
|
@ -38,6 +38,8 @@ urlpatterns = [
|
||||
path("api/v1/checks/<uuid:code>/pause", views.pause, name="hc-api-pause"),
|
||||
path("api/v1/notifications/<uuid:code>/bounce", views.bounce, name="hc-api-bounce"),
|
||||
path("api/v1/checks/<uuid:code>/pings/", views.pings, name="hc-api-pings"),
|
||||
path("api/v1/checks/<uuid:code>/flips/", views.flips, name="hc-api-flips"),
|
||||
path("api/v1/checks/<sha1:unique_key>/flips/", views.get_flips_by_unique_key),
|
||||
path("api/v1/channels/", views.channels),
|
||||
path(
|
||||
"badge/<slug:badge_key>/<slug:signature>/<quoted:tag>.<slug:fmt>",
|
||||
|
@ -1,4 +1,5 @@
|
||||
from datetime import timedelta as td
|
||||
from datetime import datetime
|
||||
import time
|
||||
import uuid
|
||||
|
||||
@ -8,6 +9,7 @@ from django.http import (
|
||||
HttpResponse,
|
||||
HttpResponseForbidden,
|
||||
HttpResponseNotFound,
|
||||
HttpResponseBadRequest,
|
||||
JsonResponse,
|
||||
)
|
||||
from django.shortcuts import get_object_or_404
|
||||
@ -293,6 +295,57 @@ def pings(request, code):
|
||||
|
||||
return JsonResponse({"pings": dicts})
|
||||
|
||||
@cors("GET")
|
||||
@csrf_exempt
|
||||
@validate_json()
|
||||
@authorize_read
|
||||
def flips(request, code):
|
||||
check = get_object_or_404(Check, code=code)
|
||||
if check.project_id != request.project.id:
|
||||
return HttpResponseForbidden()
|
||||
|
||||
if any(x in request.GET for x in ('start','end')) and 'seconds' in request.GET:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
history_start = None
|
||||
history_end = datetime.now()
|
||||
|
||||
if 'start' in request.GET:
|
||||
history_start = datetime.fromtimestamp(int(request.GET['start']))
|
||||
if 'end' in request.GET:
|
||||
history_end = datetime.fromtimestamp(int(request.GET['end']))
|
||||
|
||||
if 'seconds' in request.GET:
|
||||
history_start = datetime.now()-td(seconds=int(request.GET['seconds']))
|
||||
elif not history_start:
|
||||
history_start = datetime.now()-td(seconds=3600)
|
||||
|
||||
flips = Flip.objects.select_related("owner").filter(
|
||||
owner=check, new_status__in=("down","up"),
|
||||
created__gt=history_start,
|
||||
created__lt=history_end
|
||||
).order_by("created")
|
||||
dictStatus = {"up":1,"down":0}
|
||||
|
||||
return JsonResponse({"flips": list(map(lambda x: {'timestamp':x.created,'up':dictStatus[x.new_status]}, flips))})
|
||||
|
||||
# return JsonResponse(check.to_dict(
|
||||
# readonly=request.readonly,
|
||||
# history=(
|
||||
# history_start,history_end
|
||||
# )
|
||||
# ))
|
||||
|
||||
@cors("GET")
|
||||
@csrf_exempt
|
||||
@validate_json()
|
||||
@authorize_read
|
||||
def get_flips_by_unique_key(request, unique_key):
|
||||
checks = Check.objects.filter(project=request.project.id)
|
||||
for check in checks:
|
||||
if check.unique_key == unique_key:
|
||||
return flips(request,check.code)
|
||||
return HttpResponseNotFound()
|
||||
|
||||
@never_cache
|
||||
@cors("GET")
|
||||
|
@ -746,6 +746,83 @@ curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/pings/ \
|
||||
```
|
||||
|
||||
|
||||
## Get a list of check's flips {: #list-flips .rule }
|
||||
|
||||
`GET SITE_ROOT/api/v1/checks/<uuid>/flips/` or `GET SITE_ROOT/api/v1/checks/<unique_key>/flips/`
|
||||
|
||||
Returns a list of flips this check has experienced. A flip is a change of status (up, or down).
|
||||
|
||||
This endpoint returns the status of a check for the period of time passed according to the below parameters. If no parameters are passed, the default is to return flips occuring in the previous 3600 seconds (`/?seconds=3600`), which is the last hour.
|
||||
|
||||
### Query String Parameters
|
||||
|
||||
Either the seconds or the start (and end) parameters can be passed. Passing both the seconds parameter and the start/end parameters will return a 400 error (see below).
|
||||
|
||||
seconds=<value>
|
||||
: Filters the checks, and returns the flip history in the last `n` seconds
|
||||
|
||||
Example:
|
||||
|
||||
`SITE_ROOT/api/v1/checks/<uuid|unique_key>/flips/?seconds=3600`
|
||||
|
||||
start=<value>&end=<value>
|
||||
: Filters the checks, and returns the flip history between the start and end timestamps.
|
||||
|
||||
If provided, both values must be unix timestamps. The `end` parameter is optional and defaults to the timestamp of the current date and time.
|
||||
|
||||
Example:
|
||||
|
||||
`SITE_ROOT/api/v1/checks/<uuid|unique_key>/flips/?seconds=3600`
|
||||
|
||||
|
||||
### Response Codes
|
||||
|
||||
200 OK
|
||||
: The request succeeded.
|
||||
|
||||
400 Bad Request
|
||||
: Both a seconds and a start or end query string parameter has been passed, which is unsupported.
|
||||
|
||||
401 Unauthorized
|
||||
: The API key is either missing or invalid.
|
||||
|
||||
403 Forbidden
|
||||
: Access denied, wrong API key.
|
||||
|
||||
404 Not Found
|
||||
: The specified check does not exist.
|
||||
|
||||
### Example Request
|
||||
|
||||
```bash
|
||||
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/flips/ \
|
||||
--header "X-Api-Key: your-api-key"
|
||||
```
|
||||
|
||||
### Example Response
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "My First Check",
|
||||
"tags": "",
|
||||
"desc": "",
|
||||
"grace": 3600,
|
||||
"n_pings": 2,
|
||||
"status": "up",
|
||||
"last_ping": "2020-06-12T02:18:46+00:00",
|
||||
"next_ping": "2020-06-13T02:18:46+00:00",
|
||||
"manual_resume": false,
|
||||
"history": [
|
||||
{
|
||||
"timestamp": "2020-03-23T23:30:18.767Z",
|
||||
"up": 1
|
||||
}
|
||||
],
|
||||
"unique_key": "e855898bebff1756cde7c571319d877d07a38dab",
|
||||
"timeout": 86400
|
||||
}
|
||||
```
|
||||
|
||||
## Get a List of Existing Integrations {: #list-channels .rule }
|
||||
|
||||
`GET SITE_ROOT/api/v1/channels/`
|
||||
|
Loading…
x
Reference in New Issue
Block a user