Example #1
0
def user_track(request):
    """
    Log when POST call to "event" URL is made by a user.

    GET or POST call should provide "event_type", "event", and "page" arguments. It may optionally provide
    a "courserun_key" argument (otherwise may be extracted from the page).
    """
    try:
        username = request.user.username
    except:  # lint-amnesty, pylint: disable=bare-except
        username = "******"

    name = _get_request_value(request, 'event_type')
    data = _get_request_value(request, 'event', {})
    course_id_string = _get_request_value(request, 'courserun_key', None)
    page = _get_request_value(request, 'page')

    if isinstance(data, str) and len(data) > 0:
        try:
            data = json.loads(data)
            _add_user_id_for_username(data)
        except ValueError:
            pass

    context_override = contexts.course_context_from_url(page, course_id_string)
    context_override['username'] = username
    context_override['event_source'] = 'browser'
    context_override['page'] = page

    with eventtracker.get_tracker().context('edx.course.browser',
                                            context_override):
        eventtracker.emit(name=name, data=data)

    return HttpResponse('success')
Example #2
0
 def assert_parses_course_id_from_url(self, format_string, course_id):
     self.assertEqual(
         contexts.course_context_from_url(
             format_string.format(course_id=course_id)), {
                 'course_id': course_id,
                 'org_id': self.ORG_ID
             })
Example #3
0
def user_track(request):
    """
    Log when POST call to "event" URL is made by a user.

    GET or POST call should provide "event_type", "event", and "page" arguments.
    """
    try:
        username = request.user.username
    except:
        username = "******"

    name = _get_request_value(request, 'event_type')
    data = _get_request_value(request, 'event', {})
    page = _get_request_value(request, 'page')

    if isinstance(data, six.string_types) and len(data) > 0:
        try:
            data = json.loads(data)
            _add_user_id_for_username(data)
        except ValueError:
            pass

    context_override = contexts.course_context_from_url(page)
    context_override['username'] = username
    context_override['event_source'] = 'browser'
    context_override['page'] = page

    with eventtracker.get_tracker().context('edx.course.browser',
                                            context_override):
        eventtracker.emit(name=name, data=data)

    return HttpResponse('success')
Example #4
0
def _get_course_context(page):
    """Return the course context from the provided page.

    If the context has no/empty course_id, return empty context
    """
    course_context = contexts.course_context_from_url(page)
    if course_context.get('course_id', '') == '':
        course_context = {}

    return course_context
Example #5
0
    def enter_request_context(self, request):
        """
        Extract information from the request and add it to the tracking
        context.

        The following fields are injected into the context:

        * session - The Django session key that identifies the user's session.
        * user_id - The numeric ID for the logged in user.
        * username - The username of the logged in user.
        * ip - The IP address of the client.
        * host - The "SERVER_NAME" header, which should be the name of the server running this code.
        * agent - The client browser identification string.
        * path - The path part of the requested URL.
        * client_id - The unique key used by Google Analytics to identify a user
        """
        context = {
            'session': self.get_session_key(request),
            'user_id': self.get_user_primary_key(request),
            'username': self.get_username(request),
            'ip': self.get_request_ip_address(request),
        }
        for header_name, context_key in six.iteritems(META_KEY_TO_CONTEXT_KEY):
            # HTTP headers may contain Latin1 characters. Decoding using Latin1 encoding here
            # avoids encountering UnicodeDecodeError exceptions when these header strings are
            # output to tracking logs.
            context_value = request.META.get(header_name, '')
            if isinstance(context_value, six.binary_type):
                context_value = context_value.decode('latin1')
            context[context_key] = context_value

        # Google Analytics uses the clientId to keep track of unique visitors. A GA cookie looks like
        # this: _ga=GA1.2.1033501218.1368477899. The clientId is this part: 1033501218.1368477899.
        google_analytics_cookie = request.COOKIES.get('_ga')
        if google_analytics_cookie is None:
            context['client_id'] = request.META.get('HTTP_X_EDX_GA_CLIENT_ID')
        else:
            context['client_id'] = '.'.join(google_analytics_cookie.split('.')[2:])

        context.update(contexts.course_context_from_url(request.build_absolute_uri()))

        tracker.get_tracker().enter_context(
            CONTEXT_NAME,
            context
        )
Example #6
0
def task_track(request_info, task_info, event_type, event, page=None):
    """
    Logs tracking information for events occuring within celery tasks.

    The `event_type` is a string naming the particular event being logged,
    while `event` is a dict containing whatever additional contextual information
    is desired.

    The `request_info` is a dict containing information about the original
    task request.  Relevant keys are `username`, `ip`, `agent`, and `host`.
    While the dict is required, the values in it are not, so that {} can be
    passed in.

    In addition, a `task_info` dict provides more information about the current
    task, to be stored with the `event` dict.  This may also be an empty dict.

    The `page` parameter is optional, and allows the name of the page to
    be provided.
    """

    # supplement event information with additional information
    # about the task in which it is running.
    data = dict(event, **task_info)

    context_override = contexts.course_context_from_url(page)
    context_override.update({
        'username': request_info.get('username', 'unknown'),
        'ip': request_info.get('ip', 'unknown'),
        'agent': request_info.get('agent', 'unknown'),
        'host': request_info.get('host', 'unknown'),
        'event_source': 'task',
        'page': page,
    })

    with eventtracker.get_tracker().context('edx.course.task',
                                            context_override):
        eventtracker.emit(name=event_type, data=data)
Example #7
0
 def assert_empty_context_for_url(self, url):
     assert contexts.course_context_from_url(url) == {
         'course_id': '',
         'org_id': '',
         'enterprise_uuid': ''
     }
Example #8
0
 def assert_parses_course_id_from_url(self, format_string, course_id):
     assert contexts.course_context_from_url(format_string.format(course_id=course_id)) ==\
            {'course_id': course_id, 'org_id': self.ORG_ID, 'enterprise_uuid': ''}
Example #9
0
 def assert_parses_explicit_course_id(self, url, course_id):
     assert contexts.course_context_from_url(url, course_id_string=course_id) ==\
            {'course_id': course_id, 'org_id': self.ORG_ID, 'enterprise_uuid': ''}
Example #10
0
 def assert_empty_context_for_url(self, url):
     self.assertEqual(contexts.course_context_from_url(url), {
         'course_id': '',
         'org_id': ''
     })