+ client: add response information to the filtered query log items
This commit is contained in:
parent
3b98461a2a
commit
428706399a
|
@ -176,6 +176,8 @@
|
||||||
"rule_added_to_custom_filtering_toast": "Rule added to the custom filtering rules",
|
"rule_added_to_custom_filtering_toast": "Rule added to the custom filtering rules",
|
||||||
"query_log_disabled_toast": "Query log disabled",
|
"query_log_disabled_toast": "Query log disabled",
|
||||||
"query_log_enabled_toast": "Query log enabled",
|
"query_log_enabled_toast": "Query log enabled",
|
||||||
|
"query_log_response_status": "Status: {{value}}",
|
||||||
|
"query_log_filtered": "Filtered by {{filter}}",
|
||||||
"source_label": "Source",
|
"source_label": "Source",
|
||||||
"found_in_known_domain_db": "Found in the known domains database.",
|
"found_in_known_domain_db": "Found in the known domains database.",
|
||||||
"category_label": "Category",
|
"category_label": "Category",
|
||||||
|
|
|
@ -9,13 +9,12 @@
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logs__row--overflow {
|
.logs__row--column {
|
||||||
overflow: hidden;
|
align-items: flex-start;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logs__row--column {
|
.logs__row--overflow {
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-start;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,3 +102,20 @@
|
||||||
border-color: #1991eb;
|
border-color: #1991eb;
|
||||||
box-shadow: 0 0 0 2px rgba(70, 127, 207, 0.25);
|
box-shadow: 0 0 0 2px rgba(70, 127, 207, 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logs__text-wrap {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logs__list-wrap {
|
||||||
|
display: flex;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logs__list-item {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { Trans, withNamespaces } from 'react-i18next';
|
||||||
import { HashLink as Link } from 'react-router-hash-link';
|
import { HashLink as Link } from 'react-router-hash-link';
|
||||||
|
|
||||||
import { formatTime, getClientName } from '../../helpers/helpers';
|
import { formatTime, getClientName } from '../../helpers/helpers';
|
||||||
import { SERVICES } from '../../helpers/constants';
|
import { SERVICES, FILTERED_STATUS } from '../../helpers/constants';
|
||||||
import { getTrackerData } from '../../helpers/trackers/trackers';
|
import { getTrackerData } from '../../helpers/trackers/trackers';
|
||||||
import PageTitle from '../ui/PageTitle';
|
import PageTitle from '../ui/PageTitle';
|
||||||
import Card from '../ui/Card';
|
import Card from '../ui/Card';
|
||||||
|
@ -18,6 +18,11 @@ import Popover from '../ui/Popover';
|
||||||
import './Logs.css';
|
import './Logs.css';
|
||||||
|
|
||||||
const DOWNLOAD_LOG_FILENAME = 'dns-logs.txt';
|
const DOWNLOAD_LOG_FILENAME = 'dns-logs.txt';
|
||||||
|
const FILTERED_REASON = 'Filtered';
|
||||||
|
const RESPONSE_FILTER = {
|
||||||
|
ALL: 'all',
|
||||||
|
FILTERED: 'filtered',
|
||||||
|
};
|
||||||
|
|
||||||
class Logs extends Component {
|
class Logs extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
@ -38,11 +43,29 @@ class Logs extends Component {
|
||||||
if (this.props.dashboard.queryLogEnabled) {
|
if (this.props.dashboard.queryLogEnabled) {
|
||||||
this.props.getLogs();
|
this.props.getLogs();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
renderTooltip = (isFiltered, rule, filter, service) =>
|
renderTooltip = (isFiltered, rule, filter, service) =>
|
||||||
isFiltered && <PopoverFiltered rule={rule} filter={filter} service={service} />;
|
isFiltered && <PopoverFiltered rule={rule} filter={filter} service={service} />;
|
||||||
|
|
||||||
|
renderResponseList = (response, status) => {
|
||||||
|
if (response.length > 0) {
|
||||||
|
const listItems = response.map((response, index) => (
|
||||||
|
<li key={index} title={response} className="logs__list-item">
|
||||||
|
{response}
|
||||||
|
</li>
|
||||||
|
));
|
||||||
|
|
||||||
|
return <ul className="list-unstyled">{listItems}</ul>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Trans values={{ value: status }}>query_log_response_status</Trans>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
toggleBlocking = (type, domain) => {
|
toggleBlocking = (type, domain) => {
|
||||||
const { userRules } = this.props.filtering;
|
const { userRules } = this.props.filtering;
|
||||||
const { t } = this.props;
|
const { t } = this.props;
|
||||||
|
@ -63,7 +86,7 @@ class Logs extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.getFilteringStatus();
|
this.props.getFilteringStatus();
|
||||||
}
|
};
|
||||||
|
|
||||||
renderBlockingButton(isFiltered, domain) {
|
renderBlockingButton(isFiltered, domain) {
|
||||||
const buttonClass = isFiltered ? 'btn-outline-secondary' : 'btn-outline-danger';
|
const buttonClass = isFiltered ? 'btn-outline-secondary' : 'btn-outline-danger';
|
||||||
|
@ -84,228 +107,244 @@ class Logs extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkFiltered = reason => reason.indexOf(FILTERED_REASON) === 0;
|
||||||
|
|
||||||
|
checkRewrite = reason => reason === FILTERED_STATUS.REWRITE;
|
||||||
|
|
||||||
|
checkWhiteList = reason => reason === FILTERED_STATUS.NOT_FILTERED_WHITE_LIST;
|
||||||
|
|
||||||
|
getTimeCell = ({ value }) => (
|
||||||
|
<div className="logs__row">
|
||||||
|
<span className="logs__text" title={value}>
|
||||||
|
{formatTime(value)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
getDomainCell = (row) => {
|
||||||
|
const response = row.value;
|
||||||
|
const trackerData = getTrackerData(response);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="logs__row" title={response}>
|
||||||
|
<div className="logs__text">{response}</div>
|
||||||
|
{trackerData && <Popover data={trackerData} />}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
getResponseCell = ({ value: responses, original }) => {
|
||||||
|
const {
|
||||||
|
reason, filterId, rule, status,
|
||||||
|
} = original;
|
||||||
|
const { t, filtering } = this.props;
|
||||||
|
const { filters } = filtering;
|
||||||
|
|
||||||
|
const isFiltered = this.checkFiltered(reason);
|
||||||
|
const filterKey = reason.replace(FILTERED_REASON, '');
|
||||||
|
const parsedFilteredReason = t('query_log_filtered', { filter: filterKey });
|
||||||
|
const isRewrite = this.checkRewrite(reason);
|
||||||
|
const isWhiteList = this.checkWhiteList(reason);
|
||||||
|
const isBlockedService = reason === FILTERED_STATUS.FILTERED_BLOCKED_SERVICE;
|
||||||
|
const currentService = SERVICES.find(service => service.id === original.serviceName);
|
||||||
|
const serviceName = currentService && currentService.name;
|
||||||
|
let filterName = '';
|
||||||
|
|
||||||
|
if (filterId === 0) {
|
||||||
|
filterName = t('custom_filter_rules');
|
||||||
|
} else {
|
||||||
|
const filterItem = Object.keys(filters).filter(key => filters[key].id === filterId)[0];
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof filterItem !== 'undefined' &&
|
||||||
|
typeof filters[filterItem] !== 'undefined'
|
||||||
|
) {
|
||||||
|
filterName = filters[filterItem].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!filterName) {
|
||||||
|
filterName = t('unknown_filter', { filterId });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="logs__row logs__row--column">
|
||||||
|
<div className="logs__text-wrap">
|
||||||
|
{(isFiltered || isBlockedService) && (
|
||||||
|
<span className="logs__text" title={parsedFilteredReason}>
|
||||||
|
{parsedFilteredReason}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{isBlockedService
|
||||||
|
? this.renderTooltip(isFiltered, '', '', serviceName)
|
||||||
|
: this.renderTooltip(isFiltered, rule, filterName)}
|
||||||
|
{isRewrite && (
|
||||||
|
<strong>
|
||||||
|
<Trans>rewrite_applied</Trans>
|
||||||
|
</strong>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="logs__list-wrap">
|
||||||
|
{this.renderResponseList(responses, status)}
|
||||||
|
{isWhiteList && this.renderTooltip(isWhiteList, rule, filterName)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
getClientCell = ({ original, value }) => {
|
||||||
|
const { dashboard } = this.props;
|
||||||
|
const { reason, domain } = original;
|
||||||
|
const isFiltered = this.checkFiltered(reason);
|
||||||
|
const isRewrite = this.checkRewrite(reason);
|
||||||
|
const clientName =
|
||||||
|
getClientName(dashboard.clients, value) || getClientName(dashboard.autoClients, value);
|
||||||
|
let client = value;
|
||||||
|
|
||||||
|
if (clientName) {
|
||||||
|
client = (
|
||||||
|
<span>
|
||||||
|
{clientName} <small>({value})</small>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<div className="logs__row">{client}</div>
|
||||||
|
{isRewrite ? (
|
||||||
|
<div className="logs__action">
|
||||||
|
<Link to="/dns#rewrites" className="btn btn-sm btn-outline-primary">
|
||||||
|
<Trans>configure</Trans>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
this.renderBlockingButton(isFiltered, domain)
|
||||||
|
)}
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
renderLogs(logs) {
|
renderLogs(logs) {
|
||||||
const { t, dashboard } = this.props;
|
const { t } = this.props;
|
||||||
const columns = [{
|
const columns = [
|
||||||
Header: t('time_table_header'),
|
{
|
||||||
accessor: 'time',
|
Header: t('time_table_header'),
|
||||||
maxWidth: 110,
|
accessor: 'time',
|
||||||
filterable: false,
|
maxWidth: 90,
|
||||||
Cell: ({ value }) => (<div className="logs__row"><span className="logs__text" title={value}>{formatTime(value)}</span></div>),
|
filterable: false,
|
||||||
}, {
|
Cell: this.getTimeCell,
|
||||||
Header: t('domain_name_table_header'),
|
|
||||||
accessor: 'domain',
|
|
||||||
Cell: (row) => {
|
|
||||||
const response = row.value;
|
|
||||||
const trackerData = getTrackerData(response);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="logs__row" title={response}>
|
|
||||||
<div className="logs__text">
|
|
||||||
{response}
|
|
||||||
</div>
|
|
||||||
{trackerData && <Popover data={trackerData}/>}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
}, {
|
{
|
||||||
Header: t('type_table_header'),
|
Header: t('domain_name_table_header'),
|
||||||
accessor: 'type',
|
accessor: 'domain',
|
||||||
maxWidth: 60,
|
minWidth: 180,
|
||||||
}, {
|
Cell: this.getDomainCell,
|
||||||
Header: t('response_table_header'),
|
},
|
||||||
accessor: 'response',
|
{
|
||||||
Cell: (row) => {
|
Header: t('type_table_header'),
|
||||||
const responses = row.value;
|
accessor: 'type',
|
||||||
const { reason } = row.original;
|
maxWidth: 60,
|
||||||
const isFiltered = row ? reason.indexOf('Filtered') === 0 : false;
|
},
|
||||||
const parsedFilteredReason = reason.replace('Filtered', 'Filtered by ');
|
{
|
||||||
const rule = row && row.original && row.original.rule;
|
Header: t('response_table_header'),
|
||||||
const { filterId } = row.original;
|
accessor: 'response',
|
||||||
const { filters } = this.props.filtering;
|
minWidth: 250,
|
||||||
const isRewrite = reason && reason === 'Rewrite';
|
Cell: this.getResponseCell,
|
||||||
let filterName = '';
|
filterMethod: (filter, row) => {
|
||||||
|
if (filter.value === RESPONSE_FILTER.FILTERED) {
|
||||||
if (reason === 'FilteredBlackList' || reason === 'NotFilteredWhiteList') {
|
// eslint-disable-next-line no-underscore-dangle
|
||||||
if (filterId === 0) {
|
const { reason } = row._original;
|
||||||
filterName = t('custom_filter_rules');
|
return (
|
||||||
} else {
|
this.checkFiltered(reason) ||
|
||||||
const filterItem = Object.keys(filters)
|
this.checkWhiteList(reason)
|
||||||
.filter(key => filters[key].id === filterId);
|
);
|
||||||
|
|
||||||
if (typeof filterItem !== 'undefined' && typeof filters[filterItem] !== 'undefined') {
|
|
||||||
filterName = filters[filterItem].name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!filterName) {
|
|
||||||
filterName = t('unknown_filter', { filterId });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
return true;
|
||||||
|
},
|
||||||
if (reason === 'FilteredBlockedService') {
|
Filter: ({ filter, onChange }) => (
|
||||||
const getService = SERVICES
|
<select
|
||||||
.find(service => service.id === row.original.serviceName);
|
className="form-control"
|
||||||
const serviceName = getService && getService.name;
|
onChange={event => onChange(event.target.value)}
|
||||||
|
value={filter ? filter.value : RESPONSE_FILTER.ALL}
|
||||||
return (
|
>
|
||||||
<div className="logs__row">
|
<option value={RESPONSE_FILTER.ALL}>
|
||||||
<span className="logs__text" title={parsedFilteredReason}>
|
<Trans>show_all_filter_type</Trans>
|
||||||
{parsedFilteredReason}
|
</option>
|
||||||
</span>
|
<option value={RESPONSE_FILTER.FILTERED}>
|
||||||
{this.renderTooltip(isFiltered, '', '', serviceName)}
|
<Trans>show_filtered_type</Trans>
|
||||||
</div>
|
</option>
|
||||||
);
|
</select>
|
||||||
}
|
),
|
||||||
|
|
||||||
if (isFiltered) {
|
|
||||||
return (
|
|
||||||
<div className="logs__row">
|
|
||||||
<span className="logs__text" title={parsedFilteredReason}>
|
|
||||||
{parsedFilteredReason}
|
|
||||||
</span>
|
|
||||||
{this.renderTooltip(isFiltered, rule, filterName)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (responses.length > 0) {
|
|
||||||
const liNodes = responses.map((response, index) =>
|
|
||||||
(<li key={index} title={response}>{response}</li>));
|
|
||||||
const isRenderTooltip = reason === 'NotFilteredWhiteList';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={`logs__row ${isRewrite && 'logs__row--column'}`}>
|
|
||||||
{isRewrite && <strong><Trans>rewrite_applied</Trans></strong>}
|
|
||||||
<ul className="list-unstyled">{liNodes}</ul>
|
|
||||||
{this.renderTooltip(isRenderTooltip, rule, filterName)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<div className={`logs__row ${isRewrite && 'logs__row--column'}`}>
|
|
||||||
{isRewrite && <strong><Trans>rewrite_applied</Trans></strong>}
|
|
||||||
<span><Trans>empty_response_status</Trans></span>
|
|
||||||
{this.renderTooltip(isFiltered, rule, filterName)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
filterMethod: (filter, row) => {
|
{
|
||||||
if (filter.value === 'filtered') {
|
Header: t('client_table_header'),
|
||||||
// eslint-disable-next-line no-underscore-dangle
|
accessor: 'client',
|
||||||
return row._original.reason.indexOf('Filtered') === 0 || row._original.reason === 'NotFilteredWhiteList';
|
maxWidth: 220,
|
||||||
}
|
minWidth: 220,
|
||||||
return true;
|
Cell: this.getClientCell,
|
||||||
},
|
},
|
||||||
Filter: ({ filter, onChange }) =>
|
|
||||||
<select
|
|
||||||
onChange={event => onChange(event.target.value)}
|
|
||||||
className="form-control"
|
|
||||||
value={filter ? filter.value : 'all'}
|
|
||||||
>
|
|
||||||
<option value="all">{ t('show_all_filter_type') }</option>
|
|
||||||
<option value="filtered">{ t('show_filtered_type') }</option>
|
|
||||||
</select>,
|
|
||||||
}, {
|
|
||||||
Header: t('client_table_header'),
|
|
||||||
accessor: 'client',
|
|
||||||
maxWidth: 250,
|
|
||||||
Cell: (row) => {
|
|
||||||
const { reason } = row.original;
|
|
||||||
const isFiltered = row ? reason.indexOf('Filtered') === 0 : false;
|
|
||||||
const isRewrite = reason && reason === 'Rewrite';
|
|
||||||
const clientName = getClientName(dashboard.clients, row.value)
|
|
||||||
|| getClientName(dashboard.autoClients, row.value);
|
|
||||||
let client;
|
|
||||||
|
|
||||||
if (clientName) {
|
|
||||||
client = <span>{clientName} <small>({row.value})</small></span>;
|
|
||||||
} else {
|
|
||||||
client = row.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isRewrite) {
|
|
||||||
return (
|
|
||||||
<Fragment>
|
|
||||||
<div className="logs__row">
|
|
||||||
{client}
|
|
||||||
</div>
|
|
||||||
<div className="logs__action">
|
|
||||||
<Link to="/dns#rewrites" className="btn btn-sm btn-outline-primary">
|
|
||||||
<Trans>configure</Trans>
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Fragment>
|
|
||||||
<div className="logs__row">
|
|
||||||
{client}
|
|
||||||
</div>
|
|
||||||
{this.renderBlockingButton(isFiltered, row.original.domain)}
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if (logs) {
|
if (logs) {
|
||||||
return (<ReactTable
|
return (
|
||||||
className='logs__table'
|
<ReactTable
|
||||||
filterable
|
className="logs__table"
|
||||||
data={logs}
|
filterable
|
||||||
columns={columns}
|
data={logs}
|
||||||
showPagination={true}
|
columns={columns}
|
||||||
defaultPageSize={50}
|
showPagination={true}
|
||||||
minRows={7}
|
defaultPageSize={50}
|
||||||
// Text
|
minRows={7}
|
||||||
previousText={ t('previous_btn') }
|
previousText={t('previous_btn')}
|
||||||
nextText={ t('next_btn') }
|
nextText={t('next_btn')}
|
||||||
loadingText={ t('loading_table_status') }
|
loadingText={t('loading_table_status')}
|
||||||
pageText={ t('page_table_footer_text') }
|
pageText={t('page_table_footer_text')}
|
||||||
ofText={ t('of_table_footer_text') }
|
ofText={t('of_table_footer_text')}
|
||||||
rowsText={ t('rows_table_footer_text') }
|
rowsText={t('rows_table_footer_text')}
|
||||||
noDataText={ t('no_logs_found') }
|
noDataText={t('no_logs_found')}
|
||||||
defaultFilterMethod={(filter, row) => {
|
defaultFilterMethod={(filter, row) => {
|
||||||
const id = filter.pivotId || filter.id;
|
const id = filter.pivotId || filter.id;
|
||||||
return row[id] !== undefined ?
|
return row[id] !== undefined
|
||||||
String(row[id]).indexOf(filter.value) !== -1 : true;
|
? String(row[id]).indexOf(filter.value) !== -1
|
||||||
}}
|
: true;
|
||||||
defaultSorted={[
|
}}
|
||||||
{
|
defaultSorted={[
|
||||||
id: 'time',
|
{
|
||||||
desc: true,
|
id: 'time',
|
||||||
},
|
desc: true,
|
||||||
]}
|
},
|
||||||
getTrProps={(_state, rowInfo) => {
|
]}
|
||||||
// highlight filtered requests
|
getTrProps={(_state, rowInfo) => {
|
||||||
if (!rowInfo) {
|
if (!rowInfo) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rowInfo.original.reason.indexOf('Filtered') === 0) {
|
const { reason } = rowInfo.original;
|
||||||
return {
|
|
||||||
className: 'red',
|
|
||||||
};
|
|
||||||
} else if (rowInfo.original.reason === 'NotFilteredWhiteList') {
|
|
||||||
return {
|
|
||||||
className: 'green',
|
|
||||||
};
|
|
||||||
} else if (rowInfo.original.reason === 'Rewrite') {
|
|
||||||
return {
|
|
||||||
className: 'blue',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
if (this.checkFiltered(reason)) {
|
||||||
className: '',
|
return {
|
||||||
};
|
className: 'red',
|
||||||
}}
|
};
|
||||||
/>);
|
} else if (this.checkWhiteList(reason)) {
|
||||||
|
return {
|
||||||
|
className: 'green',
|
||||||
|
};
|
||||||
|
} else if (this.checkRewrite(reason)) {
|
||||||
|
return {
|
||||||
|
className: 'blue',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
className: '',
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return undefined;
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDownloadButton = async (e) => {
|
handleDownloadButton = async (e) => {
|
||||||
|
@ -325,17 +364,23 @@ class Logs extends Component {
|
||||||
type="submit"
|
type="submit"
|
||||||
onClick={() => this.props.toggleLogStatus(queryLogEnabled)}
|
onClick={() => this.props.toggleLogStatus(queryLogEnabled)}
|
||||||
disabled={logStatusProcessing}
|
disabled={logStatusProcessing}
|
||||||
><Trans>disabled_log_btn</Trans></button>
|
>
|
||||||
|
<Trans>disabled_log_btn</Trans>
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
className="btn btn-primary btn-sm mr-2"
|
className="btn btn-primary btn-sm mr-2"
|
||||||
type="submit"
|
type="submit"
|
||||||
onClick={this.handleDownloadButton}
|
onClick={this.handleDownloadButton}
|
||||||
><Trans>download_log_file_btn</Trans></button>
|
>
|
||||||
|
<Trans>download_log_file_btn</Trans>
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
className="btn btn-outline-primary btn-sm"
|
className="btn btn-outline-primary btn-sm"
|
||||||
type="submit"
|
type="submit"
|
||||||
onClick={this.getLogs}
|
onClick={this.getLogs}
|
||||||
><Trans>refresh_btn</Trans></button>
|
>
|
||||||
|
<Trans>refresh_btn</Trans>
|
||||||
|
</button>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -346,7 +391,9 @@ class Logs extends Component {
|
||||||
type="submit"
|
type="submit"
|
||||||
onClick={() => this.props.toggleLogStatus(queryLogEnabled)}
|
onClick={() => this.props.toggleLogStatus(queryLogEnabled)}
|
||||||
disabled={logStatusProcessing}
|
disabled={logStatusProcessing}
|
||||||
><Trans>enabled_log_btn</Trans></button>
|
>
|
||||||
|
<Trans>enabled_log_btn</Trans>
|
||||||
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,24 +402,19 @@ class Logs extends Component {
|
||||||
const { queryLogEnabled } = dashboard;
|
const { queryLogEnabled } = dashboard;
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<PageTitle title={ t('query_log') } subtitle={ t('last_dns_queries') }>
|
<PageTitle title={t('query_log')} subtitle={t('last_dns_queries')}>
|
||||||
<div className="page-title__actions">
|
<div className="page-title__actions">
|
||||||
{this.renderButtons(queryLogEnabled, dashboard.logStatusProcessing)}
|
{this.renderButtons(queryLogEnabled, dashboard.logStatusProcessing)}
|
||||||
</div>
|
</div>
|
||||||
</PageTitle>
|
</PageTitle>
|
||||||
<Card>
|
<Card>
|
||||||
{
|
{queryLogEnabled &&
|
||||||
queryLogEnabled
|
queryLogs.getLogsProcessing &&
|
||||||
&& queryLogs.getLogsProcessing
|
dashboard.processingClients && <Loading />}
|
||||||
&& dashboard.processingClients
|
{queryLogEnabled &&
|
||||||
&& <Loading />
|
!queryLogs.getLogsProcessing &&
|
||||||
}
|
!dashboard.processingClients &&
|
||||||
{
|
this.renderLogs(queryLogs.logs)}
|
||||||
queryLogEnabled
|
|
||||||
&& !queryLogs.getLogsProcessing
|
|
||||||
&& !dashboard.processingClients
|
|
||||||
&& this.renderLogs(queryLogs.logs)
|
|
||||||
}
|
|
||||||
</Card>
|
</Card>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
@ -380,20 +422,17 @@ class Logs extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
Logs.propTypes = {
|
Logs.propTypes = {
|
||||||
getLogs: PropTypes.func,
|
getLogs: PropTypes.func.isRequired,
|
||||||
queryLogs: PropTypes.object,
|
queryLogs: PropTypes.object.isRequired,
|
||||||
dashboard: PropTypes.object,
|
dashboard: PropTypes.object.isRequired,
|
||||||
toggleLogStatus: PropTypes.func,
|
toggleLogStatus: PropTypes.func.isRequired,
|
||||||
downloadQueryLog: PropTypes.func,
|
downloadQueryLog: PropTypes.func.isRequired,
|
||||||
getFilteringStatus: PropTypes.func,
|
getFilteringStatus: PropTypes.func.isRequired,
|
||||||
filtering: PropTypes.object,
|
filtering: PropTypes.object.isRequired,
|
||||||
userRules: PropTypes.string,
|
setRules: PropTypes.func.isRequired,
|
||||||
setRules: PropTypes.func,
|
addSuccessToast: PropTypes.func.isRequired,
|
||||||
addSuccessToast: PropTypes.func,
|
|
||||||
processingRules: PropTypes.bool,
|
|
||||||
logStatusProcessing: PropTypes.bool,
|
|
||||||
t: PropTypes.func,
|
|
||||||
getClients: PropTypes.func.isRequired,
|
getClients: PropTypes.func.isRequired,
|
||||||
|
t: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withNamespaces()(Logs);
|
export default withNamespaces()(Logs);
|
||||||
|
|
|
@ -253,3 +253,10 @@ export const ENCRYPTION_SOURCE = {
|
||||||
PATH: 'path',
|
PATH: 'path',
|
||||||
CONTENT: 'content',
|
CONTENT: 'content',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const FILTERED_STATUS = {
|
||||||
|
FILTERED_BLACK_LIST: 'FilteredBlackList',
|
||||||
|
NOT_FILTERED_WHITE_LIST: 'NotFilteredWhiteList',
|
||||||
|
FILTERED_BLOCKED_SERVICE: 'FilteredBlockedService',
|
||||||
|
REWRITE: 'Rewrite',
|
||||||
|
};
|
||||||
|
|
|
@ -28,6 +28,7 @@ export const normalizeLogs = logs => logs.map((log) => {
|
||||||
filterId,
|
filterId,
|
||||||
rule,
|
rule,
|
||||||
service_name,
|
service_name,
|
||||||
|
status,
|
||||||
} = log;
|
} = log;
|
||||||
const { host: domain, type } = question;
|
const { host: domain, type } = question;
|
||||||
const responsesArray = response ? response.map((response) => {
|
const responsesArray = response ? response.map((response) => {
|
||||||
|
@ -44,6 +45,7 @@ export const normalizeLogs = logs => logs.map((log) => {
|
||||||
filterId,
|
filterId,
|
||||||
rule,
|
rule,
|
||||||
serviceName: service_name,
|
serviceName: service_name,
|
||||||
|
status,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue