node-consul-service 1.0.71 → 1.0.73
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.
- package/dist/atlas/atlas.client.d.ts +22 -0
- package/dist/consul/client.d.ts +4 -2
- package/dist/index.cjs.js +291 -204
- package/dist/index.esm.js +291 -205
- package/dist/utils/slowCallLogger.d.ts +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface AtlasClientOptions {
|
|
2
|
+
host?: string;
|
|
3
|
+
port?: number;
|
|
4
|
+
secure?: boolean;
|
|
5
|
+
version?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class AtlasClient {
|
|
8
|
+
private client;
|
|
9
|
+
private version;
|
|
10
|
+
constructor(options?: AtlasClientOptions);
|
|
11
|
+
registerService(data: {
|
|
12
|
+
name: string;
|
|
13
|
+
address: string;
|
|
14
|
+
port: number;
|
|
15
|
+
tags?: string[];
|
|
16
|
+
meta?: Record<string, any>;
|
|
17
|
+
}): Promise<any>;
|
|
18
|
+
getRandomService(name: string): Promise<any>;
|
|
19
|
+
listServices(): Promise<any>;
|
|
20
|
+
checkHealth(): Promise<any>;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
package/dist/consul/client.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import Consul from
|
|
1
|
+
import Consul from 'consul';
|
|
2
|
+
import { AtlasClient } from '../atlas/atlas.client';
|
|
2
3
|
export interface ConsulClientOptions {
|
|
3
4
|
host?: string;
|
|
4
5
|
port?: number;
|
|
5
6
|
secure?: boolean;
|
|
6
7
|
}
|
|
7
8
|
export declare function toBoolean(value?: string | boolean | null): boolean;
|
|
8
|
-
export declare function initClient({ host, port, secure
|
|
9
|
+
export declare function initClient({ host, port, secure }: ConsulClientOptions): void;
|
|
10
|
+
export declare function getAtlasClient(): AtlasClient;
|
|
9
11
|
export declare function getClient(): Consul;
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var Consul = require('consul');
|
|
4
|
-
var require$$6 = require('fs');
|
|
5
|
-
var path = require('path');
|
|
6
4
|
var require$$1 = require('util');
|
|
7
5
|
var stream = require('stream');
|
|
6
|
+
var path = require('path');
|
|
8
7
|
var require$$3 = require('http');
|
|
9
8
|
var require$$4 = require('https');
|
|
10
9
|
var require$$0$1 = require('url');
|
|
10
|
+
var require$$6 = require('fs');
|
|
11
11
|
var crypto = require('crypto');
|
|
12
12
|
var require$$4$1 = require('assert');
|
|
13
13
|
var require$$1$1 = require('tty');
|
|
@@ -15,188 +15,6 @@ var require$$0$2 = require('os');
|
|
|
15
15
|
var zlib = require('zlib');
|
|
16
16
|
var events = require('events');
|
|
17
17
|
|
|
18
|
-
// src/lib/client.ts
|
|
19
|
-
let consulClient = null;
|
|
20
|
-
function toBoolean(value) {
|
|
21
|
-
if (typeof value === "boolean")
|
|
22
|
-
return value;
|
|
23
|
-
if (typeof value === "string")
|
|
24
|
-
return value.toLowerCase() === "true";
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
function initClient({ host = "127.0.0.1", port = 8500, secure = false, }) {
|
|
28
|
-
consulClient = new Consul({
|
|
29
|
-
host: host !== null && host !== void 0 ? host : "127.0.0.1",
|
|
30
|
-
port: port !== null && port !== void 0 ? port : 8500,
|
|
31
|
-
secure: toBoolean(secure),
|
|
32
|
-
});
|
|
33
|
-
consulClient.agent.self((err) => {
|
|
34
|
-
if (err) {
|
|
35
|
-
console.error("❌ Failed to connect to Consul:", err.message);
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
console.log("✅ Connected to Consul successfully");
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
function getClient() {
|
|
43
|
-
if (!consulClient) {
|
|
44
|
-
throw new Error("Consul client not initialized. Call initClient() first.");
|
|
45
|
-
}
|
|
46
|
-
return consulClient;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const registeredServices = new Set();
|
|
50
|
-
async function registerService(options) {
|
|
51
|
-
var _a, _b, _c, _d;
|
|
52
|
-
const { name, id, port, address = 'localhost', check, tags, meta, } = options;
|
|
53
|
-
if (registeredServices.has(id)) {
|
|
54
|
-
console.log(`⚠️ Service "${id}" is already registered.`);
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
const serviceDefinition = {
|
|
58
|
-
name,
|
|
59
|
-
id,
|
|
60
|
-
address,
|
|
61
|
-
port,
|
|
62
|
-
tags,
|
|
63
|
-
meta,
|
|
64
|
-
};
|
|
65
|
-
if (check !== false) {
|
|
66
|
-
const checkDefinition = {
|
|
67
|
-
name: (_a = check === null || check === void 0 ? void 0 : check.name) !== null && _a !== void 0 ? _a : `${name}-check`,
|
|
68
|
-
http: (_b = check === null || check === void 0 ? void 0 : check.http) !== null && _b !== void 0 ? _b : `http://${address}:${port}/health`,
|
|
69
|
-
interval: (_c = check === null || check === void 0 ? void 0 : check.interval) !== null && _c !== void 0 ? _c : '10s',
|
|
70
|
-
timeout: (_d = check === null || check === void 0 ? void 0 : check.timeout) !== null && _d !== void 0 ? _d : '5s',
|
|
71
|
-
};
|
|
72
|
-
if (check === null || check === void 0 ? void 0 : check.deregistercriticalserviceafter) {
|
|
73
|
-
checkDefinition.deregistercriticalserviceafter = check.deregistercriticalserviceafter;
|
|
74
|
-
}
|
|
75
|
-
serviceDefinition.check = checkDefinition;
|
|
76
|
-
}
|
|
77
|
-
await getClient().agent.service.register(serviceDefinition);
|
|
78
|
-
registeredServices.add(id);
|
|
79
|
-
console.log(`✅ Service "${id}" registered successfully.`);
|
|
80
|
-
}
|
|
81
|
-
async function deregisterService(id) {
|
|
82
|
-
if (!registeredServices.has(id)) {
|
|
83
|
-
console.log(`⚠️ Service "${id}" is not registered.`);
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
await getClient().agent.service.deregister(id);
|
|
87
|
-
registeredServices.delete(id);
|
|
88
|
-
console.log(`🛑 Service "${id}" deregistered successfully.`);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const BASE_LOG_DIR$1 = '/home/log';
|
|
92
|
-
// اسم السيرفس الحالي اللي بيعمل الـ discovery
|
|
93
|
-
const CURRENT_SERVICE$1 = process.env.SERVICE_NAME || 'unknown-service';
|
|
94
|
-
async function ensureLogDir$1(dir) {
|
|
95
|
-
await require$$6.promises.mkdir(dir, { recursive: true });
|
|
96
|
-
}
|
|
97
|
-
function formatLogLine(targetService, instance, elapsedMs) {
|
|
98
|
-
var _a, _b, _c, _d, _e;
|
|
99
|
-
const ts = new Date().toISOString();
|
|
100
|
-
const addr = (_b = (_a = instance.ServiceAddress) !== null && _a !== void 0 ? _a : instance.Address) !== null && _b !== void 0 ? _b : 'unknown';
|
|
101
|
-
const port = (_c = instance.ServicePort) !== null && _c !== void 0 ? _c : 'unknown';
|
|
102
|
-
const node = (_d = instance.Node) !== null && _d !== void 0 ? _d : 'N/A';
|
|
103
|
-
const id = (_e = instance.ServiceID) !== null && _e !== void 0 ? _e : 'N/A';
|
|
104
|
-
const elapsed = elapsedMs !== undefined ? ` | Elapsed=${elapsedMs}ms` : '';
|
|
105
|
-
return `${ts} | Target=${targetService} | ${addr}:${port} | Node=${node} | ID=${id}${elapsed}\n`;
|
|
106
|
-
}
|
|
107
|
-
async function appendDiscoveryLog(targetService, instance, elapsedMs) {
|
|
108
|
-
try {
|
|
109
|
-
// فولدر خاص بالسيرفس الحالي
|
|
110
|
-
const serviceDir = path.join(BASE_LOG_DIR$1, CURRENT_SERVICE$1);
|
|
111
|
-
await ensureLogDir$1(serviceDir);
|
|
112
|
-
// اللوج يروح في ملف ثابت detect.log
|
|
113
|
-
const file = path.join(serviceDir, 'detect.log');
|
|
114
|
-
const line = formatLogLine(targetService, instance, elapsedMs);
|
|
115
|
-
await require$$6.promises.appendFile(file, line, { encoding: 'utf8' });
|
|
116
|
-
}
|
|
117
|
-
catch (err) {
|
|
118
|
-
console.error('❌ Failed to write discovery log:', err);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const store = new Map();
|
|
123
|
-
/**
|
|
124
|
-
* Set a value in memory with optional TTL (ms).
|
|
125
|
-
*/
|
|
126
|
-
function set(key, value, ttl) {
|
|
127
|
-
const record = { value };
|
|
128
|
-
{
|
|
129
|
-
record.expiresAt = Date.now() + ttl;
|
|
130
|
-
}
|
|
131
|
-
store.set(key, record);
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Get a value from memory.
|
|
135
|
-
* Returns undefined if key does not exist or expired.
|
|
136
|
-
*/
|
|
137
|
-
function get$1(key) {
|
|
138
|
-
const record = store.get(key);
|
|
139
|
-
if (!record)
|
|
140
|
-
return undefined;
|
|
141
|
-
if (record.expiresAt && record.expiresAt < Date.now()) {
|
|
142
|
-
store.delete(key);
|
|
143
|
-
return undefined;
|
|
144
|
-
}
|
|
145
|
-
return record.value;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const CACHE_TTL = 10000; // 10 ثواني – عدلها حسب احتياجك
|
|
149
|
-
async function listServices() {
|
|
150
|
-
const cacheKey = 'services:list';
|
|
151
|
-
const cached = get$1(cacheKey);
|
|
152
|
-
if (cached)
|
|
153
|
-
return cached;
|
|
154
|
-
const services = await getClient().agent.service.list();
|
|
155
|
-
const values = Object.values(services);
|
|
156
|
-
set(cacheKey, values, CACHE_TTL);
|
|
157
|
-
return values;
|
|
158
|
-
}
|
|
159
|
-
async function getServiceInstances(serviceName) {
|
|
160
|
-
const cacheKey = `services:${serviceName}`;
|
|
161
|
-
const cached = get$1(cacheKey);
|
|
162
|
-
if (cached)
|
|
163
|
-
return cached;
|
|
164
|
-
const start = Date.now();
|
|
165
|
-
const services = await getClient().catalog.service.nodes(serviceName);
|
|
166
|
-
const elapsed = Date.now() - start;
|
|
167
|
-
console.log(`⏱️ Discovery for ${serviceName} took ${elapsed}ms`);
|
|
168
|
-
set(cacheKey, services, CACHE_TTL);
|
|
169
|
-
return services;
|
|
170
|
-
}
|
|
171
|
-
async function getRandomServiceInstance(serviceName) {
|
|
172
|
-
const cacheKey = `random:${serviceName}`;
|
|
173
|
-
const cached = get$1(cacheKey);
|
|
174
|
-
if (cached)
|
|
175
|
-
return cached;
|
|
176
|
-
const start = Date.now();
|
|
177
|
-
const instances = await getServiceInstances(serviceName);
|
|
178
|
-
if (!instances.length)
|
|
179
|
-
throw new Error(`Service "${serviceName}" not found`);
|
|
180
|
-
const randomIndex = Math.floor(Math.random() * instances.length);
|
|
181
|
-
const instance = instances[randomIndex];
|
|
182
|
-
const elapsed = Date.now() - start;
|
|
183
|
-
await appendDiscoveryLog(serviceName, instance, elapsed);
|
|
184
|
-
// cache random instance
|
|
185
|
-
set(cacheKey, instance, CACHE_TTL);
|
|
186
|
-
return instance;
|
|
187
|
-
}
|
|
188
|
-
async function getServiceUrl(serviceName) {
|
|
189
|
-
const cacheKey = `url:${serviceName}`;
|
|
190
|
-
const cached = get$1(cacheKey);
|
|
191
|
-
if (cached)
|
|
192
|
-
return cached;
|
|
193
|
-
const instance = await getRandomServiceInstance(serviceName);
|
|
194
|
-
const url = `http://${instance.ServiceAddress}:${instance.ServicePort}`;
|
|
195
|
-
// cache url
|
|
196
|
-
set(cacheKey, url, CACHE_TTL);
|
|
197
|
-
return url;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
18
|
function bind(fn, thisArg) {
|
|
201
19
|
return function wrap() {
|
|
202
20
|
return fn.apply(thisArg, arguments);
|
|
@@ -13305,11 +13123,11 @@ function requireCallBindApplyHelpers () {
|
|
|
13305
13123
|
return callBindApplyHelpers;
|
|
13306
13124
|
}
|
|
13307
13125
|
|
|
13308
|
-
var get;
|
|
13126
|
+
var get$1;
|
|
13309
13127
|
var hasRequiredGet;
|
|
13310
13128
|
|
|
13311
13129
|
function requireGet () {
|
|
13312
|
-
if (hasRequiredGet) return get;
|
|
13130
|
+
if (hasRequiredGet) return get$1;
|
|
13313
13131
|
hasRequiredGet = 1;
|
|
13314
13132
|
|
|
13315
13133
|
var callBind = requireCallBindApplyHelpers();
|
|
@@ -13332,7 +13150,7 @@ function requireGet () {
|
|
|
13332
13150
|
var $getPrototypeOf = $Object.getPrototypeOf;
|
|
13333
13151
|
|
|
13334
13152
|
/** @type {import('./get')} */
|
|
13335
|
-
get = desc && typeof desc.get === 'function'
|
|
13153
|
+
get$1 = desc && typeof desc.get === 'function'
|
|
13336
13154
|
? callBind([desc.get])
|
|
13337
13155
|
: typeof $getPrototypeOf === 'function'
|
|
13338
13156
|
? /** @type {import('./get')} */ function getDunder(value) {
|
|
@@ -13340,7 +13158,7 @@ function requireGet () {
|
|
|
13340
13158
|
return $getPrototypeOf(value == null ? value : $Object(value));
|
|
13341
13159
|
}
|
|
13342
13160
|
: false;
|
|
13343
|
-
return get;
|
|
13161
|
+
return get$1;
|
|
13344
13162
|
}
|
|
13345
13163
|
|
|
13346
13164
|
var getProto;
|
|
@@ -14856,12 +14674,12 @@ const hasStandardBrowserWebWorkerEnv = (() => {
|
|
|
14856
14674
|
const origin = hasBrowserEnv && window.location.href || 'http://localhost';
|
|
14857
14675
|
|
|
14858
14676
|
var utils = /*#__PURE__*/Object.freeze({
|
|
14859
|
-
|
|
14860
|
-
|
|
14861
|
-
|
|
14862
|
-
|
|
14863
|
-
|
|
14864
|
-
|
|
14677
|
+
__proto__: null,
|
|
14678
|
+
hasBrowserEnv: hasBrowserEnv,
|
|
14679
|
+
hasStandardBrowserEnv: hasStandardBrowserEnv,
|
|
14680
|
+
hasStandardBrowserWebWorkerEnv: hasStandardBrowserWebWorkerEnv,
|
|
14681
|
+
navigator: _navigator,
|
|
14682
|
+
origin: origin
|
|
14865
14683
|
});
|
|
14866
14684
|
|
|
14867
14685
|
var platform = {
|
|
@@ -20312,14 +20130,250 @@ const {
|
|
|
20312
20130
|
mergeConfig
|
|
20313
20131
|
} = axios;
|
|
20314
20132
|
|
|
20315
|
-
|
|
20316
|
-
|
|
20317
|
-
|
|
20133
|
+
class AtlasClient {
|
|
20134
|
+
constructor(options) {
|
|
20135
|
+
var _a, _b, _c, _d, _e, _f;
|
|
20136
|
+
const host = (_b = (_a = options === null || options === void 0 ? void 0 : options.host) !== null && _a !== void 0 ? _a : process.env.ATLAS_HOST) !== null && _b !== void 0 ? _b : '127.0.0.1';
|
|
20137
|
+
const port = (_c = options === null || options === void 0 ? void 0 : options.port) !== null && _c !== void 0 ? _c : parseInt((_d = process.env.ATLAS_PORT) !== null && _d !== void 0 ? _d : '371', 10);
|
|
20138
|
+
const secure = (_e = options === null || options === void 0 ? void 0 : options.secure) !== null && _e !== void 0 ? _e : false;
|
|
20139
|
+
this.version = (_f = options === null || options === void 0 ? void 0 : options.version) !== null && _f !== void 0 ? _f : '1';
|
|
20140
|
+
const baseURL = `${secure ? 'https' : 'http'}://${host}:${port}/v${this.version}`;
|
|
20141
|
+
this.client = axios.create({ baseURL });
|
|
20142
|
+
}
|
|
20143
|
+
// تسجيل سيرفس
|
|
20144
|
+
async registerService(data) {
|
|
20145
|
+
const res = await this.client.post('/service/register', data);
|
|
20146
|
+
return res.data;
|
|
20147
|
+
}
|
|
20148
|
+
// جلب سيرفس عشوائي بالاسم
|
|
20149
|
+
async getRandomService(name) {
|
|
20150
|
+
const res = await this.client.get(`/service/random`, {
|
|
20151
|
+
params: { name },
|
|
20152
|
+
});
|
|
20153
|
+
return res.data;
|
|
20154
|
+
}
|
|
20155
|
+
// جلب كل السيرفسات
|
|
20156
|
+
async listServices() {
|
|
20157
|
+
const res = await this.client.get('/service/list');
|
|
20158
|
+
return res.data;
|
|
20159
|
+
}
|
|
20160
|
+
// Health Check بسيط
|
|
20161
|
+
async checkHealth() {
|
|
20162
|
+
const res = await this.client.get('/health');
|
|
20163
|
+
return res.data;
|
|
20164
|
+
}
|
|
20165
|
+
}
|
|
20166
|
+
|
|
20167
|
+
// src/lib/client.ts
|
|
20168
|
+
let consulClient = null;
|
|
20169
|
+
let atlasClient = null;
|
|
20170
|
+
function toBoolean(value) {
|
|
20171
|
+
if (typeof value === 'boolean')
|
|
20172
|
+
return value;
|
|
20173
|
+
if (typeof value === 'string')
|
|
20174
|
+
return value.toLowerCase() === 'true';
|
|
20175
|
+
return false;
|
|
20176
|
+
}
|
|
20177
|
+
function initClient({ host = '127.0.0.1', port = 8500, secure = false }) {
|
|
20178
|
+
atlasClient = new AtlasClient({
|
|
20179
|
+
host: host !== null && host !== void 0 ? host : '127.0.0.1',
|
|
20180
|
+
port: port !== null && port !== void 0 ? port : 371,
|
|
20181
|
+
version: '1',
|
|
20182
|
+
});
|
|
20183
|
+
consulClient = new Consul({
|
|
20184
|
+
host: host !== null && host !== void 0 ? host : '127.0.0.1',
|
|
20185
|
+
port: port !== null && port !== void 0 ? port : 8500,
|
|
20186
|
+
secure: toBoolean(secure),
|
|
20187
|
+
});
|
|
20188
|
+
consulClient.agent.self(err => {
|
|
20189
|
+
if (err) {
|
|
20190
|
+
console.error('❌ Failed to connect to Consul:', err.message);
|
|
20191
|
+
}
|
|
20192
|
+
else {
|
|
20193
|
+
console.log('✅ Connected to Consul successfully');
|
|
20194
|
+
}
|
|
20195
|
+
});
|
|
20196
|
+
}
|
|
20197
|
+
function getAtlasClient() {
|
|
20198
|
+
if (!atlasClient) {
|
|
20199
|
+
throw new Error('atlas client not initialized. Call initClient() first.');
|
|
20200
|
+
}
|
|
20201
|
+
return atlasClient;
|
|
20202
|
+
}
|
|
20203
|
+
function getClient() {
|
|
20204
|
+
if (!consulClient) {
|
|
20205
|
+
throw new Error('Consul client not initialized. Call initClient() first.');
|
|
20206
|
+
}
|
|
20207
|
+
return consulClient;
|
|
20208
|
+
}
|
|
20209
|
+
|
|
20210
|
+
const registeredServices = new Set();
|
|
20211
|
+
async function registerService(options) {
|
|
20212
|
+
var _a, _b, _c, _d;
|
|
20213
|
+
const { name, id, port, address = 'localhost', check, tags, meta } = options;
|
|
20214
|
+
const atlasClient = getAtlasClient();
|
|
20215
|
+
await atlasClient.registerService({
|
|
20216
|
+
address,
|
|
20217
|
+
port,
|
|
20218
|
+
name,
|
|
20219
|
+
}).then((res) => {
|
|
20220
|
+
console.log("🚀 ~ registerService ~ res:", res);
|
|
20221
|
+
});
|
|
20222
|
+
if (registeredServices.has(id)) {
|
|
20223
|
+
console.log(`⚠️ Service "${id}" is already registered.`);
|
|
20224
|
+
return;
|
|
20225
|
+
}
|
|
20226
|
+
const serviceDefinition = {
|
|
20227
|
+
name,
|
|
20228
|
+
id,
|
|
20229
|
+
address,
|
|
20230
|
+
port,
|
|
20231
|
+
tags,
|
|
20232
|
+
meta,
|
|
20233
|
+
};
|
|
20234
|
+
if (check !== false) {
|
|
20235
|
+
const checkDefinition = {
|
|
20236
|
+
name: (_a = check === null || check === void 0 ? void 0 : check.name) !== null && _a !== void 0 ? _a : `${name}-check`,
|
|
20237
|
+
http: (_b = check === null || check === void 0 ? void 0 : check.http) !== null && _b !== void 0 ? _b : `http://${address}:${port}/health`,
|
|
20238
|
+
interval: (_c = check === null || check === void 0 ? void 0 : check.interval) !== null && _c !== void 0 ? _c : '10s',
|
|
20239
|
+
timeout: (_d = check === null || check === void 0 ? void 0 : check.timeout) !== null && _d !== void 0 ? _d : '5s',
|
|
20240
|
+
};
|
|
20241
|
+
if (check === null || check === void 0 ? void 0 : check.deregistercriticalserviceafter) {
|
|
20242
|
+
checkDefinition.deregistercriticalserviceafter = check.deregistercriticalserviceafter;
|
|
20243
|
+
}
|
|
20244
|
+
serviceDefinition.check = checkDefinition;
|
|
20245
|
+
}
|
|
20246
|
+
await getClient().agent.service.register(serviceDefinition);
|
|
20247
|
+
registeredServices.add(id);
|
|
20248
|
+
console.log(`✅ Service "${id}" registered successfully.`);
|
|
20249
|
+
}
|
|
20250
|
+
async function deregisterService(id) {
|
|
20251
|
+
if (!registeredServices.has(id)) {
|
|
20252
|
+
console.log(`⚠️ Service "${id}" is not registered.`);
|
|
20253
|
+
return;
|
|
20254
|
+
}
|
|
20255
|
+
await getClient().agent.service.deregister(id);
|
|
20256
|
+
registeredServices.delete(id);
|
|
20257
|
+
console.log(`🛑 Service "${id}" deregistered successfully.`);
|
|
20258
|
+
}
|
|
20259
|
+
|
|
20260
|
+
const BASE_LOG_DIR$2 = '/home/log';
|
|
20261
|
+
// اسم السيرفس الحالي اللي بيعمل الـ discovery
|
|
20262
|
+
const CURRENT_SERVICE$2 = process.env.SERVICE_NAME || 'unknown-service';
|
|
20263
|
+
async function ensureLogDir$2(dir) {
|
|
20264
|
+
await require$$6.promises.mkdir(dir, { recursive: true });
|
|
20265
|
+
}
|
|
20266
|
+
function formatLogLine(targetService, instance, elapsedMs) {
|
|
20267
|
+
var _a, _b, _c, _d, _e;
|
|
20268
|
+
const ts = new Date().toISOString();
|
|
20269
|
+
const addr = (_b = (_a = instance.ServiceAddress) !== null && _a !== void 0 ? _a : instance.Address) !== null && _b !== void 0 ? _b : 'unknown';
|
|
20270
|
+
const port = (_c = instance.ServicePort) !== null && _c !== void 0 ? _c : 'unknown';
|
|
20271
|
+
const node = (_d = instance.Node) !== null && _d !== void 0 ? _d : 'N/A';
|
|
20272
|
+
const id = (_e = instance.ServiceID) !== null && _e !== void 0 ? _e : 'N/A';
|
|
20273
|
+
const elapsed = elapsedMs !== undefined ? ` | Elapsed=${elapsedMs}ms` : '';
|
|
20274
|
+
return `${ts} | Target=${targetService} | ${addr}:${port} | Node=${node} | ID=${id}${elapsed}\n`;
|
|
20275
|
+
}
|
|
20276
|
+
async function appendDiscoveryLog(targetService, instance, elapsedMs) {
|
|
20277
|
+
try {
|
|
20278
|
+
// فولدر خاص بالسيرفس الحالي
|
|
20279
|
+
const serviceDir = path.join(BASE_LOG_DIR$2, CURRENT_SERVICE$2);
|
|
20280
|
+
await ensureLogDir$2(serviceDir);
|
|
20281
|
+
// اللوج يروح في ملف ثابت detect.log
|
|
20282
|
+
const file = path.join(serviceDir, 'detect.log');
|
|
20283
|
+
const line = formatLogLine(targetService, instance, elapsedMs);
|
|
20284
|
+
await require$$6.promises.appendFile(file, line, { encoding: 'utf8' });
|
|
20285
|
+
}
|
|
20286
|
+
catch (err) {
|
|
20287
|
+
console.error('❌ Failed to write discovery log:', err);
|
|
20288
|
+
}
|
|
20289
|
+
}
|
|
20290
|
+
|
|
20291
|
+
const store = new Map();
|
|
20292
|
+
/**
|
|
20293
|
+
* Set a value in memory with optional TTL (ms).
|
|
20294
|
+
*/
|
|
20295
|
+
function set(key, value, ttl) {
|
|
20296
|
+
const record = { value };
|
|
20297
|
+
{
|
|
20298
|
+
record.expiresAt = Date.now() + ttl;
|
|
20299
|
+
}
|
|
20300
|
+
store.set(key, record);
|
|
20301
|
+
}
|
|
20302
|
+
/**
|
|
20303
|
+
* Get a value from memory.
|
|
20304
|
+
* Returns undefined if key does not exist or expired.
|
|
20305
|
+
*/
|
|
20306
|
+
function get(key) {
|
|
20307
|
+
const record = store.get(key);
|
|
20308
|
+
if (!record)
|
|
20309
|
+
return undefined;
|
|
20310
|
+
if (record.expiresAt && record.expiresAt < Date.now()) {
|
|
20311
|
+
store.delete(key);
|
|
20312
|
+
return undefined;
|
|
20313
|
+
}
|
|
20314
|
+
return record.value;
|
|
20315
|
+
}
|
|
20316
|
+
|
|
20317
|
+
const CACHE_TTL = 60000;
|
|
20318
|
+
async function listServices() {
|
|
20319
|
+
const cacheKey = 'services:list';
|
|
20320
|
+
const cached = get(cacheKey);
|
|
20321
|
+
if (cached)
|
|
20322
|
+
return cached;
|
|
20323
|
+
const services = await getClient().agent.service.list();
|
|
20324
|
+
const values = Object.values(services);
|
|
20325
|
+
set(cacheKey, values, CACHE_TTL);
|
|
20326
|
+
return values;
|
|
20327
|
+
}
|
|
20328
|
+
async function getServiceInstances(serviceName) {
|
|
20329
|
+
const cacheKey = `services:${serviceName}`;
|
|
20330
|
+
const cached = get(cacheKey);
|
|
20331
|
+
if (cached)
|
|
20332
|
+
return cached;
|
|
20333
|
+
const start = Date.now();
|
|
20334
|
+
const services = await getClient().catalog.service.nodes(serviceName);
|
|
20335
|
+
const elapsed = Date.now() - start;
|
|
20336
|
+
console.log(`⏱️ Discovery for ${serviceName} took ${elapsed}ms`);
|
|
20337
|
+
set(cacheKey, services, CACHE_TTL);
|
|
20338
|
+
return services;
|
|
20339
|
+
}
|
|
20340
|
+
async function getRandomServiceInstance(serviceName) {
|
|
20341
|
+
const cacheKey = `random:${serviceName}`;
|
|
20342
|
+
const cached = get(cacheKey);
|
|
20343
|
+
if (cached)
|
|
20344
|
+
return cached;
|
|
20345
|
+
const start = Date.now();
|
|
20346
|
+
const instances = await getServiceInstances(serviceName);
|
|
20347
|
+
if (!instances.length)
|
|
20348
|
+
throw new Error(`Service "${serviceName}" not found`);
|
|
20349
|
+
const randomIndex = Math.floor(Math.random() * instances.length);
|
|
20350
|
+
const instance = instances[randomIndex];
|
|
20351
|
+
const elapsed = Date.now() - start;
|
|
20352
|
+
await appendDiscoveryLog(serviceName, instance, elapsed);
|
|
20353
|
+
// cache random instance
|
|
20354
|
+
set(cacheKey, instance, CACHE_TTL);
|
|
20355
|
+
return instance;
|
|
20356
|
+
}
|
|
20357
|
+
async function getServiceUrl(serviceName) {
|
|
20358
|
+
const cacheKey = `url:${serviceName}`;
|
|
20359
|
+
const cached = get(cacheKey);
|
|
20360
|
+
if (cached)
|
|
20361
|
+
return cached;
|
|
20362
|
+
const instance = await getRandomServiceInstance(serviceName);
|
|
20363
|
+
const url = `http://${instance.ServiceAddress}:${instance.ServicePort}`;
|
|
20364
|
+
// cache url
|
|
20365
|
+
set(cacheKey, url, CACHE_TTL);
|
|
20366
|
+
return url;
|
|
20367
|
+
}
|
|
20368
|
+
|
|
20369
|
+
const BASE_LOG_DIR$1 = '/home/log';
|
|
20370
|
+
const CURRENT_SERVICE$1 = process.env.SERVICE_NAME || 'unknown-service';
|
|
20371
|
+
async function ensureLogDir$1(dir) {
|
|
20318
20372
|
await require$$6.promises.mkdir(dir, { recursive: true });
|
|
20319
20373
|
}
|
|
20320
20374
|
function getLogFileForStatus(status) {
|
|
20321
20375
|
const date = new Date().toISOString().split('T')[0]; // YYYY-MM-DD
|
|
20322
|
-
const serviceDir = path.join(BASE_LOG_DIR, CURRENT_SERVICE);
|
|
20376
|
+
const serviceDir = path.join(BASE_LOG_DIR$1, CURRENT_SERVICE$1);
|
|
20323
20377
|
if (status >= 200 && status < 300)
|
|
20324
20378
|
return path.join(serviceDir, `calls-2xx-${date}.log`);
|
|
20325
20379
|
if (status >= 400 && status < 500)
|
|
@@ -20331,13 +20385,13 @@ function getLogFileForStatus(status) {
|
|
|
20331
20385
|
function formatCallLogLine(targetService, url, method, status, elapsedMs, errorMessage) {
|
|
20332
20386
|
const ts = new Date().toISOString();
|
|
20333
20387
|
const errPart = errorMessage ? ` | Error="${errorMessage}"` : '';
|
|
20334
|
-
return `${ts} | Caller=${CURRENT_SERVICE} | Target=${targetService} | ${method.toUpperCase()} ${url} | Status=${status} | Elapsed=${elapsedMs}ms${errPart}\n`;
|
|
20388
|
+
return `${ts} | Caller=${CURRENT_SERVICE$1} | Target=${targetService} | ${method.toUpperCase()} ${url} | Status=${status} | Elapsed=${elapsedMs}ms${errPart}\n`;
|
|
20335
20389
|
}
|
|
20336
20390
|
async function appendCallLog(targetService, url, method, status, elapsedMs, errorMessage) {
|
|
20337
20391
|
try {
|
|
20338
20392
|
const file = getLogFileForStatus(status);
|
|
20339
20393
|
const dir = path.dirname(file);
|
|
20340
|
-
await ensureLogDir(dir);
|
|
20394
|
+
await ensureLogDir$1(dir);
|
|
20341
20395
|
const line = formatCallLogLine(targetService, url, method, status, elapsedMs, errorMessage);
|
|
20342
20396
|
await require$$6.promises.appendFile(file, line, { encoding: 'utf8' });
|
|
20343
20397
|
}
|
|
@@ -20346,18 +20400,48 @@ async function appendCallLog(targetService, url, method, status, elapsedMs, erro
|
|
|
20346
20400
|
}
|
|
20347
20401
|
}
|
|
20348
20402
|
|
|
20403
|
+
const BASE_LOG_DIR = '/home/log';
|
|
20404
|
+
const CURRENT_SERVICE = process.env.SERVICE_NAME || 'unknown-service';
|
|
20405
|
+
const THRESHOLD = Number(process.env.SLOW_CALL_THRESHOLD || 200); // الافتراضي 200ms
|
|
20406
|
+
async function ensureLogDir(dir) {
|
|
20407
|
+
await require$$6.promises.mkdir(dir, { recursive: true });
|
|
20408
|
+
}
|
|
20409
|
+
function getLogFile() {
|
|
20410
|
+
const serviceDir = path.join(BASE_LOG_DIR, CURRENT_SERVICE);
|
|
20411
|
+
return path.join(serviceDir, 'slow-calls.log');
|
|
20412
|
+
}
|
|
20413
|
+
function formatSlowCallLine(targetService, url, method, status, elapsedMs) {
|
|
20414
|
+
const ts = new Date().toISOString();
|
|
20415
|
+
return `${ts} | Caller=${CURRENT_SERVICE} | Target=${targetService} | ${method.toUpperCase()} ${url} | Status=${status} | Elapsed=${elapsedMs}ms\n`;
|
|
20416
|
+
}
|
|
20417
|
+
async function appendSlowCallLog(targetService, url, method, status, elapsedMs) {
|
|
20418
|
+
if (elapsedMs < THRESHOLD)
|
|
20419
|
+
return; // ما يكتبش غير اللي عدّى الحد
|
|
20420
|
+
try {
|
|
20421
|
+
const file = getLogFile();
|
|
20422
|
+
const dir = path.dirname(file);
|
|
20423
|
+
await ensureLogDir(dir);
|
|
20424
|
+
const line = formatSlowCallLine(targetService, url, method, status, elapsedMs);
|
|
20425
|
+
await require$$6.promises.appendFile(file, line, { encoding: 'utf8' });
|
|
20426
|
+
}
|
|
20427
|
+
catch (err) {
|
|
20428
|
+
console.error('❌ Failed to write slow call log:', err);
|
|
20429
|
+
}
|
|
20430
|
+
}
|
|
20431
|
+
|
|
20349
20432
|
async function callService(serviceName, options = {}) {
|
|
20350
20433
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
20351
20434
|
const { method = 'GET', path = '/', data, headers, params, } = options;
|
|
20352
20435
|
const start = Date.now();
|
|
20353
20436
|
try {
|
|
20354
|
-
// ...
|
|
20355
20437
|
const instance = await getRandomServiceInstance(serviceName);
|
|
20356
20438
|
const url = `http://${instance.ServiceAddress}:${instance.ServicePort}${path}`;
|
|
20357
20439
|
const response = await axios.request({ url, method, data, headers, params });
|
|
20358
20440
|
const elapsed = Date.now() - start;
|
|
20359
|
-
// سجل
|
|
20441
|
+
// 📌 سجل الكول
|
|
20360
20442
|
await appendCallLog(serviceName, url, method, response.status, elapsed);
|
|
20443
|
+
// 📌 لو بطيء → يتسجل في slow-calls.log
|
|
20444
|
+
await appendSlowCallLog(serviceName, url, method, response.status, elapsed);
|
|
20361
20445
|
return response.data;
|
|
20362
20446
|
}
|
|
20363
20447
|
catch (error) {
|
|
@@ -20366,13 +20450,15 @@ async function callService(serviceName, options = {}) {
|
|
|
20366
20450
|
const url = (_d = (_c = error.config) === null || _c === void 0 ? void 0 : _c.url) !== null && _d !== void 0 ? _d : '';
|
|
20367
20451
|
const methodUsed = (_f = (_e = error.config) === null || _e === void 0 ? void 0 : _e.method) !== null && _f !== void 0 ? _f : method;
|
|
20368
20452
|
const message = (_g = error.message) !== null && _g !== void 0 ? _g : 'Unknown error';
|
|
20369
|
-
// 📌 سجل الفشل
|
|
20453
|
+
// 📌 سجل الفشل
|
|
20370
20454
|
await appendCallLog(serviceName, url, methodUsed, status, elapsed, message);
|
|
20455
|
+
// 📌 لو بطيء → يتسجل برضه في slow-calls.log
|
|
20456
|
+
await appendSlowCallLog(serviceName, url, methodUsed, status, elapsed);
|
|
20371
20457
|
return {
|
|
20372
20458
|
success: false,
|
|
20373
20459
|
message,
|
|
20374
20460
|
status,
|
|
20375
|
-
code: (_k = (_j = (_h = error.response) === null || _h === void 0 ? void 0 : _h.data) === null || _j === void 0 ? void 0 : _j.code) !== null && _k !== void 0 ? _k :
|
|
20461
|
+
code: (_k = (_j = (_h = error.response) === null || _h === void 0 ? void 0 : _h.data) === null || _j === void 0 ? void 0 : _j.code) !== null && _k !== void 0 ? _k : '',
|
|
20376
20462
|
data: (_l = error.response) === null || _l === void 0 ? void 0 : _l.data,
|
|
20377
20463
|
};
|
|
20378
20464
|
}
|
|
@@ -20539,6 +20625,7 @@ async function dataLink(data, schema) {
|
|
|
20539
20625
|
exports.callService = callService;
|
|
20540
20626
|
exports.dataLink = dataLink;
|
|
20541
20627
|
exports.deregisterService = deregisterService;
|
|
20628
|
+
exports.getAtlasClient = getAtlasClient;
|
|
20542
20629
|
exports.getClient = getClient;
|
|
20543
20630
|
exports.getRandomServiceInstance = getRandomServiceInstance;
|
|
20544
20631
|
exports.getServiceInstances = getServiceInstances;
|
package/dist/index.esm.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import Consul from 'consul';
|
|
2
|
-
import require$$6, { promises } from 'fs';
|
|
3
|
-
import path from 'path';
|
|
4
2
|
import require$$1 from 'util';
|
|
5
3
|
import stream, { Readable } from 'stream';
|
|
4
|
+
import path from 'path';
|
|
6
5
|
import require$$3 from 'http';
|
|
7
6
|
import require$$4 from 'https';
|
|
8
7
|
import require$$0$1 from 'url';
|
|
8
|
+
import require$$6, { promises } from 'fs';
|
|
9
9
|
import crypto from 'crypto';
|
|
10
10
|
import require$$4$1 from 'assert';
|
|
11
11
|
import require$$1$1 from 'tty';
|
|
@@ -13,188 +13,6 @@ import require$$0$2 from 'os';
|
|
|
13
13
|
import zlib from 'zlib';
|
|
14
14
|
import { EventEmitter } from 'events';
|
|
15
15
|
|
|
16
|
-
// src/lib/client.ts
|
|
17
|
-
let consulClient = null;
|
|
18
|
-
function toBoolean(value) {
|
|
19
|
-
if (typeof value === "boolean")
|
|
20
|
-
return value;
|
|
21
|
-
if (typeof value === "string")
|
|
22
|
-
return value.toLowerCase() === "true";
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
function initClient({ host = "127.0.0.1", port = 8500, secure = false, }) {
|
|
26
|
-
consulClient = new Consul({
|
|
27
|
-
host: host !== null && host !== void 0 ? host : "127.0.0.1",
|
|
28
|
-
port: port !== null && port !== void 0 ? port : 8500,
|
|
29
|
-
secure: toBoolean(secure),
|
|
30
|
-
});
|
|
31
|
-
consulClient.agent.self((err) => {
|
|
32
|
-
if (err) {
|
|
33
|
-
console.error("❌ Failed to connect to Consul:", err.message);
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
console.log("✅ Connected to Consul successfully");
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
function getClient() {
|
|
41
|
-
if (!consulClient) {
|
|
42
|
-
throw new Error("Consul client not initialized. Call initClient() first.");
|
|
43
|
-
}
|
|
44
|
-
return consulClient;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const registeredServices = new Set();
|
|
48
|
-
async function registerService(options) {
|
|
49
|
-
var _a, _b, _c, _d;
|
|
50
|
-
const { name, id, port, address = 'localhost', check, tags, meta, } = options;
|
|
51
|
-
if (registeredServices.has(id)) {
|
|
52
|
-
console.log(`⚠️ Service "${id}" is already registered.`);
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
const serviceDefinition = {
|
|
56
|
-
name,
|
|
57
|
-
id,
|
|
58
|
-
address,
|
|
59
|
-
port,
|
|
60
|
-
tags,
|
|
61
|
-
meta,
|
|
62
|
-
};
|
|
63
|
-
if (check !== false) {
|
|
64
|
-
const checkDefinition = {
|
|
65
|
-
name: (_a = check === null || check === void 0 ? void 0 : check.name) !== null && _a !== void 0 ? _a : `${name}-check`,
|
|
66
|
-
http: (_b = check === null || check === void 0 ? void 0 : check.http) !== null && _b !== void 0 ? _b : `http://${address}:${port}/health`,
|
|
67
|
-
interval: (_c = check === null || check === void 0 ? void 0 : check.interval) !== null && _c !== void 0 ? _c : '10s',
|
|
68
|
-
timeout: (_d = check === null || check === void 0 ? void 0 : check.timeout) !== null && _d !== void 0 ? _d : '5s',
|
|
69
|
-
};
|
|
70
|
-
if (check === null || check === void 0 ? void 0 : check.deregistercriticalserviceafter) {
|
|
71
|
-
checkDefinition.deregistercriticalserviceafter = check.deregistercriticalserviceafter;
|
|
72
|
-
}
|
|
73
|
-
serviceDefinition.check = checkDefinition;
|
|
74
|
-
}
|
|
75
|
-
await getClient().agent.service.register(serviceDefinition);
|
|
76
|
-
registeredServices.add(id);
|
|
77
|
-
console.log(`✅ Service "${id}" registered successfully.`);
|
|
78
|
-
}
|
|
79
|
-
async function deregisterService(id) {
|
|
80
|
-
if (!registeredServices.has(id)) {
|
|
81
|
-
console.log(`⚠️ Service "${id}" is not registered.`);
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
await getClient().agent.service.deregister(id);
|
|
85
|
-
registeredServices.delete(id);
|
|
86
|
-
console.log(`🛑 Service "${id}" deregistered successfully.`);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const BASE_LOG_DIR$1 = '/home/log';
|
|
90
|
-
// اسم السيرفس الحالي اللي بيعمل الـ discovery
|
|
91
|
-
const CURRENT_SERVICE$1 = process.env.SERVICE_NAME || 'unknown-service';
|
|
92
|
-
async function ensureLogDir$1(dir) {
|
|
93
|
-
await promises.mkdir(dir, { recursive: true });
|
|
94
|
-
}
|
|
95
|
-
function formatLogLine(targetService, instance, elapsedMs) {
|
|
96
|
-
var _a, _b, _c, _d, _e;
|
|
97
|
-
const ts = new Date().toISOString();
|
|
98
|
-
const addr = (_b = (_a = instance.ServiceAddress) !== null && _a !== void 0 ? _a : instance.Address) !== null && _b !== void 0 ? _b : 'unknown';
|
|
99
|
-
const port = (_c = instance.ServicePort) !== null && _c !== void 0 ? _c : 'unknown';
|
|
100
|
-
const node = (_d = instance.Node) !== null && _d !== void 0 ? _d : 'N/A';
|
|
101
|
-
const id = (_e = instance.ServiceID) !== null && _e !== void 0 ? _e : 'N/A';
|
|
102
|
-
const elapsed = elapsedMs !== undefined ? ` | Elapsed=${elapsedMs}ms` : '';
|
|
103
|
-
return `${ts} | Target=${targetService} | ${addr}:${port} | Node=${node} | ID=${id}${elapsed}\n`;
|
|
104
|
-
}
|
|
105
|
-
async function appendDiscoveryLog(targetService, instance, elapsedMs) {
|
|
106
|
-
try {
|
|
107
|
-
// فولدر خاص بالسيرفس الحالي
|
|
108
|
-
const serviceDir = path.join(BASE_LOG_DIR$1, CURRENT_SERVICE$1);
|
|
109
|
-
await ensureLogDir$1(serviceDir);
|
|
110
|
-
// اللوج يروح في ملف ثابت detect.log
|
|
111
|
-
const file = path.join(serviceDir, 'detect.log');
|
|
112
|
-
const line = formatLogLine(targetService, instance, elapsedMs);
|
|
113
|
-
await promises.appendFile(file, line, { encoding: 'utf8' });
|
|
114
|
-
}
|
|
115
|
-
catch (err) {
|
|
116
|
-
console.error('❌ Failed to write discovery log:', err);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const store = new Map();
|
|
121
|
-
/**
|
|
122
|
-
* Set a value in memory with optional TTL (ms).
|
|
123
|
-
*/
|
|
124
|
-
function set(key, value, ttl) {
|
|
125
|
-
const record = { value };
|
|
126
|
-
{
|
|
127
|
-
record.expiresAt = Date.now() + ttl;
|
|
128
|
-
}
|
|
129
|
-
store.set(key, record);
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Get a value from memory.
|
|
133
|
-
* Returns undefined if key does not exist or expired.
|
|
134
|
-
*/
|
|
135
|
-
function get$1(key) {
|
|
136
|
-
const record = store.get(key);
|
|
137
|
-
if (!record)
|
|
138
|
-
return undefined;
|
|
139
|
-
if (record.expiresAt && record.expiresAt < Date.now()) {
|
|
140
|
-
store.delete(key);
|
|
141
|
-
return undefined;
|
|
142
|
-
}
|
|
143
|
-
return record.value;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const CACHE_TTL = 10000; // 10 ثواني – عدلها حسب احتياجك
|
|
147
|
-
async function listServices() {
|
|
148
|
-
const cacheKey = 'services:list';
|
|
149
|
-
const cached = get$1(cacheKey);
|
|
150
|
-
if (cached)
|
|
151
|
-
return cached;
|
|
152
|
-
const services = await getClient().agent.service.list();
|
|
153
|
-
const values = Object.values(services);
|
|
154
|
-
set(cacheKey, values, CACHE_TTL);
|
|
155
|
-
return values;
|
|
156
|
-
}
|
|
157
|
-
async function getServiceInstances(serviceName) {
|
|
158
|
-
const cacheKey = `services:${serviceName}`;
|
|
159
|
-
const cached = get$1(cacheKey);
|
|
160
|
-
if (cached)
|
|
161
|
-
return cached;
|
|
162
|
-
const start = Date.now();
|
|
163
|
-
const services = await getClient().catalog.service.nodes(serviceName);
|
|
164
|
-
const elapsed = Date.now() - start;
|
|
165
|
-
console.log(`⏱️ Discovery for ${serviceName} took ${elapsed}ms`);
|
|
166
|
-
set(cacheKey, services, CACHE_TTL);
|
|
167
|
-
return services;
|
|
168
|
-
}
|
|
169
|
-
async function getRandomServiceInstance(serviceName) {
|
|
170
|
-
const cacheKey = `random:${serviceName}`;
|
|
171
|
-
const cached = get$1(cacheKey);
|
|
172
|
-
if (cached)
|
|
173
|
-
return cached;
|
|
174
|
-
const start = Date.now();
|
|
175
|
-
const instances = await getServiceInstances(serviceName);
|
|
176
|
-
if (!instances.length)
|
|
177
|
-
throw new Error(`Service "${serviceName}" not found`);
|
|
178
|
-
const randomIndex = Math.floor(Math.random() * instances.length);
|
|
179
|
-
const instance = instances[randomIndex];
|
|
180
|
-
const elapsed = Date.now() - start;
|
|
181
|
-
await appendDiscoveryLog(serviceName, instance, elapsed);
|
|
182
|
-
// cache random instance
|
|
183
|
-
set(cacheKey, instance, CACHE_TTL);
|
|
184
|
-
return instance;
|
|
185
|
-
}
|
|
186
|
-
async function getServiceUrl(serviceName) {
|
|
187
|
-
const cacheKey = `url:${serviceName}`;
|
|
188
|
-
const cached = get$1(cacheKey);
|
|
189
|
-
if (cached)
|
|
190
|
-
return cached;
|
|
191
|
-
const instance = await getRandomServiceInstance(serviceName);
|
|
192
|
-
const url = `http://${instance.ServiceAddress}:${instance.ServicePort}`;
|
|
193
|
-
// cache url
|
|
194
|
-
set(cacheKey, url, CACHE_TTL);
|
|
195
|
-
return url;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
16
|
function bind(fn, thisArg) {
|
|
199
17
|
return function wrap() {
|
|
200
18
|
return fn.apply(thisArg, arguments);
|
|
@@ -13303,11 +13121,11 @@ function requireCallBindApplyHelpers () {
|
|
|
13303
13121
|
return callBindApplyHelpers;
|
|
13304
13122
|
}
|
|
13305
13123
|
|
|
13306
|
-
var get;
|
|
13124
|
+
var get$1;
|
|
13307
13125
|
var hasRequiredGet;
|
|
13308
13126
|
|
|
13309
13127
|
function requireGet () {
|
|
13310
|
-
if (hasRequiredGet) return get;
|
|
13128
|
+
if (hasRequiredGet) return get$1;
|
|
13311
13129
|
hasRequiredGet = 1;
|
|
13312
13130
|
|
|
13313
13131
|
var callBind = requireCallBindApplyHelpers();
|
|
@@ -13330,7 +13148,7 @@ function requireGet () {
|
|
|
13330
13148
|
var $getPrototypeOf = $Object.getPrototypeOf;
|
|
13331
13149
|
|
|
13332
13150
|
/** @type {import('./get')} */
|
|
13333
|
-
get = desc && typeof desc.get === 'function'
|
|
13151
|
+
get$1 = desc && typeof desc.get === 'function'
|
|
13334
13152
|
? callBind([desc.get])
|
|
13335
13153
|
: typeof $getPrototypeOf === 'function'
|
|
13336
13154
|
? /** @type {import('./get')} */ function getDunder(value) {
|
|
@@ -13338,7 +13156,7 @@ function requireGet () {
|
|
|
13338
13156
|
return $getPrototypeOf(value == null ? value : $Object(value));
|
|
13339
13157
|
}
|
|
13340
13158
|
: false;
|
|
13341
|
-
return get;
|
|
13159
|
+
return get$1;
|
|
13342
13160
|
}
|
|
13343
13161
|
|
|
13344
13162
|
var getProto;
|
|
@@ -14854,12 +14672,12 @@ const hasStandardBrowserWebWorkerEnv = (() => {
|
|
|
14854
14672
|
const origin = hasBrowserEnv && window.location.href || 'http://localhost';
|
|
14855
14673
|
|
|
14856
14674
|
var utils = /*#__PURE__*/Object.freeze({
|
|
14857
|
-
|
|
14858
|
-
|
|
14859
|
-
|
|
14860
|
-
|
|
14861
|
-
|
|
14862
|
-
|
|
14675
|
+
__proto__: null,
|
|
14676
|
+
hasBrowserEnv: hasBrowserEnv,
|
|
14677
|
+
hasStandardBrowserEnv: hasStandardBrowserEnv,
|
|
14678
|
+
hasStandardBrowserWebWorkerEnv: hasStandardBrowserWebWorkerEnv,
|
|
14679
|
+
navigator: _navigator,
|
|
14680
|
+
origin: origin
|
|
14863
14681
|
});
|
|
14864
14682
|
|
|
14865
14683
|
var platform = {
|
|
@@ -20310,14 +20128,250 @@ const {
|
|
|
20310
20128
|
mergeConfig
|
|
20311
20129
|
} = axios;
|
|
20312
20130
|
|
|
20313
|
-
|
|
20314
|
-
|
|
20315
|
-
|
|
20131
|
+
class AtlasClient {
|
|
20132
|
+
constructor(options) {
|
|
20133
|
+
var _a, _b, _c, _d, _e, _f;
|
|
20134
|
+
const host = (_b = (_a = options === null || options === void 0 ? void 0 : options.host) !== null && _a !== void 0 ? _a : process.env.ATLAS_HOST) !== null && _b !== void 0 ? _b : '127.0.0.1';
|
|
20135
|
+
const port = (_c = options === null || options === void 0 ? void 0 : options.port) !== null && _c !== void 0 ? _c : parseInt((_d = process.env.ATLAS_PORT) !== null && _d !== void 0 ? _d : '371', 10);
|
|
20136
|
+
const secure = (_e = options === null || options === void 0 ? void 0 : options.secure) !== null && _e !== void 0 ? _e : false;
|
|
20137
|
+
this.version = (_f = options === null || options === void 0 ? void 0 : options.version) !== null && _f !== void 0 ? _f : '1';
|
|
20138
|
+
const baseURL = `${secure ? 'https' : 'http'}://${host}:${port}/v${this.version}`;
|
|
20139
|
+
this.client = axios.create({ baseURL });
|
|
20140
|
+
}
|
|
20141
|
+
// تسجيل سيرفس
|
|
20142
|
+
async registerService(data) {
|
|
20143
|
+
const res = await this.client.post('/service/register', data);
|
|
20144
|
+
return res.data;
|
|
20145
|
+
}
|
|
20146
|
+
// جلب سيرفس عشوائي بالاسم
|
|
20147
|
+
async getRandomService(name) {
|
|
20148
|
+
const res = await this.client.get(`/service/random`, {
|
|
20149
|
+
params: { name },
|
|
20150
|
+
});
|
|
20151
|
+
return res.data;
|
|
20152
|
+
}
|
|
20153
|
+
// جلب كل السيرفسات
|
|
20154
|
+
async listServices() {
|
|
20155
|
+
const res = await this.client.get('/service/list');
|
|
20156
|
+
return res.data;
|
|
20157
|
+
}
|
|
20158
|
+
// Health Check بسيط
|
|
20159
|
+
async checkHealth() {
|
|
20160
|
+
const res = await this.client.get('/health');
|
|
20161
|
+
return res.data;
|
|
20162
|
+
}
|
|
20163
|
+
}
|
|
20164
|
+
|
|
20165
|
+
// src/lib/client.ts
|
|
20166
|
+
let consulClient = null;
|
|
20167
|
+
let atlasClient = null;
|
|
20168
|
+
function toBoolean(value) {
|
|
20169
|
+
if (typeof value === 'boolean')
|
|
20170
|
+
return value;
|
|
20171
|
+
if (typeof value === 'string')
|
|
20172
|
+
return value.toLowerCase() === 'true';
|
|
20173
|
+
return false;
|
|
20174
|
+
}
|
|
20175
|
+
function initClient({ host = '127.0.0.1', port = 8500, secure = false }) {
|
|
20176
|
+
atlasClient = new AtlasClient({
|
|
20177
|
+
host: host !== null && host !== void 0 ? host : '127.0.0.1',
|
|
20178
|
+
port: port !== null && port !== void 0 ? port : 371,
|
|
20179
|
+
version: '1',
|
|
20180
|
+
});
|
|
20181
|
+
consulClient = new Consul({
|
|
20182
|
+
host: host !== null && host !== void 0 ? host : '127.0.0.1',
|
|
20183
|
+
port: port !== null && port !== void 0 ? port : 8500,
|
|
20184
|
+
secure: toBoolean(secure),
|
|
20185
|
+
});
|
|
20186
|
+
consulClient.agent.self(err => {
|
|
20187
|
+
if (err) {
|
|
20188
|
+
console.error('❌ Failed to connect to Consul:', err.message);
|
|
20189
|
+
}
|
|
20190
|
+
else {
|
|
20191
|
+
console.log('✅ Connected to Consul successfully');
|
|
20192
|
+
}
|
|
20193
|
+
});
|
|
20194
|
+
}
|
|
20195
|
+
function getAtlasClient() {
|
|
20196
|
+
if (!atlasClient) {
|
|
20197
|
+
throw new Error('atlas client not initialized. Call initClient() first.');
|
|
20198
|
+
}
|
|
20199
|
+
return atlasClient;
|
|
20200
|
+
}
|
|
20201
|
+
function getClient() {
|
|
20202
|
+
if (!consulClient) {
|
|
20203
|
+
throw new Error('Consul client not initialized. Call initClient() first.');
|
|
20204
|
+
}
|
|
20205
|
+
return consulClient;
|
|
20206
|
+
}
|
|
20207
|
+
|
|
20208
|
+
const registeredServices = new Set();
|
|
20209
|
+
async function registerService(options) {
|
|
20210
|
+
var _a, _b, _c, _d;
|
|
20211
|
+
const { name, id, port, address = 'localhost', check, tags, meta } = options;
|
|
20212
|
+
const atlasClient = getAtlasClient();
|
|
20213
|
+
await atlasClient.registerService({
|
|
20214
|
+
address,
|
|
20215
|
+
port,
|
|
20216
|
+
name,
|
|
20217
|
+
}).then((res) => {
|
|
20218
|
+
console.log("🚀 ~ registerService ~ res:", res);
|
|
20219
|
+
});
|
|
20220
|
+
if (registeredServices.has(id)) {
|
|
20221
|
+
console.log(`⚠️ Service "${id}" is already registered.`);
|
|
20222
|
+
return;
|
|
20223
|
+
}
|
|
20224
|
+
const serviceDefinition = {
|
|
20225
|
+
name,
|
|
20226
|
+
id,
|
|
20227
|
+
address,
|
|
20228
|
+
port,
|
|
20229
|
+
tags,
|
|
20230
|
+
meta,
|
|
20231
|
+
};
|
|
20232
|
+
if (check !== false) {
|
|
20233
|
+
const checkDefinition = {
|
|
20234
|
+
name: (_a = check === null || check === void 0 ? void 0 : check.name) !== null && _a !== void 0 ? _a : `${name}-check`,
|
|
20235
|
+
http: (_b = check === null || check === void 0 ? void 0 : check.http) !== null && _b !== void 0 ? _b : `http://${address}:${port}/health`,
|
|
20236
|
+
interval: (_c = check === null || check === void 0 ? void 0 : check.interval) !== null && _c !== void 0 ? _c : '10s',
|
|
20237
|
+
timeout: (_d = check === null || check === void 0 ? void 0 : check.timeout) !== null && _d !== void 0 ? _d : '5s',
|
|
20238
|
+
};
|
|
20239
|
+
if (check === null || check === void 0 ? void 0 : check.deregistercriticalserviceafter) {
|
|
20240
|
+
checkDefinition.deregistercriticalserviceafter = check.deregistercriticalserviceafter;
|
|
20241
|
+
}
|
|
20242
|
+
serviceDefinition.check = checkDefinition;
|
|
20243
|
+
}
|
|
20244
|
+
await getClient().agent.service.register(serviceDefinition);
|
|
20245
|
+
registeredServices.add(id);
|
|
20246
|
+
console.log(`✅ Service "${id}" registered successfully.`);
|
|
20247
|
+
}
|
|
20248
|
+
async function deregisterService(id) {
|
|
20249
|
+
if (!registeredServices.has(id)) {
|
|
20250
|
+
console.log(`⚠️ Service "${id}" is not registered.`);
|
|
20251
|
+
return;
|
|
20252
|
+
}
|
|
20253
|
+
await getClient().agent.service.deregister(id);
|
|
20254
|
+
registeredServices.delete(id);
|
|
20255
|
+
console.log(`🛑 Service "${id}" deregistered successfully.`);
|
|
20256
|
+
}
|
|
20257
|
+
|
|
20258
|
+
const BASE_LOG_DIR$2 = '/home/log';
|
|
20259
|
+
// اسم السيرفس الحالي اللي بيعمل الـ discovery
|
|
20260
|
+
const CURRENT_SERVICE$2 = process.env.SERVICE_NAME || 'unknown-service';
|
|
20261
|
+
async function ensureLogDir$2(dir) {
|
|
20262
|
+
await promises.mkdir(dir, { recursive: true });
|
|
20263
|
+
}
|
|
20264
|
+
function formatLogLine(targetService, instance, elapsedMs) {
|
|
20265
|
+
var _a, _b, _c, _d, _e;
|
|
20266
|
+
const ts = new Date().toISOString();
|
|
20267
|
+
const addr = (_b = (_a = instance.ServiceAddress) !== null && _a !== void 0 ? _a : instance.Address) !== null && _b !== void 0 ? _b : 'unknown';
|
|
20268
|
+
const port = (_c = instance.ServicePort) !== null && _c !== void 0 ? _c : 'unknown';
|
|
20269
|
+
const node = (_d = instance.Node) !== null && _d !== void 0 ? _d : 'N/A';
|
|
20270
|
+
const id = (_e = instance.ServiceID) !== null && _e !== void 0 ? _e : 'N/A';
|
|
20271
|
+
const elapsed = elapsedMs !== undefined ? ` | Elapsed=${elapsedMs}ms` : '';
|
|
20272
|
+
return `${ts} | Target=${targetService} | ${addr}:${port} | Node=${node} | ID=${id}${elapsed}\n`;
|
|
20273
|
+
}
|
|
20274
|
+
async function appendDiscoveryLog(targetService, instance, elapsedMs) {
|
|
20275
|
+
try {
|
|
20276
|
+
// فولدر خاص بالسيرفس الحالي
|
|
20277
|
+
const serviceDir = path.join(BASE_LOG_DIR$2, CURRENT_SERVICE$2);
|
|
20278
|
+
await ensureLogDir$2(serviceDir);
|
|
20279
|
+
// اللوج يروح في ملف ثابت detect.log
|
|
20280
|
+
const file = path.join(serviceDir, 'detect.log');
|
|
20281
|
+
const line = formatLogLine(targetService, instance, elapsedMs);
|
|
20282
|
+
await promises.appendFile(file, line, { encoding: 'utf8' });
|
|
20283
|
+
}
|
|
20284
|
+
catch (err) {
|
|
20285
|
+
console.error('❌ Failed to write discovery log:', err);
|
|
20286
|
+
}
|
|
20287
|
+
}
|
|
20288
|
+
|
|
20289
|
+
const store = new Map();
|
|
20290
|
+
/**
|
|
20291
|
+
* Set a value in memory with optional TTL (ms).
|
|
20292
|
+
*/
|
|
20293
|
+
function set(key, value, ttl) {
|
|
20294
|
+
const record = { value };
|
|
20295
|
+
{
|
|
20296
|
+
record.expiresAt = Date.now() + ttl;
|
|
20297
|
+
}
|
|
20298
|
+
store.set(key, record);
|
|
20299
|
+
}
|
|
20300
|
+
/**
|
|
20301
|
+
* Get a value from memory.
|
|
20302
|
+
* Returns undefined if key does not exist or expired.
|
|
20303
|
+
*/
|
|
20304
|
+
function get(key) {
|
|
20305
|
+
const record = store.get(key);
|
|
20306
|
+
if (!record)
|
|
20307
|
+
return undefined;
|
|
20308
|
+
if (record.expiresAt && record.expiresAt < Date.now()) {
|
|
20309
|
+
store.delete(key);
|
|
20310
|
+
return undefined;
|
|
20311
|
+
}
|
|
20312
|
+
return record.value;
|
|
20313
|
+
}
|
|
20314
|
+
|
|
20315
|
+
const CACHE_TTL = 60000;
|
|
20316
|
+
async function listServices() {
|
|
20317
|
+
const cacheKey = 'services:list';
|
|
20318
|
+
const cached = get(cacheKey);
|
|
20319
|
+
if (cached)
|
|
20320
|
+
return cached;
|
|
20321
|
+
const services = await getClient().agent.service.list();
|
|
20322
|
+
const values = Object.values(services);
|
|
20323
|
+
set(cacheKey, values, CACHE_TTL);
|
|
20324
|
+
return values;
|
|
20325
|
+
}
|
|
20326
|
+
async function getServiceInstances(serviceName) {
|
|
20327
|
+
const cacheKey = `services:${serviceName}`;
|
|
20328
|
+
const cached = get(cacheKey);
|
|
20329
|
+
if (cached)
|
|
20330
|
+
return cached;
|
|
20331
|
+
const start = Date.now();
|
|
20332
|
+
const services = await getClient().catalog.service.nodes(serviceName);
|
|
20333
|
+
const elapsed = Date.now() - start;
|
|
20334
|
+
console.log(`⏱️ Discovery for ${serviceName} took ${elapsed}ms`);
|
|
20335
|
+
set(cacheKey, services, CACHE_TTL);
|
|
20336
|
+
return services;
|
|
20337
|
+
}
|
|
20338
|
+
async function getRandomServiceInstance(serviceName) {
|
|
20339
|
+
const cacheKey = `random:${serviceName}`;
|
|
20340
|
+
const cached = get(cacheKey);
|
|
20341
|
+
if (cached)
|
|
20342
|
+
return cached;
|
|
20343
|
+
const start = Date.now();
|
|
20344
|
+
const instances = await getServiceInstances(serviceName);
|
|
20345
|
+
if (!instances.length)
|
|
20346
|
+
throw new Error(`Service "${serviceName}" not found`);
|
|
20347
|
+
const randomIndex = Math.floor(Math.random() * instances.length);
|
|
20348
|
+
const instance = instances[randomIndex];
|
|
20349
|
+
const elapsed = Date.now() - start;
|
|
20350
|
+
await appendDiscoveryLog(serviceName, instance, elapsed);
|
|
20351
|
+
// cache random instance
|
|
20352
|
+
set(cacheKey, instance, CACHE_TTL);
|
|
20353
|
+
return instance;
|
|
20354
|
+
}
|
|
20355
|
+
async function getServiceUrl(serviceName) {
|
|
20356
|
+
const cacheKey = `url:${serviceName}`;
|
|
20357
|
+
const cached = get(cacheKey);
|
|
20358
|
+
if (cached)
|
|
20359
|
+
return cached;
|
|
20360
|
+
const instance = await getRandomServiceInstance(serviceName);
|
|
20361
|
+
const url = `http://${instance.ServiceAddress}:${instance.ServicePort}`;
|
|
20362
|
+
// cache url
|
|
20363
|
+
set(cacheKey, url, CACHE_TTL);
|
|
20364
|
+
return url;
|
|
20365
|
+
}
|
|
20366
|
+
|
|
20367
|
+
const BASE_LOG_DIR$1 = '/home/log';
|
|
20368
|
+
const CURRENT_SERVICE$1 = process.env.SERVICE_NAME || 'unknown-service';
|
|
20369
|
+
async function ensureLogDir$1(dir) {
|
|
20316
20370
|
await promises.mkdir(dir, { recursive: true });
|
|
20317
20371
|
}
|
|
20318
20372
|
function getLogFileForStatus(status) {
|
|
20319
20373
|
const date = new Date().toISOString().split('T')[0]; // YYYY-MM-DD
|
|
20320
|
-
const serviceDir = path.join(BASE_LOG_DIR, CURRENT_SERVICE);
|
|
20374
|
+
const serviceDir = path.join(BASE_LOG_DIR$1, CURRENT_SERVICE$1);
|
|
20321
20375
|
if (status >= 200 && status < 300)
|
|
20322
20376
|
return path.join(serviceDir, `calls-2xx-${date}.log`);
|
|
20323
20377
|
if (status >= 400 && status < 500)
|
|
@@ -20329,13 +20383,13 @@ function getLogFileForStatus(status) {
|
|
|
20329
20383
|
function formatCallLogLine(targetService, url, method, status, elapsedMs, errorMessage) {
|
|
20330
20384
|
const ts = new Date().toISOString();
|
|
20331
20385
|
const errPart = errorMessage ? ` | Error="${errorMessage}"` : '';
|
|
20332
|
-
return `${ts} | Caller=${CURRENT_SERVICE} | Target=${targetService} | ${method.toUpperCase()} ${url} | Status=${status} | Elapsed=${elapsedMs}ms${errPart}\n`;
|
|
20386
|
+
return `${ts} | Caller=${CURRENT_SERVICE$1} | Target=${targetService} | ${method.toUpperCase()} ${url} | Status=${status} | Elapsed=${elapsedMs}ms${errPart}\n`;
|
|
20333
20387
|
}
|
|
20334
20388
|
async function appendCallLog(targetService, url, method, status, elapsedMs, errorMessage) {
|
|
20335
20389
|
try {
|
|
20336
20390
|
const file = getLogFileForStatus(status);
|
|
20337
20391
|
const dir = path.dirname(file);
|
|
20338
|
-
await ensureLogDir(dir);
|
|
20392
|
+
await ensureLogDir$1(dir);
|
|
20339
20393
|
const line = formatCallLogLine(targetService, url, method, status, elapsedMs, errorMessage);
|
|
20340
20394
|
await promises.appendFile(file, line, { encoding: 'utf8' });
|
|
20341
20395
|
}
|
|
@@ -20344,18 +20398,48 @@ async function appendCallLog(targetService, url, method, status, elapsedMs, erro
|
|
|
20344
20398
|
}
|
|
20345
20399
|
}
|
|
20346
20400
|
|
|
20401
|
+
const BASE_LOG_DIR = '/home/log';
|
|
20402
|
+
const CURRENT_SERVICE = process.env.SERVICE_NAME || 'unknown-service';
|
|
20403
|
+
const THRESHOLD = Number(process.env.SLOW_CALL_THRESHOLD || 200); // الافتراضي 200ms
|
|
20404
|
+
async function ensureLogDir(dir) {
|
|
20405
|
+
await promises.mkdir(dir, { recursive: true });
|
|
20406
|
+
}
|
|
20407
|
+
function getLogFile() {
|
|
20408
|
+
const serviceDir = path.join(BASE_LOG_DIR, CURRENT_SERVICE);
|
|
20409
|
+
return path.join(serviceDir, 'slow-calls.log');
|
|
20410
|
+
}
|
|
20411
|
+
function formatSlowCallLine(targetService, url, method, status, elapsedMs) {
|
|
20412
|
+
const ts = new Date().toISOString();
|
|
20413
|
+
return `${ts} | Caller=${CURRENT_SERVICE} | Target=${targetService} | ${method.toUpperCase()} ${url} | Status=${status} | Elapsed=${elapsedMs}ms\n`;
|
|
20414
|
+
}
|
|
20415
|
+
async function appendSlowCallLog(targetService, url, method, status, elapsedMs) {
|
|
20416
|
+
if (elapsedMs < THRESHOLD)
|
|
20417
|
+
return; // ما يكتبش غير اللي عدّى الحد
|
|
20418
|
+
try {
|
|
20419
|
+
const file = getLogFile();
|
|
20420
|
+
const dir = path.dirname(file);
|
|
20421
|
+
await ensureLogDir(dir);
|
|
20422
|
+
const line = formatSlowCallLine(targetService, url, method, status, elapsedMs);
|
|
20423
|
+
await promises.appendFile(file, line, { encoding: 'utf8' });
|
|
20424
|
+
}
|
|
20425
|
+
catch (err) {
|
|
20426
|
+
console.error('❌ Failed to write slow call log:', err);
|
|
20427
|
+
}
|
|
20428
|
+
}
|
|
20429
|
+
|
|
20347
20430
|
async function callService(serviceName, options = {}) {
|
|
20348
20431
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
20349
20432
|
const { method = 'GET', path = '/', data, headers, params, } = options;
|
|
20350
20433
|
const start = Date.now();
|
|
20351
20434
|
try {
|
|
20352
|
-
// ...
|
|
20353
20435
|
const instance = await getRandomServiceInstance(serviceName);
|
|
20354
20436
|
const url = `http://${instance.ServiceAddress}:${instance.ServicePort}${path}`;
|
|
20355
20437
|
const response = await axios.request({ url, method, data, headers, params });
|
|
20356
20438
|
const elapsed = Date.now() - start;
|
|
20357
|
-
// سجل
|
|
20439
|
+
// 📌 سجل الكول
|
|
20358
20440
|
await appendCallLog(serviceName, url, method, response.status, elapsed);
|
|
20441
|
+
// 📌 لو بطيء → يتسجل في slow-calls.log
|
|
20442
|
+
await appendSlowCallLog(serviceName, url, method, response.status, elapsed);
|
|
20359
20443
|
return response.data;
|
|
20360
20444
|
}
|
|
20361
20445
|
catch (error) {
|
|
@@ -20364,13 +20448,15 @@ async function callService(serviceName, options = {}) {
|
|
|
20364
20448
|
const url = (_d = (_c = error.config) === null || _c === void 0 ? void 0 : _c.url) !== null && _d !== void 0 ? _d : '';
|
|
20365
20449
|
const methodUsed = (_f = (_e = error.config) === null || _e === void 0 ? void 0 : _e.method) !== null && _f !== void 0 ? _f : method;
|
|
20366
20450
|
const message = (_g = error.message) !== null && _g !== void 0 ? _g : 'Unknown error';
|
|
20367
|
-
// 📌 سجل الفشل
|
|
20451
|
+
// 📌 سجل الفشل
|
|
20368
20452
|
await appendCallLog(serviceName, url, methodUsed, status, elapsed, message);
|
|
20453
|
+
// 📌 لو بطيء → يتسجل برضه في slow-calls.log
|
|
20454
|
+
await appendSlowCallLog(serviceName, url, methodUsed, status, elapsed);
|
|
20369
20455
|
return {
|
|
20370
20456
|
success: false,
|
|
20371
20457
|
message,
|
|
20372
20458
|
status,
|
|
20373
|
-
code: (_k = (_j = (_h = error.response) === null || _h === void 0 ? void 0 : _h.data) === null || _j === void 0 ? void 0 : _j.code) !== null && _k !== void 0 ? _k :
|
|
20459
|
+
code: (_k = (_j = (_h = error.response) === null || _h === void 0 ? void 0 : _h.data) === null || _j === void 0 ? void 0 : _j.code) !== null && _k !== void 0 ? _k : '',
|
|
20374
20460
|
data: (_l = error.response) === null || _l === void 0 ? void 0 : _l.data,
|
|
20375
20461
|
};
|
|
20376
20462
|
}
|
|
@@ -20534,5 +20620,5 @@ async function dataLink(data, schema) {
|
|
|
20534
20620
|
return isArray ? result : result[0];
|
|
20535
20621
|
}
|
|
20536
20622
|
|
|
20537
|
-
export { callService, dataLink, deregisterService, getClient, getRandomServiceInstance, getServiceInstances, getServiceUrl, initClient, listServices, registerService, toBoolean };
|
|
20623
|
+
export { callService, dataLink, deregisterService, getAtlasClient, getClient, getRandomServiceInstance, getServiceInstances, getServiceUrl, initClient, listServices, registerService, toBoolean };
|
|
20538
20624
|
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function appendSlowCallLog(targetService: string, url: string, method: string, status: number, elapsedMs: number): Promise<void>;
|