django和django rest框架的审计日志
django-requestlogs的Python项目详细描述
django请求日志
django requestlogs是一个为审计日志提供中间件和其他帮助程序的包。 中间件将有关请求-响应周期的信息收集到日志条目中。这个 收集的信息可以完全定制,但是开箱即用的实现 包括
- 用户ID和用户名
- 请求(路径、方法、负载..)
- 响应(状态代码,有效载荷..)
- 一般信息,如时间戳、执行时间
最后,日志条目存储在预定义的存储中,默认情况下,该存储是可配置的 使用Django的日志系统。
一旦安装,日志存储应该开始显示如下条目:
{'action_name': None, 'execution_time': '00:00:00.024900', 'timestamp': '2019-07-01T07:05:34.217703Z', 'ip_address': None, 'request': OrderedDict([('method', 'GET'), ('full_path', '/'), ('data', '{}'), ('query_params', '{}')]), 'response': OrderedDict([('status_code', 200), ('data', '{"ok": true}')]), 'user': OrderedDict([('id', 1), ('username', 'admin')])}
动机
django requestlogs试图提供实现审计日志记录(审计跟踪)的工具 对于需要这种功能的系统。这些系统通常必须能够 告诉"终端用户访问了哪些信息(以及哪些信息被发送到 系统?.django requestlogs以最简单的方式钩住django rest框架 在记录每个请求时不需要记住启用它的方法 分别查看每个视图。
目前django requestlogs包主要关注与 django rest框架。虽然也收集了普通的django请求,但是它们的请求和 例如,没有存储响应有效载荷。
要求
- Django(1.11、2.0、2.1、2.2)
- django rest框架
可选依赖项:
- Django软件
- 如果已安装,则用于存储最终用户的IP地址
安装
使用pip安装
pip install django-requestlogs
将"requestLogs.middleware.requestLogsMiddleware"添加到"middleware"设置中。
MIDDLEWARE=[...'requestlogs.middleware.RequestLogsMiddleware',]
将"requestlogs.views.exception\u handler"设置为rest\u框架的异常处理程序 (这将确保requestlog条目具有关于 500错误时的请求:
REST_FRAMEWORK={...'EXCEPTION_HANDLER':'requestlogs.views.exception_handler',}
中间件现在可以开始使用默认的
存储类
,实际上它只是使用名为requestlogs
的python记录器。现在你可以,
例如,将这些日志重定向到具有以下配置的文件:
LOGGING={'version':1,'disable_existing_loggers':False,'handlers':{'requestlogs_to_file':{'level':'INFO','class':'logging.FileHandler','filename':'/tmp/requestlogs.log',},},'loggers':{'requestlogs':{'handlers':['requestlogs_to_file'],'level':'INFO','propagate':False,},},}
设置
可以使用django设置自定义请求日志。下面显示可用设置的默认值:
REQUESTLOGS={'STORAGE_CLASS':'requestlogs.storages.LoggingStorage','ENTRY_CLASS':'requestlogs.entries.RequestLogEntry','SERIALIZER_CLASS':'requestlogs.storages.BaseEntrySerializer','SECRETS':['password','token'],'ATTRIBUTE_NAME':'_requestlog',}
- 存储类
- python类的路径,该类将处理存储日志项。如果只需要重新实现存储机制,请重写此命令。例如,在选择要存储的数据时,可能会出现这种情况。
- 入门级
- 处理完整requestlogs项构造的python类的路径。覆盖此选项可完全自定义请求日志条目行为。
- 序列化程序类
- 用于在存储之前序列化请求日志项的序列化程序类的路径。默认情况下,这是
rest_framework.serializers.serializer
的子类。
- 用于在存储之前序列化请求日志项的序列化程序类的路径。默认情况下,这是
- 秘密
- 请求/响应数据中的键列表,这些键将替换为存储项中的
'***'
。
- 请求/响应数据中的键列表,这些键将替换为存储项中的
- django requestlogs在内部将entry对象附加到django请求对象,并使用此属性名。如果引起碰撞,则覆盖。
使用请求ID登录
django requestlogs还包含一个中间件和日志帮助程序,用于关联 记录消息的请求特定标识符(uuid)。这是为了帮助 区分特定请求-响应周期的消息,这可能是有用的 在接收大量请求的应用程序中。
请求id被添加到标准日志消息(django应用程序日志)中。 通过指定自定义格式化程序并使用提供的日志筛选器。 请求id也可以存储到requestlog条目中。 启用请求id日志记录的中间件不需要核心请求日志 要安装的中间件。
在引擎盖下,请求id是通过threading.local()
实现的。
安装
通过添加requestLogs.middleware.requestLogsMiddleware来启用此功能
到
中间件设置:
MIDDLEWARE=[...'requestlogs.middleware.RequestLogsMiddleware','requestlogs.middleware.RequestIdMiddleware',]
安装后,应用程序日志应开始显示以下格式的消息 以下内容:
2019-07-18 11:56:07,261 INFO 954fb004fb404751a2fa33326101442c urls:31 Handling GET request
2019-07-18 11:56:07,262 DEBUG 954fb004fb404751a2fa33326101442c urls:32 No parameters given
2019-07-18 11:56:07,262 INFO 954fb004fb404751a2fa33326101442c urls:33 All good
要将请求id添加到requestlog条目中,还可以使用提供的序列化程序 以类为起点:
REQUESTLOGS={...'SERIALIZER_CLASS':'requestlogs.storages.RequestIdEntrySerializer',}
配置
中间件还有一些额外的配置功能:
{'action_name': None, 'execution_time': '00:00:00.024900', 'timestamp': '2019-07-01T07:05:34.217703Z', 'ip_address': None, 'request': OrderedDict([('method', 'GET'), ('full_path', '/'), ('data', '{}'), ('query_params', '{}')]), 'response': OrderedDict([('status_code', 200), ('data', '{"ok": true}')]), 'user': OrderedDict([('id', 1), ('username', 'admin')])}
0
- 请求ID HTTP头
- 如果已设置,则此请求头的值将用作请求ID(而不是 随机生成)。这必须是有效的uuid。此功能的一个用例位于 微服务体系结构,其中micreservice调用另一个内部微服务。 使用相同的请求id格式化两个应用程序的日志消息 可能是首选结果。
- 请求ID属性名称
- 在内部用于将请求id附加到
threading.locals()
。如果引起碰撞,则覆盖。
- 在内部用于将请求id附加到
要将请求id添加到django应用程序的日志消息中,请使用提供的
日志过滤并将请求id
包含到日志格式化程序。
以下是完整的日志记录配置:
{'action_name': None, 'execution_time': '00:00:00.024900', 'timestamp': '2019-07-01T07:05:34.217703Z', 'ip_address': None, 'request': OrderedDict([('method', 'GET'), ('full_path', '/'), ('data', '{}'), ('query_params', '{}')]), 'response': OrderedDict([('status_code', 200), ('data', '{"ok": true}')]), 'user': OrderedDict([('id', 1), ('username', 'admin')])}
1