django-log-formatter-asim 1.1.0a1__py3-none-any.whl → 1.1.0a2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_log_formatter_asim/__init__.py +3 -10
- django_log_formatter_asim/events/authentication.py +11 -4
- django_log_formatter_asim/events/common.py +12 -0
- django_log_formatter_asim/events/file_activity.py +11 -4
- {django_log_formatter_asim-1.1.0a1.dist-info → django_log_formatter_asim-1.1.0a2.dist-info}/METADATA +2 -1
- django_log_formatter_asim-1.1.0a2.dist-info/RECORD +9 -0
- django_log_formatter_asim-1.1.0a1.dist-info/RECORD +0 -9
- {django_log_formatter_asim-1.1.0a1.dist-info → django_log_formatter_asim-1.1.0a2.dist-info}/LICENSE +0 -0
- {django_log_formatter_asim-1.1.0a1.dist-info → django_log_formatter_asim-1.1.0a2.dist-info}/WHEEL +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import logging
|
|
3
|
+
import os
|
|
3
4
|
from datetime import datetime
|
|
5
|
+
from datetime import timezone
|
|
4
6
|
from importlib.metadata import distribution
|
|
5
|
-
import os
|
|
6
7
|
|
|
7
8
|
import ddtrace
|
|
8
9
|
from ddtrace.trace import tracer
|
|
@@ -70,7 +71,7 @@ class ASIMRootFormatter:
|
|
|
70
71
|
|
|
71
72
|
def get_log_dict(self):
|
|
72
73
|
record = self.record
|
|
73
|
-
log_time = datetime.
|
|
74
|
+
log_time = datetime.fromtimestamp(record.created, timezone.utc).isoformat()
|
|
74
75
|
log_dict = {
|
|
75
76
|
# Event fields...
|
|
76
77
|
"EventMessage": record.getMessage(),
|
|
@@ -200,14 +201,6 @@ class ASIMRequestFormatter(ASIMRootFormatter):
|
|
|
200
201
|
http_user_agent = request.META.get("HTTP_USER_AGENT", None)
|
|
201
202
|
return http_user_agent
|
|
202
203
|
|
|
203
|
-
def _get_ip_address(self, request):
|
|
204
|
-
# Import here as ipware uses settings
|
|
205
|
-
from ipware import get_client_ip
|
|
206
|
-
|
|
207
|
-
client_ip, is_routable = get_client_ip(request)
|
|
208
|
-
return client_ip or "Unknown"
|
|
209
|
-
|
|
210
|
-
|
|
211
204
|
ASIM_FORMATTERS = {
|
|
212
205
|
"root": ASIMRootFormatter,
|
|
213
206
|
"django.request": ASIMRequestFormatter,
|
|
@@ -12,6 +12,7 @@ from .common import Result
|
|
|
12
12
|
from .common import Server
|
|
13
13
|
from .common import Severity
|
|
14
14
|
from .common import _default_severity
|
|
15
|
+
from .common import _get_client_ip_address
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
class AuthenticationEvent(str, Enum):
|
|
@@ -78,6 +79,7 @@ def log_authentication(
|
|
|
78
79
|
- Django Authentication systems current username
|
|
79
80
|
- Django Session middlewares Session Key
|
|
80
81
|
- Client IP address
|
|
82
|
+
- URL requested by the client
|
|
81
83
|
- Server hostname
|
|
82
84
|
:param event: What authentication action was attempted, either "Logon" or "Logoff"
|
|
83
85
|
:param result: What outcome did the action have, either "Success", "Failure", "Partial", "NA"
|
|
@@ -126,13 +128,18 @@ def log_authentication(
|
|
|
126
128
|
|
|
127
129
|
if "hostname" in server:
|
|
128
130
|
log["DvcHostname"] = server["hostname"]
|
|
129
|
-
elif
|
|
130
|
-
log["DvcHostname"] = request.
|
|
131
|
+
elif "SERVER_NAME" in request.META:
|
|
132
|
+
log["DvcHostname"] = request.META["SERVER_NAME"]
|
|
131
133
|
|
|
132
134
|
if "ip_address" in client:
|
|
133
135
|
log["SrcIpAddr"] = client["ip_address"]
|
|
134
|
-
elif
|
|
135
|
-
log["SrcIpAddr"] =
|
|
136
|
+
elif client_ip := _get_client_ip_address(request):
|
|
137
|
+
log["SrcIpAddr"] = client_ip
|
|
138
|
+
|
|
139
|
+
if "requested_url" in client:
|
|
140
|
+
log["TargetUrl"] = client["requested_url"]
|
|
141
|
+
elif "SERVER_NAME" in request.META:
|
|
142
|
+
log["TargetUrl"] = request.scheme + "://" + request.get_host() + request.get_full_path()
|
|
136
143
|
|
|
137
144
|
if "role" in user:
|
|
138
145
|
log["ActorUserType"] = user["role"]
|
|
@@ -2,6 +2,8 @@ from enum import Enum
|
|
|
2
2
|
from typing import Optional
|
|
3
3
|
from typing import TypedDict
|
|
4
4
|
|
|
5
|
+
from django.http import HttpRequest
|
|
6
|
+
|
|
5
7
|
|
|
6
8
|
class Result(str, Enum):
|
|
7
9
|
Success = "Success"
|
|
@@ -23,6 +25,8 @@ class Client(TypedDict):
|
|
|
23
25
|
"""Internet Protocol Address of the client making the Authentication
|
|
24
26
|
event."""
|
|
25
27
|
ip_address: Optional[str]
|
|
28
|
+
"""URL requested by the client."""
|
|
29
|
+
requested_url: Optional[str]
|
|
26
30
|
|
|
27
31
|
|
|
28
32
|
class Server(TypedDict):
|
|
@@ -40,3 +44,11 @@ class Server(TypedDict):
|
|
|
40
44
|
|
|
41
45
|
def _default_severity(result: Result) -> Severity:
|
|
42
46
|
return Severity.Informational if result == Result.Success else Severity.Medium
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _get_client_ip_address(request: HttpRequest) -> Optional[str]:
|
|
50
|
+
# Import here as ipware uses settings
|
|
51
|
+
from ipware import get_client_ip
|
|
52
|
+
|
|
53
|
+
client_ip, _ = get_client_ip(request)
|
|
54
|
+
return client_ip
|
|
@@ -12,6 +12,7 @@ from .common import Result
|
|
|
12
12
|
from .common import Server
|
|
13
13
|
from .common import Severity
|
|
14
14
|
from .common import _default_severity
|
|
15
|
+
from .common import _get_client_ip_address
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
class FileActivityEvent(str, Enum):
|
|
@@ -92,6 +93,7 @@ def log_file_activity(
|
|
|
92
93
|
from which the following data will be logged if available
|
|
93
94
|
- Django Authentication systems current username
|
|
94
95
|
- Client IP address
|
|
96
|
+
- URL requested by the client
|
|
95
97
|
- Server hostname
|
|
96
98
|
:param event: What File Event action was attempted, one of:
|
|
97
99
|
- FileAccessed
|
|
@@ -167,13 +169,18 @@ def log_file_activity(
|
|
|
167
169
|
|
|
168
170
|
if "hostname" in server:
|
|
169
171
|
log["DvcHostname"] = server["hostname"]
|
|
170
|
-
elif
|
|
171
|
-
log["DvcHostname"] = request.
|
|
172
|
+
elif "SERVER_NAME" in request.META:
|
|
173
|
+
log["DvcHostname"] = request.META["SERVER_NAME"]
|
|
172
174
|
|
|
173
175
|
if "ip_address" in client:
|
|
174
176
|
log["SrcIpAddr"] = client["ip_address"]
|
|
175
|
-
elif
|
|
176
|
-
log["SrcIpAddr"] =
|
|
177
|
+
elif client_ip := _get_client_ip_address(request):
|
|
178
|
+
log["SrcIpAddr"] = client_ip
|
|
179
|
+
|
|
180
|
+
if "requested_url" in client:
|
|
181
|
+
log["TargetUrl"] = client["requested_url"]
|
|
182
|
+
elif "SERVER_NAME" in request.META:
|
|
183
|
+
log["TargetUrl"] = request.scheme + "://" + request.get_host() + request.get_full_path()
|
|
177
184
|
|
|
178
185
|
if "username" in user:
|
|
179
186
|
log["ActorUsername"] = user["username"]
|
{django_log_formatter_asim-1.1.0a1.dist-info → django_log_formatter_asim-1.1.0a2.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: django-log-formatter-asim
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.0a2
|
|
4
4
|
Summary: Formats Django logs in ASIM format.
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Department for Business and Trade Platform Team
|
|
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
16
16
|
Requires-Dist: ddtrace (>=3.2.1,<4.0.0)
|
|
17
17
|
Requires-Dist: django (>=3,<5) ; python_version == "3.9"
|
|
18
18
|
Requires-Dist: django (>=3,<6) ; python_version >= "3.10" and python_version < "4"
|
|
19
|
+
Requires-Dist: django-ipware (>=7.0.1,<8.0.0)
|
|
19
20
|
Description-Content-Type: text/markdown
|
|
20
21
|
|
|
21
22
|
# Django ASIM log formatter
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
django_log_formatter_asim/__init__.py,sha256=LDQQch2GKY6LRj-KOME393FCiwjisQ49ATWBEqAP4ZA,7684
|
|
2
|
+
django_log_formatter_asim/events/__init__.py,sha256=th8AEFNM-J5lNlO-d8Lk465jXqplE3IoTwj4DlscwYo,92
|
|
3
|
+
django_log_formatter_asim/events/authentication.py,sha256=OMAT4P8ZRmeEWngHTLvscGOXtRE8t39izZpdKNot2R8,6479
|
|
4
|
+
django_log_formatter_asim/events/common.py,sha256=G6h4ftfrAzXBNd3EkhFQsMv5BdGW0XtdeBKJ43Ja70s,1360
|
|
5
|
+
django_log_formatter_asim/events/file_activity.py,sha256=RPlzJm8TjdT3szx1wClULG29Sz9RNA16NQmUJwhxjTc,6978
|
|
6
|
+
django_log_formatter_asim-1.1.0a2.dist-info/LICENSE,sha256=dP79lN73--7LMApnankTGLqDbImXg8iYFqWgnExGkGk,1090
|
|
7
|
+
django_log_formatter_asim-1.1.0a2.dist-info/METADATA,sha256=fFVGcfHJ9wOQq19lqnulIV5PgvHc99m1Mt8aNuUSMS8,5581
|
|
8
|
+
django_log_formatter_asim-1.1.0a2.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
9
|
+
django_log_formatter_asim-1.1.0a2.dist-info/RECORD,,
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
django_log_formatter_asim/__init__.py,sha256=i-7HqYE5s3hjmHLh4TTzLpEdgr5N22msFEQw16Pe_EI,7867
|
|
2
|
-
django_log_formatter_asim/events/__init__.py,sha256=th8AEFNM-J5lNlO-d8Lk465jXqplE3IoTwj4DlscwYo,92
|
|
3
|
-
django_log_formatter_asim/events/authentication.py,sha256=Nkgv-c_pNhwS8C1QYj0M3zH_cz2QJQqopzcMRhTv7Ls,6242
|
|
4
|
-
django_log_formatter_asim/events/common.py,sha256=4P3lb-rfxv_4Vf2DfW-Mi3Sq7rIWqF_tGK8mPPCUMco,1039
|
|
5
|
-
django_log_formatter_asim/events/file_activity.py,sha256=bKDpZcoBUePTeKCDPqLToGc8CA85_aXTw1c8KXoRLq0,6741
|
|
6
|
-
django_log_formatter_asim-1.1.0a1.dist-info/LICENSE,sha256=dP79lN73--7LMApnankTGLqDbImXg8iYFqWgnExGkGk,1090
|
|
7
|
-
django_log_formatter_asim-1.1.0a1.dist-info/METADATA,sha256=Fz6KC4Ai4jr3yq-Q1PDCtl0cp9mGlor0buzMCmh9J9s,5535
|
|
8
|
-
django_log_formatter_asim-1.1.0a1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
9
|
-
django_log_formatter_asim-1.1.0a1.dist-info/RECORD,,
|
{django_log_formatter_asim-1.1.0a1.dist-info → django_log_formatter_asim-1.1.0a2.dist-info}/LICENSE
RENAMED
|
File without changes
|
{django_log_formatter_asim-1.1.0a1.dist-info → django_log_formatter_asim-1.1.0a2.dist-info}/WHEEL
RENAMED
|
File without changes
|