Skip to content

Commit 527d9de

Browse files
Merge pull request #13 from vishalanandl177/dev
Version 1.0.6
2 parents 524bba4 + 777cd70 commit 527d9de

File tree

7 files changed

+89
-43
lines changed

7 files changed

+89
-43
lines changed

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# DRF API Logger
2-
![version](https://img.shields.io/badge/version-1.0.5-blue.svg)
2+
![version](https://img.shields.io/badge/version-1.0.6-blue.svg)
33
[![Downloads](https://pepy.tech/badge/drf-api-logger)](http://pepy.tech/project/drf-api-logger)
44
[![Downloads](https://pepy.tech/badge/drf-api-logger/month)](https://pepy.tech/project/drf-api-logger)
55
[![Open Source](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)](https://opensource.org/)
@@ -79,6 +79,8 @@ DRF_API_LOGGER_DATABASE = True # Default to False
7979

8080
![Alt text](https://raw.githubusercontent.com/vishalanandl177/DRF-API-Logger/master/logs.png?raw=true, "Logger")
8181

82+
![Alt text](https://raw.githubusercontent.com/vishalanandl177/DRF-API-Logger/master/graph.png?raw=true, "Graph")
83+
8284
![Alt text](https://raw.githubusercontent.com/vishalanandl177/DRF-API-Logger/master/lists.png?raw=true, "Lists")
8385

8486
![Alt text](https://raw.githubusercontent.com/vishalanandl177/DRF-API-Logger/master/details.png?raw=true, "Details")
@@ -134,11 +136,11 @@ DRF_LOGGER_QUEUE_MAX_SIZE = 50 # Default to 50 if not specified.
134136

135137
DRF API Logger also waits for a period of time. If queue is not full and there are some logs to be inserted, it inserts after interval ends.
136138

137-
Specify interval (In Seconds).
139+
Specify an interval (In Seconds).
138140
```python
139141
DRF_LOGGER_INTERVAL = 10 # In Seconds, Default to 10 seconds if not specified.
140142
```
141-
Note: The API call time (added_on) is timezone aware datetime object. It is actual time of API call irrespective of interval value or queue size.
143+
Note: The API call time (added_on) is a timezone aware datetime object. It is actual time of API call irrespective of interval value or queue size.
142144
### Skip namespace
143145
You can skip the entire app to be logged into the database by specifying namespace of the app as list.
144146
```python
@@ -196,7 +198,7 @@ Select records for status_code 200.
196198
result_for_200_status_code = APILogsModel.objects.filter(status_code=200)
197199
```
198200

199-
Model:
201+
DRF API Logger Model:
200202
```
201203
class APILogsModel(Model):
202204
id = models.BigAutoField(primary_key=True)

dist/drf_api_logger-1.0.6.tar.gz

13.8 KB
Binary file not shown.

drf_api_logger/admin.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
from django.contrib import admin
22
from django.db.models import Count
33

4-
54
from drf_api_logger.utils import database_log_enabled
65

7-
86
if database_log_enabled():
97
from drf_api_logger.models import APILogsModel
108

@@ -34,7 +32,18 @@ def changelist_view(self, request, extra_context=None):
3432
response = super(APILogsAdmin, self).changelist_view(request, extra_context)
3533
filtered_query_set = response.context_data["cl"].queryset
3634
analytics_model = filtered_query_set.values('added_on__date').annotate(total=Count('id')).order_by('total')
37-
extra_context = dict(analytics=analytics_model)
35+
status_code_count_mode = filtered_query_set.values('id').values('status_code').annotate(
36+
total=Count('id')).order_by('status_code')
37+
status_code_count_keys = list()
38+
status_code_count_values = list()
39+
for item in status_code_count_mode:
40+
status_code_count_keys.append(item.get('status_code'))
41+
status_code_count_values.append(item.get('total'))
42+
extra_context = dict(
43+
analytics=analytics_model,
44+
status_code_count_keys=status_code_count_keys,
45+
status_code_count_values=status_code_count_values
46+
)
3847
response.context_data.update(extra_context)
3948
return response
4049

@@ -47,4 +56,5 @@ def has_change_permission(self, request, obj=None):
4756
def has_delete_permission(self, request, obj=None):
4857
return False
4958

59+
5060
admin.site.register(APILogsModel, APILogsAdmin)

drf_api_logger/middleware/api_logger_middleware.py

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -89,39 +89,38 @@ def __call__(self, request):
8989
response_body = json.loads(response.content.decode())
9090
else:
9191
response_body = json.loads(response.content)
92+
if self.DRF_API_LOGGER_PATH_TYPE == 'ABSOLUTE':
93+
api = request.build_absolute_uri()
94+
elif self.DRF_API_LOGGER_PATH_TYPE == 'FULL_PATH':
95+
api = request.get_full_path()
96+
elif self.DRF_API_LOGGER_PATH_TYPE == 'RAW_URI':
97+
api = request.get_raw_uri()
98+
else:
99+
api = request.build_absolute_uri()
100+
101+
data = dict(
102+
api=api,
103+
headers=headers,
104+
body=request_data,
105+
method=method,
106+
client_ip_address=get_client_ip(request),
107+
response=response_body,
108+
status_code=response.status_code,
109+
execution_time=time.time() - start_time,
110+
added_on=timezone.now()
111+
)
112+
if self.DRF_API_LOGGER_DATABASE:
113+
if LOGGER_THREAD:
114+
d = data.copy()
115+
d['headers'] = json.dumps(d['headers'], indent=4)
116+
if request_data:
117+
d['body'] = json.dumps(d['body'], indent=4)
118+
d['response'] = json.dumps(d['response'], indent=4)
119+
LOGGER_THREAD.put_log_data(data=d)
120+
if self.DRF_API_LOGGER_SIGNAL:
121+
API_LOGGER_SIGNAL.listen(**data)
92122
else:
93-
response_body = '** Not JSON **'
94-
95-
if self.DRF_API_LOGGER_PATH_TYPE == 'ABSOLUTE':
96-
api = request.build_absolute_uri()
97-
elif self.DRF_API_LOGGER_PATH_TYPE == 'FULL_PATH':
98-
api = request.get_full_path()
99-
elif self.DRF_API_LOGGER_PATH_TYPE == 'RAW_URI':
100-
api = request.get_raw_uri()
101-
else:
102-
api = request.build_absolute_uri()
103-
104-
data = dict(
105-
api=api,
106-
headers=headers,
107-
body=request_data,
108-
method=method,
109-
client_ip_address=get_client_ip(request),
110-
response=response_body,
111-
status_code=response.status_code,
112-
execution_time=time.time() - start_time,
113-
added_on=timezone.now()
114-
)
115-
if self.DRF_API_LOGGER_DATABASE:
116-
if LOGGER_THREAD:
117-
d = data.copy()
118-
d['headers'] = json.dumps(d['headers'], indent=4)
119-
if request_data:
120-
d['body'] = json.dumps(d['body'], indent=4)
121-
d['response'] = json.dumps(d['response'], indent=4)
122-
LOGGER_THREAD.put_log_data(data=d)
123-
if self.DRF_API_LOGGER_SIGNAL:
124-
API_LOGGER_SIGNAL.listen(**data)
123+
return response
125124
else:
126125
response = self.get_response(request)
127126
return response

drf_api_logger/templates/charts_change_list.html

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.css" />
88
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"></script>
99
<script>
10+
1011
document.addEventListener('DOMContentLoaded', () => {
11-
const ctx = document.getElementById('myChart').getContext('2d');
12+
const ctx = document.getElementById('countChart').getContext('2d');
1213

13-
// Sample data
1414
const chartData = [
1515
{% for item in analytics %}
1616
{"date": "{{ item.added_on__date }}", "y": {{ item.total }}},
@@ -60,14 +60,49 @@
6060
},
6161
},
6262
});
63+
64+
var color = Chart.helpers.color;
65+
66+
var barChartData = {
67+
labels: {{ status_code_count_keys }},
68+
datasets: [{
69+
label: 'Number of API calls by status code',
70+
backgroundColor: 'rgb(33,150,243)',
71+
borderColor: 'rgb(33,150,243)',
72+
borderWidth: 1,
73+
data: {{ status_code_count_values }}
74+
}]
75+
};
76+
77+
window.onload = function() {
78+
var ctx = document.getElementById('statusCodeChart').getContext('2d');
79+
window.myBar = new Chart(ctx, {
80+
type: 'bar',
81+
data: barChartData,
82+
options: {
83+
responsive: true,
84+
legend: {
85+
position: 'top',
86+
},
87+
title: {
88+
display: true,
89+
text: 'API calls by status code'
90+
}
91+
}
92+
});
93+
94+
};
6395
});
6496
</script>
6597
{% endblock %}
6698

6799
{% block content %}
68100
<!-- Render our chart -->
69101
<div style="width: 80%;">
70-
<canvas style="margin-bottom: 30px; width: 60%; height: 50%;" id="myChart"></canvas>
102+
<canvas style="margin-bottom: 30px; width: 60%; height: 50%;" id="countChart"></canvas>
103+
</div>
104+
<div style="width: 80%; margin-top: 24px;">
105+
<canvas style="margin-bottom: 30px; width: 60%; height: 50%;" id="statusCodeChart"></canvas>
71106
</div>
72107
<!-- Render the rest of the ChangeList view -->
73108
{{ block.super }}

graph.png

55.9 KB
Loading

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def get_long_desc():
2121

2222
setuptools.setup(
2323
name="drf_api_logger",
24-
version="1.0.5",
24+
version="1.0.6",
2525
author="Vishal Anand",
2626
author_email="vishalanandl177@gmail.com",
2727
description="An API Logger for your Django Rest Framework project.",

0 commit comments

Comments
 (0)