Skip to content

Commit 1feaaa3

Browse files
committed
added log sender, replaced console.log with wrapper
1 parent 6f5d459 commit 1feaaa3

File tree

10 files changed

+120
-37
lines changed

10 files changed

+120
-37
lines changed

app/api/logs.py

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
from datetime import datetime
1+
from datetime import datetime
22
from app.root_logger import get_root_logger
33
from ast import literal_eval
4-
4+
import inspect
55
from flask import Blueprint, request
66

77
from app.lti_session_passback.auth_checkers import check_admin
@@ -11,7 +11,6 @@
1111
logger = get_root_logger()
1212

1313

14-
1514
@api_logs.route('/api/logs/', methods=['GET'])
1615
def get_logs() -> (dict, int):
1716
"""
@@ -26,13 +25,15 @@ def get_logs() -> (dict, int):
2625
try:
2726
limit = request.args.get('limit', default=None, type=int)
2827
except Exception as e:
29-
logger.info('Limit value {} is invalid.\n{}'.format(request.args.get('limit'), e))
28+
logger.info('Limit value {} is invalid.\n{}'.format(
29+
request.args.get('limit'), e))
3030
limit = None
3131

3232
try:
3333
offset = request.args.get('offset', default=None, type=int)
3434
except Exception as e:
35-
logger.info('Offset value {} is invalid.\n{}'.format(request.args.get('offset', default=None), e))
35+
logger.info('Offset value {} is invalid.\n{}'.format(
36+
request.args.get('offset', default=None), e))
3637
offset = None
3738

3839
raw_filters = request.args.get('filter', default=None)
@@ -42,7 +43,8 @@ def get_logs() -> (dict, int):
4243
if not isinstance(filters, dict):
4344
filters = None
4445
except Exception as e:
45-
logger.info('Filter value {} is invalid.\n{}'.format(raw_filters, e))
46+
logger.info(
47+
'Filter value {} is invalid.\n{}'.format(raw_filters, e))
4648
filters = None
4749
else:
4850
filters = raw_filters
@@ -52,18 +54,22 @@ def get_logs() -> (dict, int):
5254
try:
5355
ordering = literal_eval(raw_ordering)
5456
if not isinstance(ordering, list) or not all(map(lambda x: x[1] in [-1, 1], ordering)):
55-
logger.info('Ordering value {} is invalid.'.format(raw_ordering))
57+
logger.info(
58+
'Ordering value {} is invalid.'.format(raw_ordering))
5659
ordering = None
5760
except Exception as e:
58-
logger.info('Ordering value {} is invalid.\n{}'.format(request.args.get('ordering', default=None), e))
61+
logger.info('Ordering value {} is invalid.\n{}'.format(
62+
request.args.get('ordering', default=None), e))
5963
ordering = None
6064
else:
6165
ordering = raw_ordering
6266

6367
try:
64-
logs = LogsDBManager().get_logs_filtered(filters=filters, limit=limit, offset=offset, ordering=ordering)
68+
logs = LogsDBManager().get_logs_filtered(
69+
filters=filters, limit=limit, offset=offset, ordering=ordering)
6570
except Exception as e:
66-
message = 'Incorrect get_logs_filtered execution, {}: {}.'.format(e.__class__, e)
71+
message = 'Incorrect get_logs_filtered execution, {}: {}.'.format(
72+
e.__class__, e)
6773
logger.warning(message)
6874
return {'message': message}, 404
6975

@@ -84,3 +90,56 @@ def get_logs() -> (dict, int):
8490
logs_json['logs'][str(_id)] = current_log_json
8591
logs_json['message'] = 'OK'
8692
return logs_json, 200
93+
94+
95+
@api_logs.route('/logs', methods=['POST'])
96+
def create_log():
97+
"""
98+
Endpoint to receive client logs.
99+
Expected JSON:
100+
{
101+
"timestamp": "...",
102+
"message": "..."
103+
}
104+
"""
105+
# logger.info("Received client log")
106+
frame = inspect.currentframe() # кадр
107+
caller = frame.f_back # кадр вызывающей функции
108+
pathname = caller.f_code.co_filename # путь к файлу вызвывающей функции
109+
filename = pathname.split('/')[-1] # имя файла
110+
funcName = caller.f_code.co_name # имя функции
111+
lineno = caller.f_lineno # номер строки
112+
try:
113+
data = request.get_json(force=True)
114+
if not data:
115+
return {"message": "Invalid json"}, 400
116+
117+
timestamp = data.get("timestamp")
118+
message = data.get("message")
119+
120+
if message is None:
121+
return {"message": "message field is required"}, 400
122+
123+
if timestamp:
124+
timestamp = datetime.fromisoformat(
125+
timestamp.replace("Z", "+00:00"))
126+
else:
127+
timestamp = datetime.now()
128+
129+
LogsDBManager().add_log(
130+
timestamp=timestamp,
131+
serviceName="client",
132+
levelname="INFO",
133+
levelno=20,
134+
message=message,
135+
pathname=pathname,
136+
filename=filename,
137+
funcName=funcName,
138+
lineno=lineno
139+
)
140+
141+
return {"message": "log received"}, 201
142+
143+
except Exception as e:
144+
logger.warning(f"Client log creation failed: {e}")
145+
return {"message": "Internal server error"}, 500

app/static/js/logWrapper.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
(function () {
2+
// враппер над логами
3+
window.logWrapper = function (...args) {
4+
// стандартное логирование
5+
console.log(...args);
6+
7+
// отправка на роут
8+
try {
9+
fetch('/logs', {
10+
method: 'POST',
11+
headers: {
12+
'Content-Type': 'application/json'
13+
},
14+
body: JSON.stringify({
15+
timestamp: new Date().toISOString(),
16+
message: args.map(a => a.toString()).join(' ')
17+
})
18+
});
19+
} catch (e) {
20+
console.error('Log send error', e);
21+
}
22+
}
23+
})();

app/static/js/recording.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ let gumStream,
66
timer;
77

88
function startRecording() {
9-
console.log("call startRecording(). Try to call navigator.mediaDevices.getUserMedia");
10-
console.log("navigator", navigator);
11-
console.log("navigator.mediaDevices", navigator.mediaDevices);
9+
logWrapper("call startRecording(). Try to call navigator.mediaDevices.getUserMedia");
10+
logWrapper("navigator", navigator);
11+
logWrapper("navigator.mediaDevices", navigator.mediaDevices);
1212
$("#alert").hide()
1313
$("#record-contain").show();
1414
navigator.mediaDevices.getUserMedia({audio: true, video: false}).then(function (stream) {
@@ -82,8 +82,8 @@ function startRecording() {
8282
$("#record")[0].disabled = true;
8383
$("#done")[0].disabled = false;
8484
}).catch( err => {
85-
console.log('Error on calling avigator.mediaDevices.getUserMedia')
86-
console.log(err)
85+
logWrapper('Error on calling avigator.mediaDevices.getUserMedia')
86+
logWrapper(err)
8787
$("#alert").show();
8888
$("#error-text").html("Микрофон не доступен!");
8989
});

app/static/js/show_all_trainings.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ function buildAllTrainingsTable(trainingsJson) {
161161
allTrainingsTable.appendChild(currentTrainingRowElement);
162162
});
163163
})
164-
.catch(err => console.log(err));
164+
.catch(err => logWrapper(err));
165165
}
166166

167167
const REF_PAGE_COUNT = document.getElementById('ref-page-count');

app/static/js/show_all_trainings_filters.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ function createFilter(filterCode, initialValues = "") {
578578
*/
579579
function removeAllFiltersUI() {
580580
for (const key of Object.keys(currentFilters)) {
581-
// console.log($("#" + key + "-filter"))
581+
// logWrapper($("#" + key + "-filter"))
582582
$("#" + key + "-filter").remove();
583583
}
584584
}

app/static/js/training_statistics.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ function configureAudio(info) {
5858
if (this.currentTime > info[info.length-1])
5959
setPage(info.length, info);
6060
changeURLByParam('time', this.currentTime.toFixed(1));
61-
console.log(this.currentTime);
61+
logWrapper(this.currentTime);
6262
}
6363
)
6464
}
@@ -114,7 +114,7 @@ function setCriteriaResults(s) {
114114
}
115115

116116
function setRecognizedInfo(slides){
117-
console.log(slides)
117+
logWrapper(slides)
118118
}
119119

120120
function renderPageButtons(info){

app/static/js/upload.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ function fileLoadingOnChange() {
8080
const file = $("#file-loading").prop("files")[0];
8181
let parts = file.name.split(".");
8282
let extension = parts.pop().toLowerCase();
83-
console.log(`File extension ${extension}`)
83+
logWrapper(`File extension ${extension}`)
8484
/* TODO: use list with user-allowed extensions */
8585
if (parts.length < 1 || !user_formats.includes(extension)) {
8686
$("#alert").show();

app/static/js/utils.js

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,24 @@ function buildTitleRow(columns) {
88
return titleRowElement;
99
}
1010

11-
function recheck(trainingId){
11+
function recheck(trainingId) {
1212
fetch('/api/sessions/admin')
13-
.then(response => response.json())
14-
.then(res => {
15-
if (res.admin) {
16-
fetch(`/api/trainings/${trainingId}/`, {method: "POST"})
17-
.then(response => response.json())
18-
.then(innerResponseJson => {
19-
if (innerResponseJson["message"] === "OK") {
20-
window.open(`/trainings/statistics/${trainingId}/`);
21-
//location.href = `/trainings/statistics/${trainingId}/`;
22-
}
23-
});
24-
}
25-
});
13+
.then(response => response.json())
14+
.then(res => {
15+
if (res.admin) {
16+
fetch(`/api/trainings/${trainingId}/`, { method: "POST" })
17+
.then(response => response.json())
18+
.then(innerResponseJson => {
19+
if (innerResponseJson["message"] === "OK") {
20+
window.open(`/trainings/statistics/${trainingId}/`);
21+
//location.href = `/trainings/statistics/${trainingId}/`;
22+
}
23+
});
24+
}
25+
});
2626
}
2727

28-
function strtobool(val, onError= false) {
28+
function strtobool(val, onError = false) {
2929
try {
3030
val = val.toLowerCase();
3131
if (['y', 'yes', 't', 'true', 'on', '1'].includes(val)) {

app/templates/base.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ <h1>{{ page_title }}</h1>
1616
{% block content %} {% endblock %}
1717
<!--{% include "bug_reports.html" %}-->
1818
{% block footer %} {% include "footer.html" %} {% endblock %}
19+
<script src="{{ url_for('static', filename='js/logWrapper.js') }}" defer></script>
1920
<script src="{{ url_for('static', filename='js/base.js') }}"></script>
2021
</body>
2122

app/templates/dumps.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@
4040
window.location.reload();
4141
}
4242
else{
43-
console.log(data["message"]);
43+
logWrapper(data["message"]);
4444
alert('{{ t("Ошибка создания архива.")}}' + '\n' + data["message"])
4545
}
4646
})
4747
.catch(error => {
48-
console.log(error);
48+
logWrapper(error);
4949
alert('{{ t("Ошибка создания архива.") + t("Попробуйте позже или обратитесь к администратору") }}')
5050
});
5151
})

0 commit comments

Comments
 (0)