Use datetime objects in time field in event tracking
This commit is contained in:
@@ -11,8 +11,6 @@ from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
|
||||
import dateutil
|
||||
|
||||
from django.db import models
|
||||
|
||||
from track.backends import BaseBackend
|
||||
@@ -77,7 +75,6 @@ class DjangoBackend(BaseBackend):
|
||||
self.name = name
|
||||
|
||||
def send(self, event):
|
||||
event['time'] = dateutil.parser.parse(event['time'])
|
||||
field_values = {x: event.get(x, '') for x in LOGFIELDS}
|
||||
tldat = TrackingLog(**field_values)
|
||||
try:
|
||||
|
||||
@@ -8,7 +8,7 @@ import json
|
||||
from django.conf import settings
|
||||
|
||||
from track.backends import BaseBackend
|
||||
|
||||
from track.utils import DateTimeJSONEncoder
|
||||
|
||||
log = logging.getLogger('track.backends.logger')
|
||||
|
||||
@@ -33,7 +33,7 @@ class LoggerBackend(BaseBackend):
|
||||
self.event_logger = logging.getLogger(name)
|
||||
|
||||
def send(self, event):
|
||||
event_str = json.dumps(event)
|
||||
event_str = json.dumps(event, default=DateTimeJSONEncoder)
|
||||
|
||||
# TODO: remove trucation of the serialized event, either at a
|
||||
# higher level during the emittion of the event, or by
|
||||
|
||||
37
common/djangoapps/track/tests/test_util.py
Normal file
37
common/djangoapps/track/tests/test_util.py
Normal file
@@ -0,0 +1,37 @@
|
||||
from datetime import datetime
|
||||
import json
|
||||
|
||||
from pytz import UTC
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from track.utils import DateTimeJSONEncoder
|
||||
|
||||
|
||||
class TestDateTimeJSONEncoder(TestCase):
|
||||
def test_datetime_encoding(self):
|
||||
a_naive_datetime = datetime(2012, 05, 01, 07, 27, 10, 20000)
|
||||
a_tz_datetime = datetime(2012, 05, 01, 07, 27, 10, 20000, tzinfo=UTC)
|
||||
a_date = a_naive_datetime.date()
|
||||
an_iso_datetime = '2012-05-01T07:27:10.020000+00:00'
|
||||
an_iso_date = '2012-05-01'
|
||||
|
||||
obj = {
|
||||
'number': 100,
|
||||
'string': 'hello',
|
||||
'object': {'a': 1},
|
||||
'a_datetime': a_naive_datetime,
|
||||
'a_tz_datetime': a_tz_datetime,
|
||||
'a_date': a_date,
|
||||
}
|
||||
|
||||
to_json = json.dumps(obj, cls=DateTimeJSONEncoder)
|
||||
from_json = json.loads(to_json)
|
||||
|
||||
self.assertEqual(from_json['number'], 100)
|
||||
self.assertEqual(from_json['string'], 'hello')
|
||||
self.assertEqual(from_json['object'], {'a': 1})
|
||||
|
||||
self.assertEqual(from_json['a_datetime'], an_iso_datetime)
|
||||
self.assertEqual(from_json['a_tz_datetime'], an_iso_datetime)
|
||||
self.assertEqual(from_json['a_date'], an_iso_date)
|
||||
30
common/djangoapps/track/utils.py
Normal file
30
common/djangoapps/track/utils.py
Normal file
@@ -0,0 +1,30 @@
|
||||
"""Utility functions and classes for track backends"""
|
||||
|
||||
from datetime import datetime, date
|
||||
import json
|
||||
|
||||
from pytz import UTC
|
||||
|
||||
|
||||
class DateTimeJSONEncoder(json.JSONEncoder):
|
||||
"""JSON encoder aware of datetime.datetime and datetime.date objects"""
|
||||
|
||||
def default(self, obj): # pylint: disable=method-hidden
|
||||
"""
|
||||
Serialize datetime and date objects of iso format.
|
||||
|
||||
datatime objects are converted to UTC.
|
||||
"""
|
||||
|
||||
if isinstance(obj, datetime):
|
||||
if obj.tzinfo is None:
|
||||
# Localize to UTC naive datetime objects
|
||||
obj = UTC.localize(obj)
|
||||
else:
|
||||
# Convert to UTC datetime objects from other timezones
|
||||
obj = obj.astimezone(UTC)
|
||||
return obj.isoformat()
|
||||
elif isinstance(obj, date):
|
||||
return obj.isoformat()
|
||||
|
||||
return super(DateTimeJSONEncoder, self).default(obj)
|
||||
@@ -1,15 +1,11 @@
|
||||
import json
|
||||
import logging
|
||||
import datetime
|
||||
|
||||
import dateutil.parser
|
||||
import pytz
|
||||
from pytz import UTC
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import redirect
|
||||
from django.conf import settings
|
||||
|
||||
from django_future.csrf import ensure_csrf_cookie
|
||||
|
||||
@@ -56,7 +52,7 @@ def user_track(request):
|
||||
"event": request.REQUEST['event'],
|
||||
"agent": agent,
|
||||
"page": request.REQUEST['page'],
|
||||
"time": datetime.datetime.now(UTC).isoformat(),
|
||||
"time": datetime.datetime.now(UTC),
|
||||
"host": request.META['SERVER_NAME'],
|
||||
}
|
||||
|
||||
@@ -85,7 +81,7 @@ def server_track(request, event_type, event, page=None):
|
||||
"event": event,
|
||||
"agent": agent,
|
||||
"page": page,
|
||||
"time": datetime.datetime.now(UTC).isoformat(),
|
||||
"time": datetime.datetime.now(UTC),
|
||||
"host": request.META['SERVER_NAME'],
|
||||
}
|
||||
|
||||
@@ -130,7 +126,7 @@ def task_track(request_info, task_info, event_type, event, page=None):
|
||||
"event": full_event,
|
||||
"agent": request_info.get('agent', 'unknown'),
|
||||
"page": page,
|
||||
"time": datetime.datetime.utcnow().isoformat(),
|
||||
"time": datetime.datetime.now(UTC),
|
||||
"host": request_info.get('host', 'unknown')
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user