summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster/toastermain/logs.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/toaster/toastermain/logs.py')
-rw-r--r--bitbake/lib/toaster/toastermain/logs.py158
1 files changed, 158 insertions, 0 deletions
diff --git a/bitbake/lib/toaster/toastermain/logs.py b/bitbake/lib/toaster/toastermain/logs.py
new file mode 100644
index 0000000000..62d871963a
--- /dev/null
+++ b/bitbake/lib/toaster/toastermain/logs.py
@@ -0,0 +1,158 @@
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4import os
5import logging
6import json
7from pathlib import Path
8from django.http import HttpRequest
9
10BUILDDIR = Path(os.environ.get('BUILDDIR', '/tmp'))
11
12def log_api_request(request, response, view, logger_name='api'):
13 """Helper function for LogAPIMixin"""
14
15 repjson = {
16 'view': view,
17 'path': request.path,
18 'method': request.method,
19 'status': response.status_code
20 }
21
22 logger = logging.getLogger(logger_name)
23 logger.info(
24 json.dumps(repjson, indent=4, separators=(", ", " : "))
25 )
26
27
28def log_view_mixin(view):
29 def log_view_request(*args, **kwargs):
30 # get request from args else kwargs
31 request = None
32 if len(args) > 0:
33 for req in args:
34 if isinstance(req, HttpRequest):
35 request = req
36 break
37 elif request is None:
38 request = kwargs.get('request')
39
40 response = view(*args, **kwargs)
41 view_name = 'unknown'
42 if hasattr(request, 'resolver_match'):
43 if hasattr(request.resolver_match, 'view_name'):
44 view_name = request.resolver_match.view_name
45
46 log_api_request(
47 request, response, view_name, 'toaster')
48 return response
49 return log_view_request
50
51
52
53class LogAPIMixin:
54 """Logs API requests
55
56 tested with:
57 - APIView
58 - ModelViewSet
59 - ReadOnlyModelViewSet
60 - GenericAPIView
61
62 Note: you can set `view_name` attribute in View to override get_view_name()
63 """
64
65 def get_view_name(self):
66 if hasattr(self, 'view_name'):
67 return self.view_name
68 return super().get_view_name()
69
70 def finalize_response(self, request, response, *args, **kwargs):
71 log_api_request(request, response, self.get_view_name())
72 return super().finalize_response(request, response, *args, **kwargs)
73
74
75LOGGING_SETTINGS = {
76 'version': 1,
77 'disable_existing_loggers': False,
78 'filters': {
79 'require_debug_false': {
80 '()': 'django.utils.log.RequireDebugFalse'
81 }
82 },
83 'formatters': {
84 'datetime': {
85 'format': '%(asctime)s %(levelname)s %(message)s'
86 },
87 'verbose': {
88 'format': '{levelname} {asctime} {module} {name}.{funcName} {process:d} {thread:d} {message}',
89 'datefmt': "%d/%b/%Y %H:%M:%S",
90 'style': '{',
91 },
92 'api': {
93 'format': '\n{levelname} {asctime} {name}.{funcName}:\n{message}',
94 'style': '{'
95 }
96 },
97 'handlers': {
98 'mail_admins': {
99 'level': 'ERROR',
100 'filters': ['require_debug_false'],
101 'class': 'django.utils.log.AdminEmailHandler'
102 },
103 'console': {
104 'level': 'DEBUG',
105 'class': 'logging.StreamHandler',
106 'formatter': 'datetime',
107 },
108 'file_django': {
109 'level': 'INFO',
110 'class': 'logging.handlers.TimedRotatingFileHandler',
111 'filename': BUILDDIR / 'toaster_logs/django.log',
112 'when': 'D', # interval type
113 'interval': 1, # defaults to 1
114 'backupCount': 10, # how many files to keep
115 'formatter': 'verbose',
116 },
117 'file_api': {
118 'level': 'INFO',
119 'class': 'logging.handlers.TimedRotatingFileHandler',
120 'filename': BUILDDIR / 'toaster_logs/api.log',
121 'when': 'D',
122 'interval': 1,
123 'backupCount': 10,
124 'formatter': 'verbose',
125 },
126 'file_toaster': {
127 'level': 'INFO',
128 'class': 'logging.handlers.TimedRotatingFileHandler',
129 'filename': BUILDDIR / 'toaster_logs/web.log',
130 'when': 'D',
131 'interval': 1,
132 'backupCount': 10,
133 'formatter': 'verbose',
134 },
135 },
136 'loggers': {
137 'django.request': {
138 'handlers': ['file_django', 'console'],
139 'level': 'WARN',
140 'propagate': True,
141 },
142 'django': {
143 'handlers': ['file_django', 'console'],
144 'level': 'WARNING',
145 'propogate': True,
146 },
147 'toaster': {
148 'handlers': ['file_toaster'],
149 'level': 'INFO',
150 'propagate': False,
151 },
152 'api': {
153 'handlers': ['file_api'],
154 'level': 'INFO',
155 'propagate': False,
156 }
157 }
158}