HM-99. Изменения таблицы журнала клиентских запросов (#54)
This commit is contained in:
48
src/app.html
48
src/app.html
@ -226,10 +226,52 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- Фильтры для таблицы клиентских запросов -->
|
<!-- Фильтры для таблицы клиентских запросов -->
|
||||||
<div class="col-12 col-md-6 col-lg mb-3">
|
<div class="col-12 col-md-6 col-lg mb-3">
|
||||||
<label for="logs-filter-request-type" class="form-label">Результат запроса</label>
|
<label for="logs-filter-request-data-base" class="form-label">База данных</label>
|
||||||
<div class="LogsFilters__inputWrapper">
|
<div class="LogsFilters__inputWrapper">
|
||||||
<input type="text" class="form-control" id="logs-filter-request-type"
|
<select type="text" class="form-select" id="logs-filter-request-data-base">
|
||||||
placeholder="Введите текст">
|
<option value="">Любая</option>
|
||||||
|
<option value="production">production</option>
|
||||||
|
<option value="testing">testing</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-6 col-lg mb-3">
|
||||||
|
<label for="logs-filter-request-method" class="form-label">Метод</label>
|
||||||
|
<div class="LogsFilters__inputWrapper">
|
||||||
|
<select type="text" class="form-select" id="logs-filter-request-method">
|
||||||
|
<option value="">Любой</option>
|
||||||
|
<option value="get">GET</option>
|
||||||
|
<option value="post">POST</option>
|
||||||
|
<option value="put">PUT</option>
|
||||||
|
<option value="delete">DELETE</option>
|
||||||
|
<option value="head">HEAD</option>
|
||||||
|
<option value="options">OPTIONS</option>
|
||||||
|
<option value="path">PATH</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-6 col-lg mb-3">
|
||||||
|
<label for="logs-filter-request-url" class="form-label">URL</label>
|
||||||
|
<div class="LogsFilters__inputWrapper">
|
||||||
|
<input type="text" class="form-control" id="logs-filter-request-url" placeholder="Введите текст">
|
||||||
|
<button type="button" class="LogsFilters__clearButton">
|
||||||
|
<i class="fas fa-times"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-6 col-lg mb-3">
|
||||||
|
<label for="logs-filter-request-status" class="form-label">Код ответа</label>
|
||||||
|
<div class="LogsFilters__inputWrapper">
|
||||||
|
<input type="text" class="form-control" id="logs-filter-request-status" placeholder="Введите текст">
|
||||||
|
<button type="button" class="LogsFilters__clearButton">
|
||||||
|
<i class="fas fa-times"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-6 col-lg mb-3">
|
||||||
|
<label for="logs-filter-request-message" class="form-label">Сообщение</label>
|
||||||
|
<div class="LogsFilters__inputWrapper">
|
||||||
|
<input type="text" class="form-control" id="logs-filter-request-message" placeholder="Введите текст">
|
||||||
<button type="button" class="LogsFilters__clearButton">
|
<button type="button" class="LogsFilters__clearButton">
|
||||||
<i class="fas fa-times"></i>
|
<i class="fas fa-times"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import TableCellOverflow from '../table-cell-overflow';
|
|||||||
class ClientLogsTableRow extends Component {
|
class ClientLogsTableRow extends Component {
|
||||||
constructor (parentNode, cols, row) {
|
constructor (parentNode, cols, row) {
|
||||||
super(null, parentNode);
|
super(null, parentNode);
|
||||||
|
|
||||||
this.cols = cols.map((col) => this.createComponent(TableCellOverflow, this.mainNode, row[col.id]));
|
this.cols = cols.map((col) => this.createComponent(TableCellOverflow, this.mainNode, row[col.id]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,9 +60,11 @@ class LogsFilters extends Component {
|
|||||||
initInput = ({name, id}) => {
|
initInput = ({name, id}) => {
|
||||||
const input = this.mainNode.querySelector(`#${id}`);
|
const input = this.mainNode.querySelector(`#${id}`);
|
||||||
const clearButton = input.parentNode.querySelector('.LogsFilters__clearButton');
|
const clearButton = input.parentNode.querySelector('.LogsFilters__clearButton');
|
||||||
this.addEventListener(clearButton, 'click', () => {
|
if (clearButton) {
|
||||||
input.value = '';
|
this.addEventListener(clearButton, 'click', () => {
|
||||||
});
|
input.value = '';
|
||||||
|
});
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
input,
|
input,
|
||||||
@ -78,7 +80,11 @@ class LogsFilters extends Component {
|
|||||||
{name: 'trace', id: 'logs-filter-trace'},
|
{name: 'trace', id: 'logs-filter-trace'},
|
||||||
].map(this.initInput);
|
].map(this.initInput);
|
||||||
this.clientInputs = [
|
this.clientInputs = [
|
||||||
{name: 'type', id: 'logs-filter-request-type'},
|
{name: 'data_base', id: 'logs-filter-request-data-base'},
|
||||||
|
{name: 'method', id: 'logs-filter-request-method'},
|
||||||
|
{name: 'url', id: 'logs-filter-request-url'},
|
||||||
|
{name: 'status', id: 'logs-filter-request-status'},
|
||||||
|
{name: 'message', id: 'logs-filter-request-message'},
|
||||||
].map(this.initInput);
|
].map(this.initInput);
|
||||||
|
|
||||||
this.changeType();
|
this.changeType();
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import toString from 'lodash/toString';
|
||||||
import Component from '../component/index';
|
import Component from '../component/index';
|
||||||
import storageLogsApi from '../../api/StorageLogsAPI';
|
import storageLogsApi from '../../api/StorageLogsAPI';
|
||||||
import Pagination from '../pagination';
|
import Pagination from '../pagination';
|
||||||
@ -10,6 +11,7 @@ import ServerLogsTable from '../server-logs-table';
|
|||||||
import ClientLogsTable from '../client-logs-table';
|
import ClientLogsTable from '../client-logs-table';
|
||||||
import ClientLogsViewForm from '../client-logs-view-form';
|
import ClientLogsViewForm from '../client-logs-view-form';
|
||||||
import ServerLogsViewForm from '../server-logs-view-form';
|
import ServerLogsViewForm from '../server-logs-view-form';
|
||||||
|
import {prepareClientLogElement} from '../../utils/converters';
|
||||||
|
|
||||||
const ELEMENTS_ON_PAGE = 15;
|
const ELEMENTS_ON_PAGE = 15;
|
||||||
|
|
||||||
@ -36,8 +38,8 @@ class LogsPage extends Component {
|
|||||||
this.filters = this.createComponent(LogsFilters, this.header);
|
this.filters = this.createComponent(LogsFilters, this.header);
|
||||||
|
|
||||||
this.tables = {
|
this.tables = {
|
||||||
[LOG_TYPE.SERVER]: this.createComponent(ServerLogsTable),
|
[LOG_TYPE.SERVER]: ServerLogsTable,
|
||||||
[LOG_TYPE.CLIENT]: this.createComponent(ClientLogsTable),
|
[LOG_TYPE.CLIENT]: ClientLogsTable,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.pagination = this.createComponent(Pagination, this.footer);
|
this.pagination = this.createComponent(Pagination, this.footer);
|
||||||
@ -53,8 +55,10 @@ class LogsPage extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initPage = async () => {
|
initPage = async () => {
|
||||||
this.logList[LOG_TYPE.SERVER] = await storageLogsApi.requestServerLogs();
|
const serverList = await storageLogsApi.requestServerLogs();
|
||||||
this.logList[LOG_TYPE.CLIENT] = await storageLogsApi.requestClientLogs();
|
const clientList = await storageLogsApi.requestClientLogs();
|
||||||
|
this.logList[LOG_TYPE.SERVER] = serverList;
|
||||||
|
this.logList[LOG_TYPE.CLIENT] = clientList.map(prepareClientLogElement);
|
||||||
this.renderTable();
|
this.renderTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +69,7 @@ class LogsPage extends Component {
|
|||||||
if (!rowValue) {
|
if (!rowValue) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return rowValue.toLowerCase().includes(value.toLowerCase());
|
return toString(rowValue).toLowerCase().includes(value.toLowerCase());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -122,7 +126,7 @@ class LogsPage extends Component {
|
|||||||
const {query} = routeService.getUrlData();
|
const {query} = routeService.getUrlData();
|
||||||
const {tableType, ...omitQuery} = query;
|
const {tableType, ...omitQuery} = query;
|
||||||
this.table?.destroy();
|
this.table?.destroy();
|
||||||
this.table = this.tables[tableType];
|
this.table = this.createComponent(this.tables[tableType]);
|
||||||
this.body.appendChild(this.table.mainNode);
|
this.body.appendChild(this.table.mainNode);
|
||||||
const preparedRows = this.prepareRows(this.logList[tableType]);
|
const preparedRows = this.prepareRows(this.logList[tableType]);
|
||||||
const filteredRows = this.filterRows(preparedRows, omitQuery);
|
const filteredRows = this.filterRows(preparedRows, omitQuery);
|
||||||
|
|||||||
@ -25,7 +25,7 @@ class TableCellOverflow extends Component {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
span.innerHTML = text;
|
span.innerHTML = text || '-';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ export const LOG_TYPE = {
|
|||||||
|
|
||||||
export const LOG_LABELS = [
|
export const LOG_LABELS = [
|
||||||
{id: LOG_TYPE.SERVER, label: 'Ошибки сервера'},
|
{id: LOG_TYPE.SERVER, label: 'Ошибки сервера'},
|
||||||
{id: LOG_TYPE.CLIENT, label: 'Запросы клиентов'},
|
{id: LOG_TYPE.CLIENT, label: 'Ошибки запросов'},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const SERVER_COLS = [
|
export const SERVER_COLS = [
|
||||||
@ -17,12 +17,14 @@ export const SERVER_COLS = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export const CLIENT_COLS = [
|
export const CLIENT_COLS = [
|
||||||
{id: '_id', label: 'id', width: '240px'},
|
{id: 'startTime', label: 'Дата запроса', width: '150px'},
|
||||||
{id: 'type', label: 'Результат', width: '100px'},
|
{id: 'type', label: 'Результат', width: '100px'},
|
||||||
{id: 'request', label: 'Запрос клиента', width: '240px'},
|
{id: 'data_base', label: 'База данных'},
|
||||||
{id: 'response', label: 'Ответ сервера'},
|
{id: 'url', label: 'URL'},
|
||||||
{id: 'startTime', label: 'Начало', width: '150px'},
|
{id: 'method', label: 'Метод'},
|
||||||
{id: 'endTime', label: 'Окончание', width: '150px'},
|
{id: 'status', label: 'Код ответа'},
|
||||||
|
{id: 'message', label: 'Сообщение'},
|
||||||
|
{id: 'duration', label: 'Скорость ответа'},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const LOG_COLS = {
|
export const LOG_COLS = {
|
||||||
|
|||||||
20
src/utils/converters.js
Normal file
20
src/utils/converters.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
export const prepareClientLogElement = (client) => {
|
||||||
|
const {request, response} = client;
|
||||||
|
const {headers, method, url} = request;
|
||||||
|
const {status, message} = response;
|
||||||
|
|
||||||
|
const data_base = headers.api_name ? 'testing' : 'production';
|
||||||
|
|
||||||
|
const duration = moment(client.endTime).millisecond() - moment(client.startTime).millisecond();
|
||||||
|
return {
|
||||||
|
...client,
|
||||||
|
data_base,
|
||||||
|
method,
|
||||||
|
url,
|
||||||
|
status: status || 500,
|
||||||
|
message: message || 'Критическая ошибка сервера',
|
||||||
|
duration: `${duration} мс`,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -1,4 +1,5 @@
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import toString from 'lodash/toString';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @interface CreateElementProps
|
* @interface CreateElementProps
|
||||||
@ -46,13 +47,13 @@ export const createElement = (createElementProps) => {
|
|||||||
*/
|
*/
|
||||||
export const markText = (searchMessage, text, styleClassName = 'text-warning bg-dark') => {
|
export const markText = (searchMessage, text, styleClassName = 'text-warning bg-dark') => {
|
||||||
const replaceMessage = new RegExp(searchMessage, 'gi');
|
const replaceMessage = new RegExp(searchMessage, 'gi');
|
||||||
return text.replace(replaceMessage, (match) => (
|
return toString(text).replace(replaceMessage, (match) => (
|
||||||
`<span class="${styleClassName}">${match}</span>`
|
`<span class="${styleClassName}">${match}</span>`
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const prepareServerDate = (stringDate) => {
|
export const prepareServerDate = (stringDate) => {
|
||||||
return moment(stringDate).format('DD/MM/YYYY hh:mm:ss');
|
return moment(stringDate).format('DD/MM/YYYY HH:mm:ss');
|
||||||
};
|
};
|
||||||
|
|
||||||
export const prepareObjectToString = (object) => {
|
export const prepareObjectToString = (object) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user