Merge pull request #13695 from edx/common_cleanup/audit_log
Move audit_log utility function to openedx/core
This commit is contained in:
@@ -9,7 +9,7 @@ from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.utils.decorators import method_decorator
|
||||
from opaque_keys import InvalidKeyError
|
||||
from course_modes.models import CourseMode
|
||||
from lms.djangoapps.commerce.utils import audit_log
|
||||
from openedx.core.lib.log_utils import audit_log
|
||||
from openedx.core.djangoapps.user_api.preferences.api import update_email_opt_in
|
||||
from openedx.core.lib.api.permissions import ApiKeyHeaderPermission, ApiKeyHeaderPermissionIsAuthenticated
|
||||
from rest_framework import status
|
||||
|
||||
@@ -13,7 +13,6 @@ from rest_framework.views import APIView
|
||||
from commerce.constants import Messages
|
||||
from commerce.exceptions import InvalidResponseError
|
||||
from commerce.http import DetailResponse, InternalRequestErrorResponse
|
||||
from commerce.utils import audit_log
|
||||
from course_modes.models import CourseMode
|
||||
from courseware import courses
|
||||
from embargo import api as embargo_api
|
||||
@@ -22,6 +21,7 @@ from enrollment.views import EnrollmentCrossDomainSessionAuth
|
||||
from openedx.core.djangoapps.commerce.utils import ecommerce_api_client
|
||||
from openedx.core.djangoapps.user_api.preferences.api import update_email_opt_in
|
||||
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
|
||||
from openedx.core.lib.log_utils import audit_log
|
||||
from student.models import CourseEnrollment
|
||||
from util.json_request import JsonResponse
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
"""Tests of commerce utilities."""
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
from django.test.utils import override_settings
|
||||
from mock import patch
|
||||
|
||||
from commerce.utils import audit_log, EcommerceService
|
||||
from commerce.models import CommerceConfiguration
|
||||
from django.test.client import RequestFactory
|
||||
from commerce.utils import EcommerceService
|
||||
from openedx.core.lib.log_utils import audit_log
|
||||
from student.tests.factories import UserFactory
|
||||
|
||||
|
||||
@@ -19,7 +20,7 @@ def update_commerce_config(enabled=False, checkout_page='/test_basket/'):
|
||||
|
||||
class AuditLogTests(TestCase):
|
||||
"""Tests of the commerce audit logging helper."""
|
||||
@patch('commerce.utils.log')
|
||||
@patch('openedx.core.lib.log_utils.log')
|
||||
def test_log_message(self, mock_log):
|
||||
"""Verify that log messages are constructed correctly."""
|
||||
audit_log('foo', qux='quux', bar='baz')
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
"""Utilities to assist with commerce tasks."""
|
||||
import logging
|
||||
from urlparse import urljoin
|
||||
|
||||
from django.conf import settings
|
||||
@@ -7,37 +6,6 @@ from django.conf import settings
|
||||
from commerce.models import CommerceConfiguration
|
||||
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def audit_log(name, **kwargs):
|
||||
"""DRY helper used to emit an INFO-level log message.
|
||||
|
||||
Messages logged with this function are used to construct an audit trail. Log messages
|
||||
should be emitted immediately after the event they correspond to has occurred and, if
|
||||
applicable, after the database has been updated. These log messages use a verbose
|
||||
key-value pair syntax to make it easier to extract fields when parsing the application's
|
||||
logs.
|
||||
|
||||
This function is variadic, accepting a variable number of keyword arguments.
|
||||
|
||||
Arguments:
|
||||
name (str): The name of the message to log. For example, 'payment_received'.
|
||||
|
||||
Keyword Arguments:
|
||||
Indefinite. Keyword arguments are strung together as comma-separated key-value
|
||||
pairs ordered alphabetically by key in the resulting log message.
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
# Joins sorted keyword argument keys and values with an "=", wraps each value
|
||||
# in quotes, and separates each pair with a comma and a space.
|
||||
payload = u', '.join(['{k}="{v}"'.format(k=k, v=v) for k, v in sorted(kwargs.items())])
|
||||
message = u'{name}: {payload}'.format(name=name, payload=payload)
|
||||
|
||||
log.info(message)
|
||||
|
||||
|
||||
class EcommerceService(object):
|
||||
""" Helper class for ecommerce service integration. """
|
||||
|
||||
@@ -30,7 +30,7 @@ from eventtracking import tracker
|
||||
from opaque_keys import InvalidKeyError
|
||||
from opaque_keys.edx.keys import CourseKey, UsageKey
|
||||
|
||||
from commerce.utils import audit_log, EcommerceService
|
||||
from commerce.utils import EcommerceService
|
||||
from course_modes.models import CourseMode
|
||||
from courseware.url_helpers import get_redirect_url
|
||||
from edx_rest_api_client.exceptions import SlumberBaseException
|
||||
@@ -42,6 +42,7 @@ from openedx.core.djangoapps.user_api.accounts.api import update_account_setting
|
||||
from openedx.core.djangoapps.user_api.errors import UserNotFound, AccountValidationError
|
||||
from openedx.core.djangoapps.credit.api import set_credit_requirement_status
|
||||
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
|
||||
from openedx.core.lib.log_utils import audit_log
|
||||
from student.models import CourseEnrollment
|
||||
from shoppingcart.models import Order, CertificateItem
|
||||
from shoppingcart.processors import (
|
||||
|
||||
36
openedx/core/lib/log_utils.py
Normal file
36
openedx/core/lib/log_utils.py
Normal file
@@ -0,0 +1,36 @@
|
||||
"""
|
||||
Helper functions for logging.
|
||||
"""
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def audit_log(name, **kwargs):
|
||||
"""
|
||||
DRY helper used to emit an INFO-level log message.
|
||||
|
||||
Messages logged with this function are used to construct an audit trail. Log messages
|
||||
should be emitted immediately after the event they correspond to has occurred and, if
|
||||
applicable, after the database has been updated. These log messages use a verbose
|
||||
key-value pair syntax to make it easier to extract fields when parsing the application's
|
||||
logs.
|
||||
|
||||
This function is variadic, accepting a variable number of keyword arguments.
|
||||
|
||||
Arguments:
|
||||
name (str): The name of the message to log. For example, 'payment_received'.
|
||||
|
||||
Keyword Arguments:
|
||||
Indefinite. Keyword arguments are strung together as comma-separated key-value
|
||||
pairs ordered alphabetically by key in the resulting log message.
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
# Joins sorted keyword argument keys and values with an "=", wraps each value
|
||||
# in quotes, and separates each pair with a comma and a space.
|
||||
payload = u', '.join(['{k}="{v}"'.format(k=k, v=v) for k, v in sorted(kwargs.items())])
|
||||
message = u'{name}: {payload}'.format(name=name, payload=payload)
|
||||
|
||||
log.info(message)
|
||||
Reference in New Issue
Block a user