diff options
author | Andy Doan <andy.doan@linaro.org> | 2014-08-14 12:13:08 -0500 |
---|---|---|
committer | Andy Doan <andy.doan@linaro.org> | 2014-08-14 12:13:08 -0500 |
commit | 90f47509f9eefae9c1ba8e2530dabaeab1a4eaa7 (patch) | |
tree | 892fc79da93683b72c4b0ba31acdd701d7626ed3 | |
parent | aee10219ef8f551344beda7acbc3757d5a08337a (diff) |
api: make metric logging more robust
The old method required too much manual intervention to prevent log
files from growing too large. This makes the API cleaner and allows
it to rotate logs on its own.
Change-Id: Ib7dd9dd17b748cf2fed7b186bcd84c661ee552e5
-rw-r--r-- | license_protected_downloads/models.py | 16 | ||||
-rw-r--r-- | license_protected_downloads/uploads.py | 47 |
2 files changed, 25 insertions, 38 deletions
diff --git a/license_protected_downloads/models.py b/license_protected_downloads/models.py index 35ac098..22f61ca 100644 --- a/license_protected_downloads/models.py +++ b/license_protected_downloads/models.py @@ -31,3 +31,19 @@ class License(models.Model): class APIKeyStore(models.Model): key = models.CharField(max_length=80) public = models.BooleanField() + + +class APILog(models.Model): + timestamp = models.DateTimeField(auto_now_add=True) + # we are on an old version of django missing an ipv6 friendly field + # so just use a charfield to keep it simple + ip = models.CharField(max_length=40) + key = models.ForeignKey(APIKeyStore, blank=True, null=True) + label = models.CharField(max_length=32) + path = models.CharField(max_length=256) + + @staticmethod + def mark(request, label, key=None): + ip = request.META.get('REMOTE_ADDR') + ip = request.META.get('HTTP_X_FORWARDED_FOR', ip).split(',')[0] + APILog.objects.create(label=label, ip=ip, path=request.path, key=key) diff --git a/license_protected_downloads/uploads.py b/license_protected_downloads/uploads.py index b04c791..5cc6fa1 100644 --- a/license_protected_downloads/uploads.py +++ b/license_protected_downloads/uploads.py @@ -1,9 +1,6 @@ -import io -import fcntl import os import random import shutil -import time from django.views.decorators.csrf import csrf_exempt from django.http import ( @@ -13,32 +10,8 @@ from django.http import ( ) from django.conf import settings -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) +from license_protected_downloads.models import APIKeyStore, APILog +from license_protected_downloads.common import safe_path_join def upload_target_path(path, key, public): @@ -66,21 +39,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', [path]) + APILog.mark(request, 'INVALID_KEY') return HttpResponseServerError("Invalid key") - api_key = APIKeyStore.objects.filter(key=request.POST["key"]) + api_key = APIKeyStore.objects.get(key=request.POST["key"]) if 'file' not in request.FILES or not path: - _log_metric(request, 'INVALID_ARGUMENTS', - [str(request.FILES.keys()), path, request.POST['key']]) + APILog.mark(request, 'INVALID_ARGUMENTS', api_key) return HttpResponseServerError("Invalid call") - _log_metric(request, 'FILE_UPLOAD', - [path, str(api_key[0].public), request.POST['key']]) + APILog.mark(request, 'FILE_UPLOAD', api_key) path = upload_target_path( - path, request.POST["key"], public=api_key[0].public) + path, request.POST["key"], public=api_key.public) # Create directory if required dirname = os.path.dirname(path) @@ -95,7 +66,7 @@ def file_server_post(request, path): def api_request_key(request): - _log_metric(request, 'REQUEST_KEY') + APILog.mark(request, 'REQUEST_KEY') if("key" in request.GET and request.GET["key"] == settings.MASTER_API_KEY and settings.MASTER_API_KEY): @@ -121,7 +92,7 @@ def api_request_key(request): def api_delete_key(request): - _log_metric(request, 'DELETE_KEY') + APILog.mark(request, 'DELETE_KEY') if "key" not in request.GET: return HttpResponseServerError("Invalid key") |