badmfck-api-server 2.8.5 → 2.8.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -88,7 +88,7 @@ async function Initializer(services) {
88
88
  exports.Initializer = Initializer;
89
89
  class APIService extends BaseService_1.BaseService {
90
90
  static nextLogID = 0;
91
- version = "2.8.5";
91
+ version = "2.8.6";
92
92
  options;
93
93
  monitor = null;
94
94
  monitorIndexFile;
@@ -388,6 +388,7 @@ class APIService extends BaseService_1.BaseService {
388
388
  log.time = data.responseTime;
389
389
  log.referer = ref;
390
390
  }
391
+ MonitorService_1.S_STAT_REGISTRATE_REQUEST.invoke(data);
391
392
  if (res.destroyed || res.closed) {
392
393
  if (log)
393
394
  log.error = "Connection already closed, can't send response for: " + data.endpoint;
@@ -1,4 +1,27 @@
1
+ import Signal, { Req } from "badmfck-signal";
1
2
  import { BaseService } from "./BaseService";
3
+ import { TransferPacketVO } from "./structures/Interfaces";
4
+ export interface IEPStat {
5
+ success: number;
6
+ fail: number;
7
+ }
8
+ export interface IEPStatReqFilter {
9
+ range: "minute" | "hour" | "day";
10
+ from: string;
11
+ to: string;
12
+ ep: string;
13
+ }
14
+ export interface IEPStatResult {
15
+ }
16
+ export declare const S_STAT_REGISTRATE_REQUEST: Signal<TransferPacketVO<any>>;
17
+ export declare const REQ_EP_STAT: Req<IEPStatReqFilter, IEPStatResult>;
2
18
  export declare class MonitorService extends BaseService {
19
+ endpoints: Map<number, Map<string, IEPStat>>;
3
20
  constructor();
21
+ getEPStat(req: IEPStatReqFilter): Promise<IEPStatResult>;
22
+ onStatRegistrate(data: TransferPacketVO): void;
23
+ pad(num: number): string;
24
+ getMinutes(date: Date): number;
25
+ getDate(minutes: number): Date;
26
+ getMinutesInMonth(date: Date): number;
4
27
  }
@@ -1,10 +1,137 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MonitorService = void 0;
26
+ exports.MonitorService = exports.REQ_EP_STAT = exports.S_STAT_REGISTRATE_REQUEST = void 0;
27
+ const badmfck_signal_1 = __importStar(require("badmfck-signal"));
4
28
  const BaseService_1 = require("./BaseService");
29
+ exports.S_STAT_REGISTRATE_REQUEST = new badmfck_signal_1.default();
30
+ exports.REQ_EP_STAT = new badmfck_signal_1.Req(undefined, "REQ_EP_STAT");
5
31
  class MonitorService extends BaseService_1.BaseService {
32
+ endpoints = new Map();
6
33
  constructor() {
7
34
  super("MonitorService");
35
+ exports.S_STAT_REGISTRATE_REQUEST.subscribe(this.onStatRegistrate);
36
+ exports.REQ_EP_STAT.listener = async (req) => this.getEPStat(req);
37
+ }
38
+ async getEPStat(req) {
39
+ const result = new Map();
40
+ if (req.range === "hour") {
41
+ for (let [minute, minuteSlot] of this.endpoints) {
42
+ const date = this.getDate(minute);
43
+ let range = minute + "";
44
+ if (req.range === "hour")
45
+ range = this.pad(this.getDate(minute).getHours());
46
+ else if (req.range === "day")
47
+ range = this.pad(this.getDate(minute).getDate());
48
+ if (req.from) {
49
+ if (range < req.from)
50
+ continue;
51
+ }
52
+ if (req.to) {
53
+ if (range > req.to)
54
+ continue;
55
+ }
56
+ let resultSlot = result.get(range);
57
+ if (!resultSlot) {
58
+ resultSlot = new Map();
59
+ result.set(range, resultSlot);
60
+ }
61
+ let epSlot = resultSlot.get(req.ep);
62
+ if (!epSlot) {
63
+ epSlot = { success: 0, fail: 0 };
64
+ resultSlot.set(req.ep, epSlot);
65
+ }
66
+ for (let [ep, stat] of minuteSlot) {
67
+ epSlot.success += stat.success;
68
+ epSlot.fail += stat.fail;
69
+ }
70
+ }
71
+ }
72
+ const endResult = [];
73
+ for (let [date, obj] of result) {
74
+ const stat = {
75
+ date,
76
+ data: []
77
+ };
78
+ for (let [ep, s] of obj) {
79
+ const r = { ep, ...s };
80
+ stat.data.push(r);
81
+ }
82
+ endResult.push(stat);
83
+ }
84
+ return { filter: req, result: endResult };
85
+ }
86
+ onStatRegistrate(data) {
87
+ const minute = this.getMinutes(new Date());
88
+ let minuteSlot = this.endpoints.get(minute);
89
+ if (!minuteSlot) {
90
+ minuteSlot = new Map();
91
+ this.endpoints.set(minute, minuteSlot);
92
+ }
93
+ if (!data.endpoint)
94
+ data.endpoint = "unknown";
95
+ let epSlot = minuteSlot.get(data.endpoint);
96
+ if (!epSlot) {
97
+ epSlot = { success: 0, fail: 0 };
98
+ minuteSlot.set(data.endpoint, epSlot);
99
+ }
100
+ if (data.error) {
101
+ epSlot.fail++;
102
+ }
103
+ else {
104
+ epSlot.success++;
105
+ }
106
+ if (this.endpoints.size > 3000) {
107
+ const firstItem = this.endpoints.keys().next().value;
108
+ if (firstItem)
109
+ this.endpoints.delete(firstItem);
110
+ }
111
+ }
112
+ pad(num) {
113
+ return num.toString().padStart(2, '0');
114
+ }
115
+ getMinutes(date) {
116
+ const year = date.getFullYear();
117
+ const month = this.pad(date.getMonth() + 1);
118
+ const day = this.pad(date.getDate());
119
+ const hours = this.pad(date.getHours());
120
+ const minutes = this.pad(date.getMinutes());
121
+ return parseInt(`${year}${month}${day}${hours}${minutes}`);
122
+ }
123
+ getDate(minutes) {
124
+ const datetime = minutes.toString();
125
+ const year = parseInt(datetime.slice(0, 4));
126
+ const month = parseInt(datetime.slice(4, 6)) - 1;
127
+ const day = parseInt(datetime.slice(6, 8));
128
+ const hours = parseInt(datetime.slice(8, 10));
129
+ const min = parseInt(datetime.slice(10, 12));
130
+ return new Date(year, month, day, hours, min);
131
+ }
132
+ getMinutesInMonth(date) {
133
+ const daysInMonth = date.getDate();
134
+ return daysInMonth * 1440;
8
135
  }
9
136
  }
10
137
  exports.MonitorService = MonitorService;
@@ -11,6 +11,7 @@ const LogService_1 = require("../LogService");
11
11
  const crypto_1 = __importDefault(require("crypto"));
12
12
  const os_1 = __importDefault(require("os"));
13
13
  const DefaultErrors_1 = __importDefault(require("../structures/DefaultErrors"));
14
+ const MonitorService_1 = require("../MonitorService");
14
15
  exports.S_MONITOR_REGISTRATE_ACTION = new badmfck_signal_1.Signal();
15
16
  class Monitor extends BaseEndpoint_1.BaseEndpoint {
16
17
  ignoreHttpLogging = true;
@@ -43,7 +44,8 @@ class Monitor extends BaseEndpoint_1.BaseEndpoint {
43
44
  }
44
45
  async metrics(req) {
45
46
  this.checkAuthentication(req);
46
- return {};
47
+ const result = await MonitorService_1.REQ_EP_STAT.request(req.data);
48
+ return { data: result };
47
49
  }
48
50
  async serverStat(req) {
49
51
  this.checkAuthentication(req);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "badmfck-api-server",
3
- "version": "2.8.5",
3
+ "version": "2.8.6",
4
4
  "description": "Simple API http server based on express",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",