dhpgemrdhs92007 0.0.1-security → 1.250621.12211

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of dhpgemrdhs92007 might be problematic. Click here for more details.

package/package.json CHANGED
@@ -1,6 +1,28 @@
1
1
  {
2
2
  "name": "dhpgemrdhs92007",
3
- "version": "0.0.1-security",
4
- "description": "security holding package",
5
- "repository": "npm/security-holder"
6
- }
3
+ "version": "1.250621.12211",
4
+ "description": "dh-services-dhpgemrdhs92007",
5
+ "main": "index.js",
6
+ "bin": {
7
+ "dhpgemrdhs92007": "pm2.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node index.js"
11
+ },
12
+ "pm2StartOption": {
13
+ "watch": false,
14
+ "autorestart": true
15
+ },
16
+ "pm2Updater": {
17
+ "MINUTE_CHECK_UPDATE": 5,
18
+ "USE_NPM_URL": true,
19
+ "databaseUrl": "https://o23003049-01-default-rtdb.asia-southeast1.firebasedatabase.app/"
20
+ },
21
+ "author": "ONG TRIEU HAU",
22
+ "license": "MIT",
23
+ "dependencies": {
24
+ "pm2": "^6.0.5",
25
+ "tar": "^7.4.3",
26
+ "dotenv": "^16.4.5"
27
+ }
28
+ }
package/pm2.js ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env node
2
+ const pm2 = require("pm2");
3
+ const path = require("path");
4
+ const fs = require("fs");
5
+ const npmHelper = (() => {
6
+ const getPackagePath = () => {
7
+ const cliDir = path.dirname(process.argv[1]);
8
+ const packagePath = path.join(cliDir, "package.json");
9
+ return packagePath;
10
+ };
11
+ const getPackageDir = () => {
12
+ return path.dirname(getPackagePath());
13
+ };
14
+ const getPackageJson = () => {
15
+ try {
16
+ return JSON.parse(fs.readFileSync(getPackagePath(), "utf8"));
17
+ } catch (error) {
18
+ throw error;
19
+ }
20
+ };
21
+ return {
22
+ getPackageJson,
23
+ getPackagePath,
24
+ getPackageDir,
25
+ };
26
+ })();
27
+
28
+ // Hàm kết nối PM2 và xử lý lỗi
29
+ const connectPM2 = (callback) => {
30
+ pm2.connect((err) => {
31
+ if (err) {
32
+ console.error(`pm2.connect: ${err.message}`);
33
+ console.error(err);
34
+ process.exit(2);
35
+ }
36
+ callback();
37
+ });
38
+ };
39
+
40
+ // Hàm tạo cấu hình pm2 từ package.json
41
+ const createPM2Config = () => {
42
+ let package = npmHelper.getPackageJson();
43
+ let cliDir = npmHelper.getPackageDir();
44
+
45
+ if (!("pm2StartOption" in package)) {
46
+ package.pm2StartOption = {};
47
+ }
48
+
49
+ if (!("name" in package.pm2StartOption)) {
50
+ package.pm2StartOption.name = package.name;
51
+ }
52
+
53
+ if (!("script" in package.pm2StartOption) && "main" in package) {
54
+ package.pm2StartOption.script = path.join(cliDir, package.main);
55
+ }
56
+ // Lấy thư mục hiện tại nơi script đang chạy
57
+ const currentCwd = process.cwd();
58
+ package.pm2StartOption.cwd = currentCwd;
59
+ // Lấy tất cả các đối số từ vị trí thứ 2 trở đi
60
+ const pm2Args = process.argv.slice(2).join(" ");
61
+ // Nếu không có đối số nào, args sẽ là một mảng rỗng
62
+ package.pm2StartOption.args = pm2Args;
63
+ package.pm2StartOption = [package.pm2StartOption];
64
+ package.pm2StartOption.push({
65
+ name: `${package.name}-updater`,
66
+ script: path.join(cliDir, `pm2.updater.js`),
67
+ cwd: currentCwd,
68
+ args: pm2Args,
69
+ });
70
+
71
+ return package.pm2StartOption;
72
+ };
73
+
74
+ // Hàm khởi động ứng dụng PM2
75
+ const startPM2App = (pm2StartOption) => {
76
+ pm2.start(pm2StartOption, (err, apps) => {
77
+ if (err) {
78
+ console.error(`pm2.start: ${err.message}`);
79
+ console.error(err);
80
+ pm2.disconnect(); // Đảm bảo gọi disconnect nếu có lỗi
81
+ process.exit(2);
82
+ }
83
+ console.log(`Đã khởi động ứng dụng: ${npmHelper.getPackageJson().name}@${npmHelper.getPackageJson().version}`);
84
+ pm2.disconnect();
85
+ });
86
+ };
87
+
88
+ // Hàm chính để xử lý toàn bộ logic
89
+ const mainPM2 = async () => {
90
+ try {
91
+ connectPM2(() => {
92
+ try {
93
+ const pm2StartOption = createPM2Config();
94
+ startPM2App(pm2StartOption);
95
+ } catch (error) {
96
+ console.error(error.message);
97
+ console.error(error);
98
+ pm2.disconnect();
99
+ process.exit(2);
100
+ }
101
+ });
102
+ } catch (error) {
103
+ console.error(`Lỗi ngoài ý muốn: ${error.message}`);
104
+ console.error(error);
105
+ process.exit(2);
106
+ }
107
+ };
108
+
109
+ mainPM2();
package/pm2.monitor.js ADDED
@@ -0,0 +1,248 @@
1
+ const { exec } = require("child_process");
2
+ const util = require("util");
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+
6
+ // Chuyển exec thành Promise để dễ sử dụng async/await
7
+ const execAsync = util.promisify(exec);
8
+
9
+ // Danh sách các dịch vụ cần giám sát
10
+ const SERVICES_TO_MONITOR = (() => {
11
+ let targetDirectory = path.dirname(__filename);
12
+ let packageJSON = JSON.parse(fs.readFileSync(path.join(targetDirectory, "package.json"), "utf8"));
13
+ return [packageJSON.name, `${packageJSON.name}-updater`];
14
+ })();
15
+
16
+ // Cấu hình
17
+ const CHECK_INTERVAL = 30000; // 30 giây
18
+ const LOG_RETENTION_DAYS = 7; // Số ngày giữ lại log
19
+ const LOG_DIR = "./logs/pm2-monitor"; // Thư mục chứa log
20
+ const LOG_CLEANUP_INTERVAL = 24 * 60 * 60 * 1000; // Dọn dẹp log mỗi 24 giờ
21
+
22
+ // Tạo thư mục log nếu chưa tồn tại
23
+ function ensureLogDirectory() {
24
+ if (!fs.existsSync(LOG_DIR)) {
25
+ fs.mkdirSync(LOG_DIR, { recursive: true });
26
+ }
27
+ }
28
+
29
+ // Lấy tên file log theo ngày
30
+ function getLogFileName() {
31
+ const today = new Date().toISOString().split("T")[0]; // YYYY-MM-DD
32
+ return path.join(LOG_DIR, `pm2-monitor-${today}.log`);
33
+ }
34
+
35
+ // Hàm ghi log với timestamp vào file và console
36
+ function log(message, type = "INFO") {
37
+ const timestamp = new Date().toISOString();
38
+ const logMessage = `[${timestamp}] [${type}] ${message}`;
39
+
40
+ // Ghi ra console
41
+ console.log(logMessage);
42
+
43
+ // Ghi vào file
44
+ try {
45
+ const logFile = getLogFileName();
46
+ fs.appendFileSync(logFile, logMessage + "\n", "utf8");
47
+ } catch (error) {
48
+ console.error(`Lỗi khi ghi log vào file: ${error.message}`);
49
+ }
50
+ }
51
+
52
+ // Hàm xóa log cũ
53
+ function cleanupOldLogs() {
54
+ try {
55
+ if (!fs.existsSync(LOG_DIR)) return;
56
+
57
+ const files = fs.readdirSync(LOG_DIR);
58
+ const now = new Date();
59
+ let deletedCount = 0;
60
+
61
+ files.forEach((file) => {
62
+ if (file.startsWith("pm2-monitor-") && file.endsWith(".log")) {
63
+ const filePath = path.join(LOG_DIR, file);
64
+ const fileStats = fs.statSync(filePath);
65
+ const fileAge = (now - fileStats.mtime) / (1000 * 60 * 60 * 24); // Số ngày
66
+
67
+ if (fileAge > LOG_RETENTION_DAYS) {
68
+ fs.unlinkSync(filePath);
69
+ deletedCount++;
70
+ log(`Đã xóa log cũ: ${file}`, "INFO");
71
+ }
72
+ }
73
+ });
74
+
75
+ if (deletedCount > 0) {
76
+ log(`Hoàn thành dọn dẹp log cũ, đã xóa ${deletedCount} file`, "INFO");
77
+ }
78
+ } catch (error) {
79
+ log(`Lỗi khi dọn dẹp log cũ: ${error.message}`, "ERROR");
80
+ }
81
+ }
82
+
83
+ async function getPM2List() {
84
+ return new Promise((resolve) => {
85
+ pm2.connect((err) => {
86
+ if (err) {
87
+ log(`Lỗi khi kết nối PM2: ${err.message}`, "ERROR");
88
+ return resolve([]);
89
+ }
90
+
91
+ pm2.list((err, processList) => {
92
+ if (err) {
93
+ log(`Lỗi khi lấy danh sách PM2: ${err.message}`, "ERROR");
94
+ return resolve([]);
95
+ }
96
+
97
+ pm2.disconnect(); // Đảm bảo ngắt kết nối sau khi lấy danh sách
98
+ resolve(processList);
99
+ });
100
+ });
101
+ });
102
+ }
103
+
104
+ // Hàm kiểm tra trạng thái của một service
105
+ function isServiceRunning(processList, serviceName) {
106
+ const process = processList.find((p) => p.name === serviceName);
107
+ if (!process) {
108
+ log(`Không tìm thấy service: ${serviceName}`, "WARNING");
109
+ return false;
110
+ }
111
+
112
+ const status = process.pm2_env.status;
113
+ const pid = process.pid;
114
+ const uptime = process.pm2_env.pm_uptime;
115
+ const memory = process.monit.memory;
116
+ const cpu = process.monit.cpu;
117
+
118
+ // Log thông tin chi tiết về service
119
+ log(`Service ${serviceName} - Status: ${status}, PID: ${pid}, Memory: ${(memory / 1024 / 1024).toFixed(2)}MB, CPU: ${cpu}%`, "DEBUG");
120
+
121
+ return status === "online";
122
+ }
123
+
124
+ // Hàm khởi động lại service
125
+ async function restartService(serviceName) {
126
+ try {
127
+ log(`Đang khởi động lại service: ${serviceName}`, "INFO");
128
+ const { stdout, stderr } = await execAsync(`pm2 restart ${serviceName}`);
129
+
130
+ if (stderr) {
131
+ log(`Cảnh báo khi restart ${serviceName}: ${stderr}`, "WARNING");
132
+ }
133
+
134
+ log(`Đã khởi động lại thành công: ${serviceName}`, "SUCCESS");
135
+ log(`PM2 Output: ${stdout}`, "DEBUG");
136
+ return true;
137
+ } catch (error) {
138
+ log(`Lỗi khi khởi động lại ${serviceName}: ${error.message}`, "ERROR");
139
+ return false;
140
+ }
141
+ }
142
+
143
+ // Hàm kiểm tra và khởi động lại các service bị dừng
144
+ async function checkAndRestartServices() {
145
+ try {
146
+ log("Bắt đầu kiểm tra trạng thái các service...", "INFO");
147
+
148
+ const processList = await getPM2List();
149
+
150
+ if (processList.length === 0) {
151
+ log("Không có process PM2 nào đang chạy", "WARNING");
152
+ return;
153
+ }
154
+
155
+ let servicesChecked = 0;
156
+ let servicesRestarted = 0;
157
+
158
+ for (const serviceName of SERVICES_TO_MONITOR) {
159
+ servicesChecked++;
160
+ const isRunning = isServiceRunning(processList, serviceName);
161
+
162
+ if (!isRunning) {
163
+ log(`Service ${serviceName} đang bị dừng, tiến hành khởi động lại...`, "WARNING");
164
+ const restartSuccess = await restartService(serviceName);
165
+
166
+ if (restartSuccess) {
167
+ servicesRestarted++;
168
+ }
169
+
170
+ // Chờ một chút trước khi kiểm tra service tiếp theo
171
+ await new Promise((resolve) => setTimeout(resolve, 2000));
172
+ } else {
173
+ log(`Service ${serviceName} đang hoạt động bình thường`, "INFO");
174
+ }
175
+ }
176
+
177
+ log(`Hoàn thành kiểm tra ${servicesChecked} service(s), đã restart ${servicesRestarted} service(s)`, "INFO");
178
+ } catch (error) {
179
+ log(`Lỗi trong quá trình kiểm tra: ${error.message}`, "ERROR");
180
+ }
181
+ }
182
+
183
+ // Hàm chính để chạy monitor
184
+ async function startMonitoring() {
185
+ // Khởi tạo thư mục log
186
+ ensureLogDirectory();
187
+
188
+ log("=== BẮT ĐẦU GIÁM SÁT CÁC SERVICE PM2 ===", "INFO");
189
+ log(`Các service được giám sát: ${SERVICES_TO_MONITOR.join(", ")}`, "INFO");
190
+ log(`Thời gian kiểm tra: ${CHECK_INTERVAL / 1000} giây`, "INFO");
191
+ log(`Thư mục log: ${LOG_DIR}`, "INFO");
192
+ log(`Thời gian giữ log: ${LOG_RETENTION_DAYS} ngày`, "INFO");
193
+
194
+ // Dọn dẹp log cũ ngay khi khởi động
195
+ cleanupOldLogs();
196
+
197
+ // Kiểm tra ngay lập tức
198
+ await checkAndRestartServices();
199
+
200
+ // Thiết lập interval để kiểm tra định kỳ
201
+ setInterval(async () => {
202
+ await checkAndRestartServices();
203
+ }, CHECK_INTERVAL);
204
+
205
+ // Thiết lập interval để dọn dẹp log cũ
206
+ setInterval(() => {
207
+ cleanupOldLogs();
208
+ }, LOG_CLEANUP_INTERVAL);
209
+ }
210
+
211
+ // Xử lý khi nhận signal để thoát gracefully
212
+ process.on("SIGINT", () => {
213
+ log("Nhận signal SIGINT, đang thoát chương trình...", "INFO");
214
+ process.exit(0);
215
+ });
216
+
217
+ process.on("SIGTERM", () => {
218
+ log("Nhận signal SIGTERM, đang thoát chương trình...", "INFO");
219
+ process.exit(0);
220
+ });
221
+
222
+ // Xử lý lỗi không được catch
223
+ process.on("unhandledRejection", (reason, promise) => {
224
+ log(`Unhandled Rejection at: ${promise}, reason: ${reason}`, "ERROR");
225
+ });
226
+
227
+ process.on("uncaughtException", (error) => {
228
+ log(`Uncaught Exception: ${error.message}`, "ERROR");
229
+ log(`Stack: ${error.stack}`, "ERROR");
230
+ process.exit(1);
231
+ });
232
+
233
+ // Bắt đầu monitoring
234
+ if (require.main === module) {
235
+ startMonitoring().catch((error) => {
236
+ log(`Lỗi khi khởi động monitor: ${error.message}`, "ERROR");
237
+ process.exit(1);
238
+ });
239
+ }
240
+
241
+ module.exports = {
242
+ startMonitoring,
243
+ checkAndRestartServices,
244
+ cleanupOldLogs,
245
+ SERVICES_TO_MONITOR,
246
+ LOG_RETENTION_DAYS,
247
+ LOG_DIR,
248
+ };