Package: px-django-actions-tracker
Actions tracking APIInstallationpipinstallpx-django-actions-trackerInsettings.py:INSTALLED_APPS+=['pxd_actions_tracker',# If wouldn't use database storage - do not add this application here:'pxd_actions_tracker.storages.db',]MIDDLEWARE=[# Tracking key generation middleware should be "as first as possible" in your# middlewares list. It generates base tracking code.'pxd_actions_tracker.middleware.tracking_middleware',*MIDDLEWARE,]# To configure tracker you my pass different values, instead of defaults here:PXD_ACTIONS_TRACKER={# Determines how to commit logs:'OPERATE':'straight',# 'straight' | 'threading'# Method that used to save data.'SAVER':'pxd_actions_tracker.storages.db.storage.save',# Set of fields that should be replaced with a placeholder:'SENSITIVE_FIELDS':{'api','token','key','secret','password','signature','authorization',},# Placeholder to replace sensitive data with.'SENSITIVE_PLACEHOLDER':'*******',}UsageRequests trackingWe have a builtin tracker for pythonrequestslibrary. As it is a commonly-used way to do something using http.importrequestsfrompxd_actions_tracker.trackersimporttrack_requestsfrom..constimportDOMAIN# It returns response object and newly created log identifier.response,log_id=track_requests.track(# Any domain for request "tagging".DOMAIN|'SOME-URL-REQUEST',# Resolver function that returns a `requests` library response instance.lambda:requests.post(url,json={},allow_redirects=True),# Additional arguments for passed resolvers:args=(),# Additional keyword arguments for passed resolvers:kwargs={},# Message formatter function:message_format=track_requests.MESSAGE_FORMAT,# Resolver whether this response should be tracked or not:# Be default it's logging only if response is not 200.should_track=track_requests.should_track_non_200,# There is also a built in checker to log every request:should_track=track_requests.should_track_all,# Function that parses response into a saved `detail` dict.# You may replace it to save additional info or decrease that information.detail_resolver=track_requests.resolve_log_detail,)Django view trackerThere are three ways of handling django views:1. Most "low-level":trackIt can be used manually whenever you need. But with a small cost of additional "handling" code.importrequestsfrompxd_actions_tracker.trackersimporttrack_viewsfrom..constimportDOMAIN# It returns log identifier.log_id=track_views.track(# Any domain for request "tagging".DOMAIN|'SOME-REQUEST',# Django's request.request,# Django's response. Optional.response=response,# Exception, if occurred.error=NoneorException(),# Additional arguments for passed resolvers:args=(),# Additional keyword arguments for passed resolvers:kwargs={},# Message formatter function:message_format=track_views.MESSAGE_FORMAT,# Resolver whether this action should be tracked or not:# Be default it's logging only if response is not 200. And no `error` passed.should_track=track_views.should_track_non_200,# There is also a built in checker to log every request:should_track=track_views.should_track_all,# Function that parses response into a saved `detail` dict.# You may replace it to save additional info or decrease that information.detail_resolver=track_views.resolve_log_detail,)Or without additional boilerplate code you may track is astrack_requests.trackmechanics with response resolver:# It returns log identifier.response,log_id=track_views.track_middleware(# Any domain for request "tagging".DOMAIN|'SOME-REQUEST',# Response resolver. It can be a view function, for example.lambdarequest,*a,**k:HttpResponse(''),# Django's request.request,# Other tracking function(for example with `partial` parameters).tracker=track_views.track,# Additional arguments for passed resolvers:args=(),# Additional keyword arguments for passed resolvers:kwargs={},)2. Decorator:decorateJust a view function decorator:@track_views.decorate(# Any domain for view "tagging".DOMAIN|'SOME-VIEW',# Other tracking function(for example with `partial` parameters).tracker=track_views.track,)defview(request:HttpRequest):returnHttpResponse('')3. Middleware factory:create_middlewareOr you may just create a middleware that will handle all your views:frompx_domainsimportDomainview_request_logger_middleware=track_views.create_middleware(# Base domain for a tracked viewsDomain('VIEW'),# Other tracking function(for example with `partial` parameters).tracker=track_views.track,)And insettings.py:MIDDLEWARE=[*MIDDLEWARE,'your_app.middleware.view_request_logger_middleware',]Tracking loggerThere is also a built in logging class to track any log messages you need:LOGGING={'version':1,'disable_existing_loggers':False,'handlers':{# Adding handler class, for example for error logging:'actions_tracker':{'level':'ERROR','class':'pxd_actions_tracker.trackers.track_logs.ActionsTrackerHandler',},},'root':{'handlers':['actions_tracker'],'level':'DEBUG',},}Tracking codesYou may add additional tracking codes to understand better what user used to do before/after.frompxd_actions_tracker.casesimporttrack,uuid_trackwithtrack('TRACKING-CODE'):do_something()# Same track but with uuid code:withuuid_track():do_something()Signals# General# Fires when new log entry created.pxd_actions_tracker.signals.log_created# Fires when new tracking code added to a stack.pxd_actions_tracker.signals.tracking_enter# Fires when new tracking code removed from a stack.pxd_actions_tracker.signals.tracking_exit# DB storage# Fires when new log entry stored in database.pxd_actions_tracker.storages.db.signals.log_storedChangelogAll notable changes to this project will be documented in this file.The format is based onKeep a Changelog,
and this project adheres toSemantic Versioning.[Unreleased][0.1.7]AddedDomain filtering.[0.1.6]FixedTracking middleware log_id return issue.[0.1.5]FixedPython 3.7lru_cachecompatibility with.[0.1.4]FixedRequest data gathering issue onRawPostDataExceptionexception.[0.1.3]FixedAdmincreated atfield localization formatting.[0.1.2]AddedLogging handler class.FixedViews tracker fixes.[0.1.0]Initial version.