Skip to content

Commit

Permalink
get top ip addresses list (last year by default) - #36
Browse files Browse the repository at this point in the history
  • Loading branch information
matyaskopp committed Nov 29, 2021
1 parent 2a6504d commit 27a64c4
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 6 deletions.
4 changes: 2 additions & 2 deletions app/controllers/dataController.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ exports.getUsers = (userId) => {
});
};

exports.getIPs = (userId) => {
exports.getTopIPs = (userId) => {
logger.trace();
return new promise((resolve, reject) => {
db.ip.getRecent()
db.ip.getTop()
.then(data => {
db.user.logAction(userId, 'listIPs');
resolve(data);
Expand Down
149 changes: 149 additions & 0 deletions app/db/ip.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@ const config = require('config');
const promise = require('bluebird');
const logger = require('../logger');
const db = require('./connection');
const moment = require('moment');

const date2string_def = {
'month': {
'full': 'YYYY-MM-01 00:00:00',
'header': 'YYYY-MM'
},
'day': {
'full': 'YYYY-MM-DD 00:00:00',
'header': 'YYYY-MM-DD'
}
};

exports.get = () => {
logger.trace();
Expand Down Expand Up @@ -45,6 +57,143 @@ exports.get = () => {
});
};


function date2string(date=new Date(), level='month', type='full'){
return date.format(date2string_def[level][type])
}


function createFilter(filter){

logger.warn('IP filter is not implemented');
var query={
'pivot_ip': {
'filter_ip' : '',
'filter_period' : '',
'filter_service' : ' AND lg.service_id IS NULL '
},
'pivot_val': { // change to row !!!
'filter_service' : ' AND data.service_id IS NULL '
},
'pivot_col': {
'names': ' ip INET ',
'values': ''
}
};
var values={};
var header=['ip'];

values.level = filter.period.level;
values.period_interval = '1 ' + values.level;
query.pivot_ip.filter_period = ' AND lg.period_start_date >= \'$<filter.period_start>\' AND lg.period_end_date < \'$<filter.period_end>\' ';
values.period_start = date2string(filter.period.start,filter.period.level,'full');
values.period_end = date2string(filter.period.end,filter.period.level,'full');
query.pivot_col.values = `generate_series(
date_trunc(\'$<filter.level>\', timestamp \'$<filter.period_start>\'),
date_trunc(\'$<filter.level>\', timestamp \'$<filter.period_end>\' - interval \'$<filter.period_interval>\'),
\'$<filter.period_interval>\'::interval
)`;

var date_i = filter.period.start;
while(date_i < filter.period.end){
var date_str = date2string(date_i,filter.period.level,'header');
query.pivot_col.names += ', "'+date_str+'" BIGINT ';
header.push(date_str);
date_i = date_i.add(1,filter.period.level+'s');
}
if(typeof filter.service_id !== 'undefined'){
logger.warn('result contains only single/all services');
query.pivot_ip.filter_service = ' AND lg.service_id = $<filter.service_id> ';
query.pivot_val.filter_service = ' AND data.service_id = $<filter.service_id> ';
values.service_id = filter.service_id;
}

return {
query: query,
values: values,
header: header
}
}



exports.getTop = (filter={},
period_start = (new Date().getFullYear())+'-01-01 00:00:00',
period_end = (new Date().getFullYear() + 1)+'-01-01 00:00:00',
measure='units',
level='month',
min_exist = 0
) => {
logger.trace();
logger.warn('db.ip.getTop() uses only default settings !!!');
const {query, values, header} = createFilter({
'period': {
'start': moment(period_start),
'end': moment(period_end),
'level': level
},
'value':{
'measure': measure,
'min_exist': min_exist
},
...filter
});
return new promise((resolve, reject) => {
db.any(`
SELECT *
FROM crosstab(
'SELECT top.ip,to_char(data.period_start_date,''YYYY-MM-DD 00:00:00''),COALESCE(data.cnt_${measure},0)
FROM
( SELECT DISTINCT ip
FROM log_ip_aggr lg
WHERE
lg.cnt_${measure} > $<min_exist>
AND lg.period_level=\'$<filter.level>\'::period_levels
${query.pivot_ip.filter_ip}
${query.pivot_ip.filter_period} -- AND lg.period_start_date >= ''2021-01-01 00:00:00'' AND lg.period_end_date < ''2022-01-01 00:00:00''
${query.pivot_ip.filter_service} -- AND lg.service_id IS NULL
) AS top
JOIN log_ip_aggr data
ON data.ip = top.ip
WHERE data.period_level=\'$<filter.level>\'::period_levels
${query.pivot_val.filter_service} -- AND data.service_id IS NULL
ORDER BY 1,2',
'SELECT s::timestamp
FROM
${query.pivot_col.values} s'
) as pivot (
-- column names
${query.pivot_col.names}
);
`, {
'min_exist': min_exist,
'filter': values
})
.then(data => {
logger.trace();
if (data) {
resolve({data: data, header: header}); // data
}
else {
reject({
state: 'failure',
reason: 'No IPs returned',
extra: null
});
}
})
.catch(error => {
logger.trace();
logger.error(error);
reject({
state: 'failure',
reason: 'Database error',
extra: error
});
});
});
};

exports.getRecent = () => { /* return only last three months*/
logger.trace();
return new promise((resolve, reject) => {
Expand Down
4 changes: 2 additions & 2 deletions app/routes/apiRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,8 @@ router.get('/api/ips', function (req, res, next) {
error : 'Permission Denied.'
});
} else {
dataController.getIPs(user.user_id).then(data => {
res.json({"data": data});
dataController.getTopIPs(user.user_id).then(data => {
res.json(data);
}).catch();
}
});
Expand Down
3 changes: 1 addition & 2 deletions app/views/ips.pug
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@ block content
.row
.col.s12
h6 Last three months IP list
table.striped(type='lb-datatable' data-type='json' data-field='data' data-url='api/ips' data-header='["IP", "Requests", "Units", "Requests", "Units", "Requests", "Units", "Requests", "Units"]' data-items='["ip", "m2_requests", "m2_units", "m1_requests", "m1_units", "m0_requests", "m0_units", "requests", "units"]' )
table.striped(type='lb-datatable' data-type='json' data-field='data' data-url='api/ips' data-header-field='header' data-items-field='header' )
script.
[ {
"targets": 0,
"data": null,
"render": function ( data, type, row, meta ) {return '<a class="clr-bg-add btn-floating btn-small" href="admin/add-endpoint?ip='+data[0]+'" title="create endpoint from IP address"><i class="material-icons tiny">settings_input_component</i></a> <a class="clr-fg-link" href="admin/ip/'+data[0]+'">'+data[0]+'</a>';}
}

]

1 change: 1 addition & 0 deletions scripts/database-patch02.sh
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ LANGUAGE plpgsql;
CREATE TRIGGER user_endpoints_copy_ip_aggr AFTER INSERT ON user_endpoints FOR ROW EXECUTE PROCEDURE trigger_add_endpoint_copy_ip_aggr();
CREATE EXTENSION IF NOT EXISTS tablefunc;
INSERT INTO db_schema_version(version, script_path)
VALUES(2, 'scripts/database-patch02.sh') ON CONFLICT DO NOTHING;
Expand Down

0 comments on commit 27a64c4

Please sign in to comment.