raekkeri / django-requestlogs Goto Github PK
View Code? Open in Web Editor NEWdjango-requestlogs is a package providing middleware and other helpers for audit logging.
License: MIT License
django-requestlogs is a package providing middleware and other helpers for audit logging.
License: MIT License
Custom User model with no username field
it raises exception if i dont have username in my user model. I have custom user model with no username field
The default implementation of request serializer that uses JSONEncoder is incompatible with FileField/ImageField that are supported by default in rest_framework(500 UnicodeDecodeError is raised).
In my project I've made a workaround by replacing JsonDumpField as follows:
class JsonDumpField(serializers.Field):
def to_representation(self, value: QueryDict):
"""
JSONEncoder doesn't support binary files such as images etc.
Replace them with string 'File: <filename'
"""
for val in value.items():
if isinstance(val[1], InMemoryUploadedFile):
value.update({ val[0]: f"File: {val[1].name}" })
return json.dumps(value, cls=JSONEncoder)
The problem can be retrieved with the core functionality of rest_framework
, that's why I think it should be solved in the package, not individually in a project.
I have ViewSet with drf @action
class SomeView(BaseViewSet):
requestlogs_action_names = {
'list': "Receiving",
"some_action": "some event has occurred",
}
...
@action(
methods=["get"],
detail=True,
url_path="some-action",
url_name="some-action",
)
def some_action(self, request, *args, **kwargs):
some_logic(kwargs)
return response
I can't get action_name to log
Its my log:
{'action_name': None, ... , ('full_path', '/api/some-action/'), ...}
Since the output is for a log (display only), would it make better sense to change "IntegerField" to "CharField" in (storages.py)?
class UserSerializer(serializers.Serializer):
id = serializers.IntegerField()
username = serializers.CharField()
Please,
I'm new in Django and DRF
I want to know ho to logg all my message in a database table
Thank you in advance for your response
DOMGA
What do you all think about having a install procedure like:
pip install django-requestlogs[ipware]
which installs the optional dependency.
The project would still maintain the default way of installing pip install django-requestlogs
If desired, this should be as easy as adding
extras_require={"ipware": ["django-ipware"]}
to the setup.py.
Hey, really making great use of this package. Wanted to ask if this would get updated to support Django 4.
Thanks!
There are users for that I don't need to capture the requests.
Can we create a filter to ignore requests from certain users?
My idea is to create two new configurations:
DEFAULT_SETTINGS = {
...
'IGNORE_USER_FIELD': '',
'IGNORE_USERS': [],
}
My own configuration would look like this:
REQUESTLOGS = {
...
'IGNORE_USER_FIELD': 'username',
'IGNORE_USERS': ['username1', 'username2'],
}
or
REQUESTLOGS = {
...
'IGNORE_USER_FIELD': 'email',
'IGNORE_USERS': ['[email protected]', '[email protected]'],
}
and finalize()
method in RequestLogEntry class
do:
self.response = self.response_handler(response)
if SETTINGS['IGNORE_USER_FIELD']:
if (self.user.get(SETTINGS['IGNORE_USER_FIELD'], None) in SETTINGS['IGNORE_USERS']):
return None
self.store()
@Raekkeri, what do you think about this?
Hey! Just about to use this on a project of mine.
Is there a way to exclude paths?
For example, I want to exclude logging all /admin/*
requests.
I used custom MyEntrySerializer by extending BaseEntrySerializer bcz I was getting issue before (AttributeError: Got AttributeError when attempting to get a value for field user
on serializer BaseEntrySerializer
.
The serializer field might be named incorrectly and not match any attribute or key on the RequestLogEntry
instance.
Original exception text was: 'User' object has no attribute 'username'.), but now getting different issue "TypeError: 'str' object is not callable" , Details are below.
Traceback (most recent call last):
File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/requestlogs/middleware.py", line 20, in call
get_requestlog_entry(request).finalize(response)
File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/requestlogs/entries.py", line 96, in finalize
self.store()
File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/requestlogs/entries.py", line 100, in store
storage.store(self)
File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/requestlogs/storages.py", line 69, in store
logger.info(self.prepare(entry))
File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/requestlogs/storages.py", line 64, in prepare
return self.get_serializer_class()(entry).data
TypeError: 'str' object is not callable
please help to solve this one
With swagger enabled, the data property of ResponseHandler gets called when attempting to visit the generated documentation. However in this case, the data
is actually a Swagger
object, that is derived from dict. A copy of the object is attempted to be made, however with a Swagger object copy() appears to call __init__
of the Swagger class which fails with an error NoneType' object has no attribute '_default_version'
( See https://github.com/axnsan12/drf-yasg/blob/master/src/drf_yasg/openapi.py#L256 )
Pls fix.
Thank you for your work!
I have noticed, though, that django-ipware package is required for retrieving IP addresses in the logs. It might be helpful to mention that in the document.
There's also a typo here:
The feature is enabled by adding requestlogs.middleware.RequestLogsMiddleware to the MIDDLEWARE setting:
Should actually be
The feature is enabled by adding requestlogs.middleware.RequestIdMiddleware to the MIDDLEWARE setting:
After installing request logs, I started having an error in one of my tests. It was supposed to throw a 400 (BAD REQUEST) error, however, I received a 500 (internal server error). This was my test code:
def test_change_password_with_fake_json(self):
"""Error in password change with invalid JSON."""
auth_client_with_token(self)
response = self.client.post(
API_BASE_USERS_URL + str(self.user.id) + API_BASE_CHANGE_PASSWORD,
PASSWORD_CHANGE_FAIL,
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
The 500 came from the post
function. This was the traceback:
Traceback (most recent call last):
users/tests/test_endpoints.py line 119 in test_change_password_with_fake_json
PASSWORD_CHANGE_FAIL,
/usr/local/lib/python3.7/site-packages/rest_framework/test.py line 294 in post
path, data=data, format=format, content_type=content_type, **extra)
/usr/local/lib/python3.7/site-packages/rest_framework/test.py line 207 in post
return self.generic('POST', path, data, content_type, **extra)
/usr/local/lib/python3.7/site-packages/rest_framework/test.py line 232 in generic
method, path, data, content_type, secure, **extra)
/usr/local/lib/python3.7/site-packages/django/test/client.py line 421 in generic
return self.request(**r)
/usr/local/lib/python3.7/site-packages/rest_framework/test.py line 283 in request
return super().request(**kwargs)
/usr/local/lib/python3.7/site-packages/rest_framework/test.py line 235 in request
request = super().request(**kwargs)
/usr/local/lib/python3.7/site-packages/django/test/client.py line 496 in request
raise exc_value
/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py line 34 in inner
response = get_response(request)
/home/movisat/.local/lib/python3.7/site-packages/requestlogs/middleware.py line 17 in __call__
get_requestlog_entry(request).finalize(response)
/home/movisat/.local/lib/python3.7/site-packages/requestlogs/entries.py line 96 in finalize
self.store()
/home/movisat/.local/lib/python3.7/site-packages/requestlogs/entries.py line 100 in store
storage.store(self)
/home/movisat/.local/lib/python3.7/site-packages/requestlogs/storages.py line 62 in store
logger.info(self.prepare(entry))
/home/movisat/.local/lib/python3.7/site-packages/requestlogs/storages.py line 57 in prepare
return self.get_serializer_class()(entry).data
/usr/local/lib/python3.7/site-packages/rest_framework/serializers.py line 562 in data
ret = super().data
/usr/local/lib/python3.7/site-packages/rest_framework/serializers.py line 260 in data
self._data = self.to_representation(self.instance)
/usr/local/lib/python3.7/site-packages/rest_framework/serializers.py line 529 in to_representation
ret[field.field_name] = field.to_representation(attribute)
/usr/local/lib/python3.7/site-packages/rest_framework/serializers.py line 529 in to_representation
ret[field.field_name] = field.to_representation(attribute)
/home/movisat/.local/lib/python3.7/site-packages/requestlogs/storages.py line 14 in to_representation
return json.dumps(value)
/usr/local/lib/python3.7/json/__init__.py line 231 in dumps
return _default_encoder.encode(obj)
/usr/local/lib/python3.7/json/encoder.py line 199 in encode
chunks = self.iterencode(o, _one_shot=True)
/usr/local/lib/python3.7/json/encoder.py line 257 in iterencode
return _iterencode(o, 0)
/usr/local/lib/python3.7/json/encoder.py line 179 in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type __proxy__ is not JSON serializable
The error happened in the serializer, in the class JsonDumpField
when calling json.dumps(value)
. I solved it by overriding the serializer, but it could be solved just rewriting the class mentioned before, so I leave you my solution here in case you consider it appropriate to change it in the repo:
class JsonDumpField(serializers.Field):
def to_representation(self, value):
try:
json_obj = json.dumps(value)
except:
json_obj = json.dumps(str(value))
return json_obj
BTW, great job, very useful package!
Hello,
how to include a header in the request dictionary?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.