@urga-panel/ur-panels-core 1.0.19 → 1.0.21
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/ServiceManager.d.ts +2 -2
- package/dist/ServiceManager.js +60 -25
- package/dist/services/abstract/apiService/ApiService.js +6 -1
- package/dist/services/abstract/authServices/AuthService.js +2 -3
- package/dist/services/abstract/pageServices/controllers/NSPageControllerService.js +2 -2
- package/dist/services/abstract/webviewServices/WVFrontService.js +3 -3
- package/dist/services/main/httpServices/RequestHandlerService.d.ts +2 -1
- package/dist/services/main/httpServices/RequestHandlerService.js +19 -7
- package/dist/services/main/logService/LogService.d.ts +31 -0
- package/dist/services/main/logService/LogService.js +131 -0
- package/dist/services/main/logService/index.d.ts +7 -0
- package/dist/services/main/logService/index.js +4 -0
- package/dist/services/main/logService/transports/ConsoleTransport.d.ts +16 -0
- package/dist/services/main/logService/transports/ConsoleTransport.js +62 -0
- package/dist/services/main/logService/transports/DatabaseTransport.d.ts +28 -0
- package/dist/services/main/logService/transports/DatabaseTransport.js +90 -0
- package/dist/services/main/logService/types.d.ts +23 -0
- package/dist/services/main/logService/types.js +1 -0
- package/dist/services/main/logService/utils/parseEnvConfig.d.ts +27 -0
- package/dist/services/main/logService/utils/parseEnvConfig.js +60 -0
- package/dist/services/main/remoteApiControllerService/RemoteApiControllerService.js +2 -2
- package/dist/services/main/testServices/TestService2.js +1 -1
- package/dist/types/Service.d.ts +17 -12
- package/dist/types/Service.js +31 -7
- package/dist/types/ServiceOts.d.ts +1 -0
- package/package.json +1 -1
- package/src/ServiceManager.ts +62 -27
- package/src/services/abstract/apiService/ApiService.ts +7 -1
- package/src/services/abstract/authServices/AuthService.ts +2 -3
- package/src/services/abstract/pageServices/controllers/NSPageControllerService.ts +2 -2
- package/src/services/abstract/webviewServices/WVFrontService.ts +3 -3
- package/src/services/main/httpServices/RequestHandlerService.ts +21 -7
- package/src/services/main/logService/LogService.ts +151 -0
- package/src/services/main/logService/index.ts +7 -0
- package/src/services/main/logService/transports/ConsoleTransport.ts +73 -0
- package/src/services/main/logService/transports/DatabaseTransport.ts +116 -0
- package/src/services/main/logService/types.ts +26 -0
- package/src/services/main/logService/utils/parseEnvConfig.ts +78 -0
- package/src/services/main/remoteApiControllerService/RemoteApiControllerService.ts +2 -2
- package/src/services/main/testServices/TestService2.ts +1 -1
- package/src/types/Service.ts +54 -14
- package/src/types/ServiceOts.ts +1 -0
package/dist/ServiceManager.d.ts
CHANGED
|
@@ -11,8 +11,8 @@ export declare class _ServiceManager {
|
|
|
11
11
|
[key: string]: ServiceEntry<Service>;
|
|
12
12
|
};
|
|
13
13
|
constructor();
|
|
14
|
-
initServices(type: "ns" | "svelte" | "node" | "svelteBackend", services: Array<RegisterServiceInfo
|
|
15
|
-
getService<T extends Service>(serviceName: string): T;
|
|
14
|
+
initServices(type: "ns" | "svelte" | "node" | "svelteBackend", services: Array<RegisterServiceInfo>, namespace?: string): Promise<void>;
|
|
15
|
+
getService<T extends Service>(serviceName: string, namespace?: string): T;
|
|
16
16
|
private setKey;
|
|
17
17
|
private quickService;
|
|
18
18
|
/**
|
package/dist/ServiceManager.js
CHANGED
|
@@ -3,6 +3,7 @@ import { NSPageControllerService } from "./services/abstract/pageServices/contro
|
|
|
3
3
|
import { SVPageControllerService } from "./services/abstract/pageServices/controllers/SVPageControllerService.js";
|
|
4
4
|
import { NSPageService } from "./services/abstract/pageServices/pages/NsPageService.js";
|
|
5
5
|
import { PageService } from "./services/abstract/pageServices/PageServices.js";
|
|
6
|
+
import { LogService } from "./services/main/logService/LogService.js";
|
|
6
7
|
export class _ServiceManager {
|
|
7
8
|
services = {
|
|
8
9
|
TestService: {
|
|
@@ -12,17 +13,30 @@ export class _ServiceManager {
|
|
|
12
13
|
};
|
|
13
14
|
constructor() {
|
|
14
15
|
}
|
|
15
|
-
async initServices(type,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
16
|
+
async initServices(type, services, namespace) {
|
|
17
|
+
const timestamp = new Date().toLocaleTimeString('tr-TR', { hour12: false });
|
|
18
|
+
const prefix = namespace ? `[ServiceManager:${namespace}]` : '[ServiceManager]';
|
|
19
|
+
console.log(`🚀 ${timestamp} ${prefix} Initializing services...`);
|
|
20
|
+
// İLK ÖNCE LogService'i başlat
|
|
21
|
+
let logService;
|
|
22
|
+
if (!namespace) { // LogService sadece global scope'ta oluşturulur
|
|
23
|
+
const logServiceKey = "LogService";
|
|
24
|
+
const logServiceEntry = this.setKey(logServiceKey, {
|
|
25
|
+
serviceSelf: new LogService({
|
|
26
|
+
usedService: {},
|
|
27
|
+
tag: "LogService",
|
|
28
|
+
type: type,
|
|
29
|
+
}),
|
|
30
|
+
status: "waitSetup",
|
|
31
|
+
});
|
|
32
|
+
logService = logServiceEntry;
|
|
33
|
+
await logService.setup();
|
|
34
|
+
await logService.start();
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// Namespace'li servisler global LogService'i kullanır
|
|
38
|
+
logService = this.getService("LogService");
|
|
39
|
+
}
|
|
26
40
|
// // TestService'i oluştur ve başlat
|
|
27
41
|
// const _TestService = this.setKey("TestService", {
|
|
28
42
|
// serviceSelf: new TestService({
|
|
@@ -37,13 +51,13 @@ export class _ServiceManager {
|
|
|
37
51
|
if (type == "ns") {
|
|
38
52
|
const _PageControllerService = this.setKey("NSPageControllerService", {
|
|
39
53
|
serviceSelf: new NSPageControllerService({
|
|
40
|
-
usedService: {},
|
|
54
|
+
usedService: logService ? { "LogService": () => logService } : {},
|
|
41
55
|
abilities: {
|
|
42
56
|
createChildService: (tag) => {
|
|
43
57
|
//console.log("createChildService called for ---", tag);
|
|
44
58
|
const _pageService = this.setKey(tag, {
|
|
45
59
|
serviceSelf: new NSPageService({
|
|
46
|
-
usedService: {},
|
|
60
|
+
usedService: logService ? { "LogService": () => logService } : {},
|
|
47
61
|
tag: tag,
|
|
48
62
|
type: type,
|
|
49
63
|
}),
|
|
@@ -63,7 +77,7 @@ export class _ServiceManager {
|
|
|
63
77
|
else if (type == "svelte") {
|
|
64
78
|
const _PageControllerService = this.setKey("SVPageControllerService", {
|
|
65
79
|
serviceSelf: new SVPageControllerService({
|
|
66
|
-
usedService: {},
|
|
80
|
+
usedService: logService ? { "LogService": () => logService } : {},
|
|
67
81
|
abilities: {
|
|
68
82
|
// Artık class referansını parametre olarak alıyor
|
|
69
83
|
createChildService: (tag, PageCtor) => {
|
|
@@ -71,7 +85,7 @@ export class _ServiceManager {
|
|
|
71
85
|
const ServiceClass = PageCtor ?? PageService;
|
|
72
86
|
const _pageService = this.setKey(tag, {
|
|
73
87
|
serviceSelf: new ServiceClass({
|
|
74
|
-
usedService: {},
|
|
88
|
+
usedService: logService ? { "LogService": () => logService } : {},
|
|
75
89
|
tag: tag,
|
|
76
90
|
type: type,
|
|
77
91
|
}),
|
|
@@ -136,16 +150,31 @@ export class _ServiceManager {
|
|
|
136
150
|
//console.log(`Service ${serviceName} has serviceInfo defined:`, service.serviceInfo);
|
|
137
151
|
}
|
|
138
152
|
const usedService = {};
|
|
153
|
+
// LogService'i her zaman ekle (eğer varsa)
|
|
154
|
+
if (logService) {
|
|
155
|
+
usedService["LogService"] = () => logService;
|
|
156
|
+
}
|
|
139
157
|
if (Array.isArray(service.serviceInfo.requiredServices)) {
|
|
140
158
|
for (const reqName of service.serviceInfo.requiredServices) {
|
|
141
|
-
|
|
159
|
+
// Namespace-aware service lookup: önce namespace'li ara, yoksa global'e fallback
|
|
160
|
+
usedService[reqName] = () => {
|
|
161
|
+
if (namespace) {
|
|
162
|
+
const namespacedService = this.getService(`${namespace}:${reqName}`);
|
|
163
|
+
if (namespacedService)
|
|
164
|
+
return namespacedService;
|
|
165
|
+
}
|
|
166
|
+
return this.getService(reqName);
|
|
167
|
+
};
|
|
142
168
|
}
|
|
143
169
|
}
|
|
144
|
-
|
|
170
|
+
// Namespace varsa key'i namespace:tag formatında oluştur
|
|
171
|
+
const serviceKey = namespace ? `${namespace}:${tag}` : tag;
|
|
172
|
+
const serviceInstance = this.setKey(serviceKey, {
|
|
145
173
|
serviceSelf: new service({
|
|
146
174
|
usedService,
|
|
147
175
|
tag: tag,
|
|
148
176
|
type: type,
|
|
177
|
+
namespace: namespace,
|
|
149
178
|
ServiceManager: _this,
|
|
150
179
|
abilities: {
|
|
151
180
|
createChildService: (tag, PageCtor) => {
|
|
@@ -153,7 +182,7 @@ export class _ServiceManager {
|
|
|
153
182
|
const ServiceClass = PageCtor ?? PageService;
|
|
154
183
|
const _pageService = this.setKey(tag, {
|
|
155
184
|
serviceSelf: new ServiceClass({
|
|
156
|
-
usedService: {},
|
|
185
|
+
usedService: logService ? { "LogService": () => logService } : {},
|
|
157
186
|
tag: tag,
|
|
158
187
|
type: type,
|
|
159
188
|
//@ts-ignore
|
|
@@ -231,15 +260,21 @@ export class _ServiceManager {
|
|
|
231
260
|
// callback();
|
|
232
261
|
// }
|
|
233
262
|
// }
|
|
234
|
-
getService(serviceName) {
|
|
235
|
-
|
|
263
|
+
getService(serviceName, namespace) {
|
|
264
|
+
// Namespace verilmişse önce namespace:serviceName formatında ara
|
|
265
|
+
if (namespace) {
|
|
266
|
+
const namespacedKey = `${namespace}:${serviceName}`;
|
|
267
|
+
if (this.services[namespacedKey]) {
|
|
268
|
+
return this.services[namespacedKey].serviceSelf;
|
|
269
|
+
}
|
|
236
270
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
return undefined;
|
|
271
|
+
// Fallback: direkt isimle ara (core servisler için)
|
|
272
|
+
if (this.services[serviceName]) {
|
|
273
|
+
return this.services[serviceName].serviceSelf;
|
|
241
274
|
}
|
|
242
|
-
|
|
275
|
+
//console.log(`ServiceManager: Service ${serviceName} not found.`);
|
|
276
|
+
//console.log("Available services:", Object.keys(this.services));
|
|
277
|
+
return undefined;
|
|
243
278
|
}
|
|
244
279
|
setKey(key, value) {
|
|
245
280
|
this.services[key] = value;
|
|
@@ -4,8 +4,13 @@ export class ApiService extends Service {
|
|
|
4
4
|
apis = {};
|
|
5
5
|
onStart() {
|
|
6
6
|
const requestHandlerService = this.ots.usedService.RequestHandlerService();
|
|
7
|
+
const namespace = this.ots.namespace;
|
|
7
8
|
Object.entries(this.apis).forEach(([name, { handler, options }]) => {
|
|
8
|
-
|
|
9
|
+
// Namespace varsa handler key'i namespace:ServiceName/method formatında oluştur
|
|
10
|
+
const handlerKey = namespace
|
|
11
|
+
? `${namespace}:${this.tag}/${name}`
|
|
12
|
+
: `${this.tag}/${name}`;
|
|
13
|
+
requestHandlerService.addHandler(handlerKey, handler.bind(this), options || { auth: true, role: "guest" });
|
|
9
14
|
});
|
|
10
15
|
return Promise.resolve({ status: "success", message: "ApiService started" });
|
|
11
16
|
}
|
|
@@ -65,7 +65,7 @@ export class AuthService extends Service {
|
|
|
65
65
|
});
|
|
66
66
|
}
|
|
67
67
|
catch (error) {
|
|
68
|
-
|
|
68
|
+
this.log.error("Logout error:", error);
|
|
69
69
|
return new Response(JSON.stringify({ status: "error", message: "An error occurred during logout" }), { status: 500, headers: { "Content-Type": "application/json" } });
|
|
70
70
|
}
|
|
71
71
|
}
|
|
@@ -92,7 +92,7 @@ export class AuthService extends Service {
|
|
|
92
92
|
if (typeof window === "undefined") {
|
|
93
93
|
bcrypt = await import("bcryptjs");
|
|
94
94
|
}
|
|
95
|
-
|
|
95
|
+
this.log.debug("User authenticated:", result.user);
|
|
96
96
|
const match = await bcrypt.compare(password, result.user.password);
|
|
97
97
|
if (!match) {
|
|
98
98
|
return this.resposeHandler({ success: false });
|
|
@@ -280,7 +280,6 @@ export class AuthService extends Service {
|
|
|
280
280
|
// // const decoded = jwt.verify(token, 'gizliAnahtar');
|
|
281
281
|
// // return !!decoded;
|
|
282
282
|
// // } catch (error) {
|
|
283
|
-
// // console.error('Token verification failed:', error);
|
|
284
283
|
// // return false;
|
|
285
284
|
// // }
|
|
286
285
|
// }
|
|
@@ -2,7 +2,7 @@ import { PageControllerService } from "./PageControllerService.js";
|
|
|
2
2
|
export class NSPageControllerService extends PageControllerService {
|
|
3
3
|
serviceInfo;
|
|
4
4
|
registerPage(tag, opt) {
|
|
5
|
-
|
|
5
|
+
this.log.debug(`Registering page with tag: ${tag}`);
|
|
6
6
|
const service = this.ots.abilities.createChildService?.(tag);
|
|
7
7
|
// await service.setup();
|
|
8
8
|
this.pages[tag] = {
|
|
@@ -12,7 +12,7 @@ export class NSPageControllerService extends PageControllerService {
|
|
|
12
12
|
return service;
|
|
13
13
|
}
|
|
14
14
|
onLoaded() {
|
|
15
|
-
|
|
15
|
+
this.log.info("NSPageControllerService onLoaded called");
|
|
16
16
|
// Implement any additional logic needed when the page is loaded
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -33,7 +33,7 @@ export class WVFrontService extends Service {
|
|
|
33
33
|
this.oWebViewInterface.emit("gotoBack", "");
|
|
34
34
|
}
|
|
35
35
|
async sendFetchRequest(url, options) {
|
|
36
|
-
|
|
36
|
+
this.log.debug("sendFetchRequest", url, options);
|
|
37
37
|
const id = `r_${Date.now()}_${++WVFrontService._requestIdCounter}`;
|
|
38
38
|
return new Promise((resolve) => {
|
|
39
39
|
const handler = (args) => {
|
|
@@ -66,14 +66,14 @@ export class WVFrontService extends Service {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
catch (e) {
|
|
69
|
-
|
|
69
|
+
this.log.error('sendFetchRequest: failed to decode response body', e);
|
|
70
70
|
text = '';
|
|
71
71
|
}
|
|
72
72
|
const response = new Response(text, {
|
|
73
73
|
status: 200,
|
|
74
74
|
headers: { "Content-Type": "application/json" }
|
|
75
75
|
});
|
|
76
|
-
|
|
76
|
+
this.log.debug("sendFetchRequest received (id)", id, envelope.param);
|
|
77
77
|
// remove listeners
|
|
78
78
|
this.oWebViewInterface.removeListener('sendFetchRequest', handler);
|
|
79
79
|
this.oWebViewInterface.removeListener('sendFetchRequestResponse', handler);
|
|
@@ -36,10 +36,11 @@ export declare class RequestHandlerService extends Service {
|
|
|
36
36
|
auth?: boolean;
|
|
37
37
|
role?: string;
|
|
38
38
|
}): Promise<void>;
|
|
39
|
-
requestCome({ params, request, url }: {
|
|
39
|
+
requestCome({ params, request, url, namespace }: {
|
|
40
40
|
params: any;
|
|
41
41
|
request: any;
|
|
42
42
|
url: any;
|
|
43
|
+
namespace?: string;
|
|
43
44
|
}): Promise<any>;
|
|
44
45
|
getCookie(cookieHeader: string | null, name: string): string | undefined;
|
|
45
46
|
resposeHandler(response: any): Response;
|
|
@@ -27,7 +27,7 @@ export class RequestHandlerService extends Service {
|
|
|
27
27
|
this.handlers[name] = { callback, options };
|
|
28
28
|
this.log.OK("RequestHandlerService addHandler", name);
|
|
29
29
|
}
|
|
30
|
-
async requestCome({ params, request, url }) {
|
|
30
|
+
async requestCome({ params, request, url, namespace }) {
|
|
31
31
|
this.log.OK("RequestHandlerService requestCome", params);
|
|
32
32
|
let bodyData = null;
|
|
33
33
|
const contentType = request.headers.get('content-type');
|
|
@@ -49,9 +49,21 @@ export class RequestHandlerService extends Service {
|
|
|
49
49
|
bodyData = null;
|
|
50
50
|
}
|
|
51
51
|
const handlerName = params.path; // Assuming path is the handler name
|
|
52
|
-
|
|
52
|
+
// Namespace-aware handler lookup: önce namespace:handlerName ara, yoksa handlerName ara
|
|
53
|
+
let handler = null;
|
|
54
|
+
if (namespace) {
|
|
55
|
+
const namespacedKey = `${namespace}:${handlerName}`;
|
|
56
|
+
handler = this.handlers[namespacedKey];
|
|
57
|
+
if (handler) {
|
|
58
|
+
this.log.OK("RequestHandlerService found namespaced handler:", namespacedKey);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Fallback: namespace'siz ara (core handlers için - login, logout, etc.)
|
|
62
|
+
if (!handler) {
|
|
63
|
+
handler = this.handlers[handlerName];
|
|
64
|
+
}
|
|
53
65
|
if (!handler) {
|
|
54
|
-
this.log.ERROR("Handler not found:", handlerName);
|
|
66
|
+
this.log.ERROR("Handler not found:", handlerName, "namespace:", namespace);
|
|
55
67
|
//throw new Error(`Handler not found: ${handlerName}`);
|
|
56
68
|
return { status: "error", message: "An error occurred" };
|
|
57
69
|
}
|
|
@@ -77,14 +89,14 @@ export class RequestHandlerService extends Service {
|
|
|
77
89
|
role: handler.options?.role
|
|
78
90
|
}
|
|
79
91
|
});
|
|
80
|
-
|
|
92
|
+
this.log.debug("isAuthenticated", isAuthenticated);
|
|
81
93
|
if (!isAuthenticated.valid) {
|
|
82
94
|
return this.resposeHandler({ status: "error", message: "Unauthorized" });
|
|
83
95
|
}
|
|
84
96
|
user = isAuthenticated.user || null;
|
|
85
97
|
if (isAuthenticated.newAccessToken) {
|
|
86
98
|
// Update cookies with new tokens
|
|
87
|
-
|
|
99
|
+
this.log.debug("update token");
|
|
88
100
|
header = {
|
|
89
101
|
"Set-Cookie": `panel_token=${isAuthenticated.newAccessToken}; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=900, refreshToken=${isAuthenticated.newRefreshToken}; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=604800`,
|
|
90
102
|
};
|
|
@@ -105,8 +117,8 @@ export class RequestHandlerService extends Service {
|
|
|
105
117
|
else {
|
|
106
118
|
response = await handler.callback({ ...event, user });
|
|
107
119
|
}
|
|
108
|
-
|
|
109
|
-
|
|
120
|
+
this.log.debug("RequestHandlerService requestCome response");
|
|
121
|
+
this.log.debug("Object.keys(header).length", Object.keys(header).length);
|
|
110
122
|
// Eğer header içinde Set-Cookie veya başka header varsa response'a ekle
|
|
111
123
|
if (Object.keys(header).length > 0) {
|
|
112
124
|
// Response zaten bir Response nesnesi ise, header'ları birleştirerek yeni bir Response oluştur
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Service, ServiceLogger } from "../../../types/Service.js";
|
|
2
|
+
import { ServiceResponse } from "../../../types/ServiceResponse.js";
|
|
3
|
+
import { ServiceSetupOptions } from "../../../types/ServiceSetupOptions.js";
|
|
4
|
+
import { ILogTransport } from "./types.js";
|
|
5
|
+
export declare class LogService extends Service {
|
|
6
|
+
static serviceInfo: {
|
|
7
|
+
name: string;
|
|
8
|
+
requiredServices: any[];
|
|
9
|
+
};
|
|
10
|
+
private transports;
|
|
11
|
+
private minLevel;
|
|
12
|
+
private enabledNamespaces?;
|
|
13
|
+
private logLevelOrder;
|
|
14
|
+
protected onSetup(options?: ServiceSetupOptions): Promise<ServiceResponse>;
|
|
15
|
+
protected onStart(): Promise<ServiceResponse>;
|
|
16
|
+
protected onStop(): Promise<ServiceResponse>;
|
|
17
|
+
protected onDestroy(): Promise<ServiceResponse>;
|
|
18
|
+
/**
|
|
19
|
+
* Runtime'da yeni transport ekle
|
|
20
|
+
*/
|
|
21
|
+
addTransport(transport: ILogTransport): void;
|
|
22
|
+
/**
|
|
23
|
+
* Transport'u kaldır
|
|
24
|
+
*/
|
|
25
|
+
removeTransport(transportName: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Her service için özel logger döndürür
|
|
28
|
+
*/
|
|
29
|
+
logSetupForService(tag: string, namespace?: string): ServiceLogger;
|
|
30
|
+
private writeLog;
|
|
31
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Service } from "../../../types/Service.js";
|
|
2
|
+
import { ConsoleTransport } from "./transports/ConsoleTransport.js";
|
|
3
|
+
export class LogService extends Service {
|
|
4
|
+
static serviceInfo = {
|
|
5
|
+
name: "LogService",
|
|
6
|
+
requiredServices: []
|
|
7
|
+
};
|
|
8
|
+
transports = [];
|
|
9
|
+
minLevel = 'debug';
|
|
10
|
+
enabledNamespaces;
|
|
11
|
+
logLevelOrder = {
|
|
12
|
+
debug: 0,
|
|
13
|
+
info: 1,
|
|
14
|
+
success: 2,
|
|
15
|
+
warn: 3,
|
|
16
|
+
error: 4
|
|
17
|
+
};
|
|
18
|
+
async onSetup(options) {
|
|
19
|
+
// Default: sadece ConsoleTransport
|
|
20
|
+
const config = options?.config;
|
|
21
|
+
if (config) {
|
|
22
|
+
this.transports = config.transports;
|
|
23
|
+
if (config.minLevel)
|
|
24
|
+
this.minLevel = config.minLevel;
|
|
25
|
+
if (config.enabledNamespaces)
|
|
26
|
+
this.enabledNamespaces = config.enabledNamespaces;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
// Varsayılan: ConsoleTransport
|
|
30
|
+
this.transports = [new ConsoleTransport()];
|
|
31
|
+
}
|
|
32
|
+
this.log.success(`LogService initialized with ${this.transports.length} transport(s)`);
|
|
33
|
+
return { status: "success", message: "LogService setup complete" };
|
|
34
|
+
}
|
|
35
|
+
async onStart() {
|
|
36
|
+
return { status: "success", message: "LogService started" };
|
|
37
|
+
}
|
|
38
|
+
async onStop() {
|
|
39
|
+
// Tüm transport'ları flush et
|
|
40
|
+
await Promise.all(this.transports
|
|
41
|
+
.filter(t => t.flush)
|
|
42
|
+
.map(t => t.flush()));
|
|
43
|
+
return { status: "success", message: "LogService stopped" };
|
|
44
|
+
}
|
|
45
|
+
async onDestroy() {
|
|
46
|
+
// Tüm transport'ları kapat
|
|
47
|
+
await Promise.all(this.transports
|
|
48
|
+
.filter(t => t.close)
|
|
49
|
+
.map(t => t.close()));
|
|
50
|
+
this.transports = [];
|
|
51
|
+
return { status: "success", message: "LogService destroyed" };
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Runtime'da yeni transport ekle
|
|
55
|
+
*/
|
|
56
|
+
addTransport(transport) {
|
|
57
|
+
this.transports.push(transport);
|
|
58
|
+
this.log.info(`Transport added: ${transport.name}`);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Transport'u kaldır
|
|
62
|
+
*/
|
|
63
|
+
removeTransport(transportName) {
|
|
64
|
+
const index = this.transports.findIndex(t => t.name === transportName);
|
|
65
|
+
if (index !== -1) {
|
|
66
|
+
const transport = this.transports[index];
|
|
67
|
+
if (transport.close) {
|
|
68
|
+
transport.close();
|
|
69
|
+
}
|
|
70
|
+
this.transports.splice(index, 1);
|
|
71
|
+
this.log.info(`Transport removed: ${transportName}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Her service için özel logger döndürür
|
|
76
|
+
*/
|
|
77
|
+
logSetupForService(tag, namespace) {
|
|
78
|
+
return {
|
|
79
|
+
debug: (...args) => this.writeLog('debug', tag, namespace, ...args),
|
|
80
|
+
info: (...args) => this.writeLog('info', tag, namespace, ...args),
|
|
81
|
+
success: (...args) => this.writeLog('success', tag, namespace, ...args),
|
|
82
|
+
warn: (...args) => this.writeLog('warn', tag, namespace, ...args),
|
|
83
|
+
error: (...args) => this.writeLog('error', tag, namespace, ...args),
|
|
84
|
+
// Backward compatibility
|
|
85
|
+
OK: (...args) => this.writeLog('success', tag, namespace, ...args),
|
|
86
|
+
ERROR: (...args) => this.writeLog('error', tag, namespace, ...args),
|
|
87
|
+
WARN: (...args) => this.writeLog('warn', tag, namespace, ...args),
|
|
88
|
+
l: (...args) => this.writeLog('info', tag, namespace, ...args),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
writeLog(level, tag, namespace, ...args) {
|
|
92
|
+
// Level filtreleme (LogService seviyesinde)
|
|
93
|
+
if (this.logLevelOrder[level] < this.logLevelOrder[this.minLevel]) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// Namespace filtreleme
|
|
97
|
+
if (this.enabledNamespaces && this.enabledNamespaces.length > 0) {
|
|
98
|
+
const fullName = namespace ? `${namespace}:${tag}` : tag;
|
|
99
|
+
const isEnabled = this.enabledNamespaces.some(ns => fullName.includes(ns) || tag.includes(ns));
|
|
100
|
+
if (!isEnabled)
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const entry = {
|
|
104
|
+
timestamp: new Date(),
|
|
105
|
+
level,
|
|
106
|
+
tag,
|
|
107
|
+
namespace,
|
|
108
|
+
message: args[0],
|
|
109
|
+
args: args.slice(1)
|
|
110
|
+
};
|
|
111
|
+
// Her transport için kontrol et ve logla
|
|
112
|
+
for (const transport of this.transports) {
|
|
113
|
+
// Transport seviyesinde filtreleme
|
|
114
|
+
if (!transport.shouldLog(entry)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
const result = transport.log(entry);
|
|
119
|
+
// Eğer Promise dönerse bekle
|
|
120
|
+
if (result instanceof Promise) {
|
|
121
|
+
result.catch(err => {
|
|
122
|
+
console.error(`[LogService] Transport ${transport.name} failed:`, err);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
console.error(`[LogService] Transport ${transport.name} failed:`, err);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { LogService } from "./LogService.js";
|
|
2
|
+
export { ConsoleTransport } from "./transports/ConsoleTransport.js";
|
|
3
|
+
export { DatabaseTransport } from "./transports/DatabaseTransport.js";
|
|
4
|
+
export { parseLogConfigFromEnv, getDatabaseTransportConfigFromEnv } from "./utils/parseEnvConfig.js";
|
|
5
|
+
export type { ILogEntry, ILogTransport, LogServiceConfig } from "./types.js";
|
|
6
|
+
export type { DatabaseTransportOptions } from "./transports/DatabaseTransport.js";
|
|
7
|
+
export type { EnvLogConfig } from "./utils/parseEnvConfig.js";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { LogService } from "./LogService.js";
|
|
2
|
+
export { ConsoleTransport } from "./transports/ConsoleTransport.js";
|
|
3
|
+
export { DatabaseTransport } from "./transports/DatabaseTransport.js";
|
|
4
|
+
export { parseLogConfigFromEnv, getDatabaseTransportConfigFromEnv } from "./utils/parseEnvConfig.js";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ILogEntry, ILogTransport } from "../types.js";
|
|
2
|
+
import { LogLevel } from "../../../../types/Service.js";
|
|
3
|
+
export declare class ConsoleTransport implements ILogTransport {
|
|
4
|
+
name: string;
|
|
5
|
+
levels?: LogLevel[];
|
|
6
|
+
minLevel?: LogLevel;
|
|
7
|
+
private logLevelOrder;
|
|
8
|
+
constructor(options?: {
|
|
9
|
+
levels?: LogLevel[];
|
|
10
|
+
minLevel?: LogLevel;
|
|
11
|
+
});
|
|
12
|
+
shouldLog(entry: ILogEntry): boolean;
|
|
13
|
+
private getLogPrefix;
|
|
14
|
+
private getIcon;
|
|
15
|
+
log(entry: ILogEntry): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export class ConsoleTransport {
|
|
2
|
+
name = "ConsoleTransport";
|
|
3
|
+
levels;
|
|
4
|
+
minLevel;
|
|
5
|
+
logLevelOrder = {
|
|
6
|
+
debug: 0,
|
|
7
|
+
info: 1,
|
|
8
|
+
success: 2,
|
|
9
|
+
warn: 3,
|
|
10
|
+
error: 4
|
|
11
|
+
};
|
|
12
|
+
constructor(options) {
|
|
13
|
+
if (options?.levels)
|
|
14
|
+
this.levels = options.levels;
|
|
15
|
+
if (options?.minLevel)
|
|
16
|
+
this.minLevel = options.minLevel;
|
|
17
|
+
}
|
|
18
|
+
shouldLog(entry) {
|
|
19
|
+
// Eğer spesifik level'lar belirtilmişse
|
|
20
|
+
if (this.levels && this.levels.length > 0) {
|
|
21
|
+
return this.levels.includes(entry.level);
|
|
22
|
+
}
|
|
23
|
+
// Eğer minimum level belirtilmişse
|
|
24
|
+
if (this.minLevel) {
|
|
25
|
+
return this.logLevelOrder[entry.level] >= this.logLevelOrder[this.minLevel];
|
|
26
|
+
}
|
|
27
|
+
// Varsayılan: her şeyi logla
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
getLogPrefix(entry) {
|
|
31
|
+
if (entry.namespace) {
|
|
32
|
+
return `[${entry.namespace}:${entry.tag}]`;
|
|
33
|
+
}
|
|
34
|
+
return `[${entry.tag}]`;
|
|
35
|
+
}
|
|
36
|
+
getIcon(level) {
|
|
37
|
+
const icons = {
|
|
38
|
+
debug: '🔍',
|
|
39
|
+
info: 'ℹ️',
|
|
40
|
+
success: '✅',
|
|
41
|
+
warn: '⚠️',
|
|
42
|
+
error: '❌'
|
|
43
|
+
};
|
|
44
|
+
return icons[level];
|
|
45
|
+
}
|
|
46
|
+
log(entry) {
|
|
47
|
+
const timestamp = entry.timestamp.toLocaleTimeString('tr-TR', { hour12: false });
|
|
48
|
+
const prefix = this.getLogPrefix(entry);
|
|
49
|
+
const icon = this.getIcon(entry.level);
|
|
50
|
+
const formattedArgs = [`${icon} ${timestamp} ${prefix}`, entry.message, ...entry.args];
|
|
51
|
+
switch (entry.level) {
|
|
52
|
+
case 'error':
|
|
53
|
+
console.error(...formattedArgs);
|
|
54
|
+
break;
|
|
55
|
+
case 'warn':
|
|
56
|
+
console.warn(...formattedArgs);
|
|
57
|
+
break;
|
|
58
|
+
default:
|
|
59
|
+
console.log(...formattedArgs);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ILogEntry, ILogTransport } from "../types.js";
|
|
2
|
+
import { LogLevel } from "../../../../types/Service.js";
|
|
3
|
+
export interface DatabaseTransportOptions {
|
|
4
|
+
levels?: LogLevel[];
|
|
5
|
+
minLevel?: LogLevel;
|
|
6
|
+
getDatabaseService: () => any;
|
|
7
|
+
collectionName?: string;
|
|
8
|
+
batchSize?: number;
|
|
9
|
+
flushInterval?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class DatabaseTransport implements ILogTransport {
|
|
12
|
+
name: string;
|
|
13
|
+
levels?: LogLevel[];
|
|
14
|
+
minLevel?: LogLevel;
|
|
15
|
+
private getDatabaseService;
|
|
16
|
+
private collectionName;
|
|
17
|
+
private batchSize;
|
|
18
|
+
private flushInterval;
|
|
19
|
+
private logBuffer;
|
|
20
|
+
private flushTimer?;
|
|
21
|
+
private logLevelOrder;
|
|
22
|
+
constructor(options: DatabaseTransportOptions);
|
|
23
|
+
shouldLog(entry: ILogEntry): boolean;
|
|
24
|
+
log(entry: ILogEntry): Promise<void>;
|
|
25
|
+
flush(): Promise<void>;
|
|
26
|
+
close(): Promise<void>;
|
|
27
|
+
private startFlushTimer;
|
|
28
|
+
}
|