-
Notifications
You must be signed in to change notification settings - Fork 14
/
Snapshot.ts
123 lines (100 loc) · 3.25 KB
/
Snapshot.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import * as Fs from "fs";
import { hostname } from "os";
import { Fetch } from "planck-http-fetch";
import { error, info } from "./Log";
const INACTIVE_AFTER_M = 5;
export interface IAuth {
user: string;
password: string;
}
export interface IShapshotConfig {
snapshot: {
url?: string;
auth?: IAuth,
token?: string;
disabled?: boolean;
inactiveAfterM?: number;
}
}
interface IValue {
v: any;
bad?: boolean;
}
export interface IPayload {
token?: string;
host: string,
timeStamp?: number,
app: {
[appId: number]: {
name: string;
metric: {
[key: string]: {
history: boolean;
v: IValue;
};
};
timeStamp?: number;
inactive: boolean;
}
}
}
export class Snapshot {
private _data: IPayload = {
host: hostname(),
app: {}
};
constructor(private _config: IShapshotConfig) {
if (!this._config.snapshot)
this._config.snapshot = {};
this._data.token = this._config.snapshot.token;
if (this._config.snapshot.inactiveAfterM == null)
this._config.snapshot.inactiveAfterM = INACTIVE_AFTER_M;
}
push(appId: number, app: string, key: string, history: boolean, v: IValue) {
if (!this._data.app[appId])
this._data.app[appId] = { name: app, metric: {}, inactive: false };
this._data.app[appId].timeStamp = new Date().getTime();
this._data.app[appId].metric[key] = { history, v };
}
last(appId: number, key: string) {
if (!this._data.app[appId] || !this._data.app[appId].metric[key])
return undefined;
return this._data.app[appId].metric[key].v.v;
}
dump() {
this._data.timeStamp = new Date().getTime();
Fs.writeFile(`History_${new Date().toISOString()}.json`, JSON.stringify(this._data), (ex) => {
if (ex)
error(`can't dump history -> ${ex.message || ex}`);
});
}
async send() {
if (!this._config.snapshot.url || !this._config.snapshot.token || this._config.snapshot.disabled === true)
return;
try {
this._data.timeStamp = new Date().getTime();
const fetch = new Fetch(this._config.snapshot.url);
if (this._config.snapshot.auth && this._config.snapshot.auth.user) // auth
fetch.basicAuth(this._config.snapshot.auth.user, this._config.snapshot.auth.password);
await fetch.fetch(JSON.stringify(this._data));
}
catch (ex) {
error(`snapshot push failed -> ${ex.message || ex}`);
}
}
/**
* detects if application is inactive based on last received probe time
*/
inactivate() {
const t = new Date().getTime();
for (const id of Object.keys(this._data.app)) {
const
app = this._data.app[<any>id],
dt = (t - app.timeStamp) / 60000;
const inactive = dt > this._config.snapshot.inactiveAfterM;
if (app.inactive !== inactive)
info(`app [${app.name}] inactive = ${inactive}`);
app.inactive = inactive;
}
}
}