123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- import { Meteor } from 'meteor/meteor';
- import Users from '../users';
- function acceptedIpAddress(ipAddress) {
- const trustedIpAddress = process.env.METRICS_ACCEPTED_IP_ADDRESS;
- return (
- trustedIpAddress !== undefined &&
- trustedIpAddress.split(',').includes(ipAddress)
- );
- }
- function accessToken(req) {
- const valid_token = process.env.METRICS_ACCESS_TOKEN;
- let token;
- if (req.headers && req.headers.authorization) {
- var parts = req.headers.authorization.split(" ");
- if (parts.length === 2) {
- var scheme = parts[0];
- var credentials = parts[1];
- if (/^Bearer$/i.test(scheme)) {
- token = credentials;
- }
- }
- }
- if (!token && req.query && req.query.access_token) {
- token = req.query.access_token;
- }
- return (
- token !== undefined &&
- valid_token !== undefined &&
- token == valid_token
- );
- }
- const getBoardTitleWithMostActivities = (dateWithXdaysAgo, nbLimit) => {
- return Promise.await(
- Activities.rawCollection()
- .aggregate([
- {
- $match: { modifiedAt: { $gte: dateWithXdaysAgo }}
- },
- {
- $group: { _id: '$boardId', count: { $sum: 1 } }
- },
- {
- $sort: { count: -1 }
- },
- {
- $lookup: { from: 'boards', localField: '_id', foreignField: '_id', as: 'lookup'}
- },
- {
- $project: { "lookup.title":1, "count":1}
- }])
- .limit(nbLimit).toArray()
- );
- };
- const getBoards = (boardIds) => {
- const ret = ReactiveCache.getBoards({ _id: { $in: boardIds } });
- return ret;
- };
- Meteor.startup(() => {
- WebApp.connectHandlers.use('/metrics', (req, res, next) => {
- try {
- const ipAddress =
- req.headers['x-forwarded-for'] || req.socket.remoteAddress;
- // if(process.env.TRUST_PROXY_FORXARD)
- // {
- // const ipAddress = req.headers['x-forwarded-for'] || req.socket.remoteAddress
- // }else{
- // const ipAddress = req.socket.remoteAddress
- // }
- // List of trusted ip adress will be found in environment variable "METRICS_ACCEPTED_IP_ADDRESS" (separeted with commas)
- if (acceptedIpAddress(ipAddress) || (accessToken(req))) {
- let metricsRes = '';
- let resCount = 0;
- //connected users
- metricsRes += '# Number of connected users\n';
- // Get number of connected user by using meteor socketJs
- const allOpenedSockets = Meteor.server.stream_server.open_sockets;
- let connectedUserIds = [];
- allOpenedSockets.forEach(
- (socket) =>
- socket._meteorSession.userId !== null &&
- connectedUserIds.push(socket._meteorSession.userId),
- );
- resCount = connectedUserIds.length; // KPI 1
- metricsRes += 'wekan_connectedUsers ' + resCount + '\n';
- //registered users
- metricsRes += '# Number of registered users\n';
- // Get number of registered user
- resCount = ReactiveCache.getUsers({}).length; // KPI 2
- metricsRes += 'wekan_registeredUsers ' + resCount + '\n';
- resCount = 0;
- //board numbers
- metricsRes += '# Number of registered boards\n';
- // Get number of registered boards
- resCount = ReactiveCache.getBoards({ archived: false, type: 'board' }).length; // KPI 3
- metricsRes += 'wekan_registeredboards ' + resCount + '\n';
- resCount = 0;
- //board numbers by registered users
- metricsRes += '# Number of registered boards by registered users\n';
- // Get number of registered boards by registered users
- resCount =
- ReactiveCache.getBoards({ archived: false, type: 'board' }).length /
- ReactiveCache.getUsers({}).length; // KPI 4
- metricsRes +=
- 'wekan_registeredboardsBysRegisteredUsers ' + resCount + '\n';
- resCount = 0;
- //board numbers with only one member
- metricsRes += '# Number of registered boards\n';
- // Get board numbers with only one member
- resCount = ReactiveCache.getBoards({
- archived: false,
- type: 'board',
- members: { $size: 1 },
- }).length; // KPI 5
- metricsRes +=
- 'wekan_registeredboardsWithOnlyOneMember ' + resCount + '\n';
- resCount = 0;
- // KPI 6 : - store last login date
- // KPI 6 = count where date of last connection > x days
- // Cutting in label since 5 days / 10 days / 20 days / 30 days
- //Number of users with last connection dated 5 days ago
- metricsRes +=
- '# Number of users with last connection dated 5 days ago\n';
- // Get number of users with last connection dated 5 days ago
- let xdays = 5;
- let dateWithXdaysAgo = new Date(
- new Date() - xdays * 24 * 60 * 60 * 1000,
- );
- resCount = ReactiveCache.getUsers({
- lastConnectionDate: { $gte: dateWithXdaysAgo },
- }).length; // KPI 5
- metricsRes +=
- 'wekan_usersWithLastConnectionDated5DaysAgo ' + resCount + '\n';
- resCount = 0;
- metricsRes +=
- '# Number of users with last connection dated 10 days ago\n';
- // Get number of users with last connection dated 10 days ago
- xdays = 10;
- dateWithXdaysAgo = new Date(new Date() - xdays * 24 * 60 * 60 * 1000);
- resCount = ReactiveCache.getUsers({
- lastConnectionDate: { $gte: dateWithXdaysAgo },
- }).length; // KPI 5
- metricsRes +=
- 'wekan_usersWithLastConnectionDated10DaysAgo ' + resCount + '\n';
- resCount = 0;
- metricsRes +=
- '# Number of users with last connection dated 20 days ago\n';
- // Get number of users with last connection dated 20 days ago
- xdays = 20;
- dateWithXdaysAgo = new Date(new Date() - xdays * 24 * 60 * 60 * 1000);
- resCount = ReactiveCache.getUsers({
- lastConnectionDate: { $gte: dateWithXdaysAgo },
- }).length; // KPI 5
- metricsRes +=
- 'wekan_usersWithLastConnectionDated20DaysAgo ' + resCount + '\n';
- resCount = 0;
- metricsRes +=
- '# Number of users with last connection dated 30 days ago\n';
- // Get number of users with last connection dated 20 days ago
- xdays = 30;
- dateWithXdaysAgo = new Date(new Date() - xdays * 24 * 60 * 60 * 1000);
- resCount = ReactiveCache.getUsers({
- lastConnectionDate: { $gte: dateWithXdaysAgo },
- }).length; // KPI 5
- metricsRes +=
- 'wekan_usersWithLastConnectionDated30DaysAgo ' + resCount + '\n';
- resCount = 0;
- // TO DO:
- // connection average: ((disconnection date - last connection date) + (last average)) / 2
- // KPI 7 : sum of connection average / number of users (ignore users with 0 average)
- metricsRes +=
- '# Top 10 boards with most activities dated 30 days ago\n';
- //Get top 10 table with most activities in current month
- const boardTitleWithMostActivities = getBoardTitleWithMostActivities(
- dateWithXdaysAgo,
- xdays,
- );
- const boardWithMostActivities = boardTitleWithMostActivities.map(
- (board) => board.lookup[0].title,
- );
- boardWithMostActivities.forEach((title, index) => {
- metricsRes +=
- `wekan_top10BoardsWithMostActivities{n="${title}"} ${
- index + 1
- }` + '\n';
- });
- res.writeHead(200); // HTTP status
- res.end(metricsRes);
- } else {
- res.writeHead(401); // HTTP status
- res.end(
- 'IpAddress: ' +
- ipAddress +
- ' is not authorized to perform this action !!\n',
- );
- }
- } catch (e) {
- res.writeHead(500); // HTTP status
- res.end(e.toString());
- }
- });
- });
|