Actions tracking API
Installation
pip install px-django-actions-tracker
In settings.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': '*******',
}
Usage
Requests tracking
We have a builtin tracker for python requests library. As it is a commonly-used way to do something using http.
import requests
from pxd_actions_tracker.trackers import track_requests
from ..const import DOMAIN
# 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 tracker
There are three ways of handling django views:
1. Most "low-level": track
It can be used manually whenever you need. But with a small cost of additional "handling" code.
import requests
from pxd_actions_tracker.trackers import track_views
from ..const import DOMAIN
# 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=None or Exception(),
# 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 as track_requests.track mechanics 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.
lambda request, *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: decorate
Just 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,
)
def view(request: HttpRequest):
return HttpResponse('')
3. Middleware factory: create_middleware
Or you may just create a middleware that will handle all your views:
from px_domains import Domain
view_request_logger_middleware = track_views.create_middleware(
# Base domain for a tracked views
Domain('VIEW'),
# Other tracking function(for example with `partial` parameters).
tracker=track_views.track,
)
And in settings.py:
MIDDLEWARE = [
*MIDDLEWARE,
'your_app.middleware.view_request_logger_middleware',
]
Tracking logger
There 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 codes
You may add additional tracking codes to understand better what user used to do before/after.
from pxd_actions_tracker.cases import track, uuid_track
with track('TRACKING-CODE'):
do_something()
# Same track but with uuid code:
with uuid_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_stored
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
[0.1.10]
Fixed
- Logger message formatting issue.
[0.1.9]
Fixed
- Request body logging for DRF views.
[0.1.7]
Added
- Domain filtering.
[0.1.6]
Fixed
- Tracking middleware log_id return issue.
[0.1.5]
Fixed
- Python 3.7
lru_cachecompatibility with.
[0.1.4]
Fixed
- Request data gathering issue on
RawPostDataExceptionexception.
[0.1.3]
Fixed
- Admin
created atfield localization formatting.
[0.1.2]
Added
- Logging handler class.
Fixed
- Views tracker fixes.
[0.1.0]
Initial version.
Metadata
Release files for px-django-actions-tracker 0.1.10
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| px_django_actions_tracker-0.1.10.tar.gz | 13.9 kB | Without provenance | Details |
Release files / px_django_actions_tracker-0.1.10.tar.gz
| Download URL | px_django_actions_tracker-0.1.10.tar.gz |
|---|---|
| Size | 13.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
82980b725e1de3fdcb634efe3f79122dad9a6680b2f3c13d12c2940cc07c2907
|
|
BLAKE2b-256 checksum How to use checksums |
6b579303919f60b67f8fa0d335746846adde0fc81f01518aaaa9a5a1911ddf5b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.8
|
Security for px-django-actions-tracker 0.1.10
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.