diff options
author | Andy Doan <andy.doan@linaro.org> | 2014-08-04 17:03:35 +0000 |
---|---|---|
committer | Andy Doan <andy.doan@linaro.org> | 2014-08-04 17:03:35 +0000 |
commit | f5ae8b3f13c6f57a0f7055e05f025a9d2a758046 (patch) | |
tree | 666a6a22bafd7ca7f8f3d4427a02107c4ce35e6e | |
parent | 65948f3d3a70e9384d20f369beb2329c9dd8f250 (diff) |
API: log usage metrics2014.07.1
We are about to be making some changes to our API. It would be
helpful to better understand how its being used. This adds a simple
mechanism to help us track usage of the API.
The metrics are logged in the format:
<timestamp>: <remote ip>: <stat name>: <fields (optional)>
Example output:
1407170717.06: 127.0.0.1: REQUEST_KEY:
1407171070.57: 127.0.0.1: INVALID_KEY:
1407171191.78: 127.0.0.1: INVALID_API_FORM:
1407171348.14: 127.0.0.1: FILE_UPLOAD: foo_path,False,45d2f5af78194bbfd
Change-Id: I034e6a9a6e502a76d1f0a48346ad92ebe6c6121a
-rw-r--r-- | license_protected_downloads/uploads.py | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/license_protected_downloads/uploads.py b/license_protected_downloads/uploads.py index 419ce3e..3bf6f67 100644 --- a/license_protected_downloads/uploads.py +++ b/license_protected_downloads/uploads.py @@ -1,6 +1,9 @@ +import io +import fcntl import os import random import shutil +import time from django.views.decorators.csrf import csrf_exempt from django.http import ( @@ -15,6 +18,30 @@ from models import APIKeyStore from common import safe_path_join +def _client_ip(request): + x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') + if x_forwarded_for: + return x_forwarded_for.split(',')[0] + return request.META.get('REMOTE_ADDR') + + +def _log_metric(request, name, fields=None): + """Store information on a given API call. + + This allows us to get some understanding of how this API is being used. + """ + with open('/tmp/llp-stats.txt', 'a') as f: + try: + fcntl.flock(f, fcntl.LOCK_EX) + f.seek(0, io.SEEK_END) + f.write('%s: %s: %s: ' % (time.time(), _client_ip(request), name)) + if fields is not None: + f.write(','.join(fields)) + f.write('\n') + finally: + fcntl.flock(f, fcntl.LOCK_UN) + + class UploadFileForm(forms.Form): file = forms.FileField() @@ -44,14 +71,19 @@ def file_server_post(request, path): """ if not ("key" in request.POST and APIKeyStore.objects.filter(key=request.POST["key"])): + _log_metric(request, 'INVALID_KEY') return HttpResponseServerError("Invalid key") api_key = APIKeyStore.objects.filter(key=request.POST["key"]) form = UploadFileForm(request.POST, request.FILES) if not form.is_valid() or not path: + _log_metric(request, 'INVALID_API_FORM') return HttpResponseServerError("Invalid call") + _log_metric(request, 'FILE_UPLOAD', + [path, str(api_key[0].public), request.POST['key']]) + path = upload_target_path( path, request.POST["key"], public=api_key[0].public) @@ -68,6 +100,7 @@ def file_server_post(request, path): def api_request_key(request): + _log_metric(request, 'REQUEST_KEY') if("key" in request.GET and request.GET["key"] == settings.MASTER_API_KEY and settings.MASTER_API_KEY): @@ -93,6 +126,7 @@ def api_request_key(request): def api_delete_key(request): + _log_metric(request, 'DELETE_KEY') if "key" not in request.GET: return HttpResponseServerError("Invalid key") |