HM-99. Изменения таблицы журнала клиентских запросов (#54)

This commit is contained in:
Nikolay
2020-08-13 23:32:40 +03:00
committed by GitHub
parent 5453d0c63f
commit 0e0c37a63a
8 changed files with 97 additions and 23 deletions

View File

@ -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>

View File

@ -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]));
} }
} }

View File

@ -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();

View File

@ -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);

View File

@ -25,7 +25,7 @@ class TableCellOverflow extends Component {
}, },
}); });
span.innerHTML = text; span.innerHTML = text || '-';
} }
} }

View File

@ -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
View 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} мс`,
};
};

View File

@ -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) => {