@urga-panel/ur-panels-core 1.0.20 → 1.0.22

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.
Files changed (41) hide show
  1. package/dist/ServiceManager.js +34 -16
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +2 -0
  4. package/dist/services/abstract/authServices/AuthService.js +2 -3
  5. package/dist/services/abstract/pageServices/controllers/NSPageControllerService.js +2 -2
  6. package/dist/services/abstract/webviewServices/WVFrontService.js +3 -3
  7. package/dist/services/main/httpServices/RequestHandlerService.js +4 -4
  8. package/dist/services/main/logService/LogService.d.ts +31 -0
  9. package/dist/services/main/logService/LogService.js +131 -0
  10. package/dist/services/main/logService/index.d.ts +7 -0
  11. package/dist/services/main/logService/index.js +4 -0
  12. package/dist/services/main/logService/transports/ConsoleTransport.d.ts +16 -0
  13. package/dist/services/main/logService/transports/ConsoleTransport.js +62 -0
  14. package/dist/services/main/logService/transports/DatabaseTransport.d.ts +28 -0
  15. package/dist/services/main/logService/transports/DatabaseTransport.js +90 -0
  16. package/dist/services/main/logService/types.d.ts +23 -0
  17. package/dist/services/main/logService/types.js +1 -0
  18. package/dist/services/main/logService/utils/parseEnvConfig.d.ts +27 -0
  19. package/dist/services/main/logService/utils/parseEnvConfig.js +60 -0
  20. package/dist/services/main/remoteApiControllerService/RemoteApiControllerService.js +2 -2
  21. package/dist/services/main/testServices/TestService2.js +1 -1
  22. package/dist/types/Service.d.ts +17 -12
  23. package/dist/types/Service.js +31 -7
  24. package/dist/types/ServiceOts.d.ts +1 -0
  25. package/package.json +1 -1
  26. package/src/ServiceManager.ts +35 -16
  27. package/src/index.ts +4 -0
  28. package/src/services/abstract/authServices/AuthService.ts +2 -3
  29. package/src/services/abstract/pageServices/controllers/NSPageControllerService.ts +2 -2
  30. package/src/services/abstract/webviewServices/WVFrontService.ts +3 -3
  31. package/src/services/main/httpServices/RequestHandlerService.ts +4 -4
  32. package/src/services/main/logService/LogService.ts +151 -0
  33. package/src/services/main/logService/index.ts +7 -0
  34. package/src/services/main/logService/transports/ConsoleTransport.ts +73 -0
  35. package/src/services/main/logService/transports/DatabaseTransport.ts +116 -0
  36. package/src/services/main/logService/types.ts +26 -0
  37. package/src/services/main/logService/utils/parseEnvConfig.ts +78 -0
  38. package/src/services/main/remoteApiControllerService/RemoteApiControllerService.ts +2 -2
  39. package/src/services/main/testServices/TestService2.ts +1 -1
  40. package/src/types/Service.ts +54 -14
  41. package/src/types/ServiceOts.ts +1 -0
@@ -0,0 +1,116 @@
1
+ import { ILogEntry, ILogTransport } from "../types";
2
+ import { LogLevel } from "../../../../types/Service";
3
+
4
+ export interface DatabaseTransportOptions {
5
+ levels?: LogLevel[];
6
+ minLevel?: LogLevel;
7
+ getDatabaseService: () => any; // DatabaseService'i almak için callback
8
+ collectionName?: string; // Varsayılan: "logs"
9
+ batchSize?: number; // Toplu yazma için
10
+ flushInterval?: number; // ms cinsinden
11
+ }
12
+
13
+ export class DatabaseTransport implements ILogTransport {
14
+ name = "DatabaseTransport";
15
+ levels?: LogLevel[];
16
+ minLevel?: LogLevel;
17
+
18
+ private getDatabaseService: () => any;
19
+ private collectionName: string;
20
+ private batchSize: number;
21
+ private flushInterval: number;
22
+ private logBuffer: ILogEntry[] = [];
23
+ private flushTimer?: NodeJS.Timeout;
24
+
25
+ private logLevelOrder: Record<LogLevel, number> = {
26
+ debug: 0,
27
+ info: 1,
28
+ success: 2,
29
+ warn: 3,
30
+ error: 4
31
+ };
32
+
33
+ constructor(options: DatabaseTransportOptions) {
34
+ this.getDatabaseService = options.getDatabaseService;
35
+ this.collectionName = options.collectionName || "logs";
36
+ this.batchSize = options.batchSize || 10;
37
+ this.flushInterval = options.flushInterval || 5000; // 5 saniye
38
+
39
+ if (options.levels) this.levels = options.levels;
40
+ if (options.minLevel) this.minLevel = options.minLevel;
41
+
42
+ // Periyodik flush başlat
43
+ this.startFlushTimer();
44
+ }
45
+
46
+ shouldLog(entry: ILogEntry): boolean {
47
+ // Eğer spesifik level'lar belirtilmişse
48
+ if (this.levels && this.levels.length > 0) {
49
+ return this.levels.includes(entry.level);
50
+ }
51
+
52
+ // Eğer minimum level belirtilmişse
53
+ if (this.minLevel) {
54
+ return this.logLevelOrder[entry.level] >= this.logLevelOrder[this.minLevel];
55
+ }
56
+
57
+ // Varsayılan: sadece warn ve error
58
+ return entry.level === 'warn' || entry.level === 'error';
59
+ }
60
+
61
+ async log(entry: ILogEntry): Promise<void> {
62
+ // Buffer'a ekle
63
+ this.logBuffer.push(entry);
64
+
65
+ // Eğer buffer dolmuşsa hemen flush et
66
+ if (this.logBuffer.length >= this.batchSize) {
67
+ await this.flush();
68
+ }
69
+ }
70
+
71
+ async flush(): Promise<void> {
72
+ if (this.logBuffer.length === 0) return;
73
+
74
+ try {
75
+ const dbService = this.getDatabaseService();
76
+ if (!dbService || !dbService.client) {
77
+ console.error('[DatabaseTransport] DatabaseService not ready');
78
+ return;
79
+ }
80
+
81
+ const db = dbService.client.db();
82
+ const logsCollection = db.collection(this.collectionName);
83
+
84
+ const documents = this.logBuffer.map(entry => ({
85
+ timestamp: entry.timestamp,
86
+ level: entry.level,
87
+ service: entry.tag,
88
+ namespace: entry.namespace,
89
+ message: entry.message,
90
+ args: entry.args,
91
+ createdAt: new Date()
92
+ }));
93
+
94
+ await logsCollection.insertMany(documents);
95
+ this.logBuffer = []; // Buffer'ı temizle
96
+ } catch (error) {
97
+ console.error('[DatabaseTransport] Failed to write logs:', error);
98
+ }
99
+ }
100
+
101
+ async close(): Promise<void> {
102
+ // Timer'ı durdur
103
+ if (this.flushTimer) {
104
+ clearInterval(this.flushTimer);
105
+ }
106
+
107
+ // Kalan log'ları flush et
108
+ await this.flush();
109
+ }
110
+
111
+ private startFlushTimer(): void {
112
+ this.flushTimer = setInterval(async () => {
113
+ await this.flush();
114
+ }, this.flushInterval);
115
+ }
116
+ }
@@ -0,0 +1,26 @@
1
+ import { LogLevel } from "../../../types/Service";
2
+
3
+ export interface ILogEntry {
4
+ timestamp: Date;
5
+ level: LogLevel;
6
+ tag: string;
7
+ namespace?: string;
8
+ message: string;
9
+ args: any[];
10
+ }
11
+
12
+ export interface ILogTransport {
13
+ name: string;
14
+ levels?: LogLevel[]; // Eğer belirtilirse, sadece bu level'ları logla
15
+ minLevel?: LogLevel; // Eğer belirtilirse, bu level ve üstü
16
+ shouldLog(entry: ILogEntry): boolean; // Transport log'u kabul ediyor mu?
17
+ log(entry: ILogEntry): void | Promise<void>;
18
+ flush?(): void | Promise<void>;
19
+ close?(): void | Promise<void>;
20
+ }
21
+
22
+ export interface LogServiceConfig {
23
+ transports: ILogTransport[];
24
+ minLevel?: LogLevel;
25
+ enabledNamespaces?: string[]; // ['template:kurs', 'DatabaseService']
26
+ }
@@ -0,0 +1,78 @@
1
+ import { LogLevel } from "../../../../types/Service";
2
+ import { LogServiceConfig } from "../types";
3
+ import { ConsoleTransport } from "../transports/ConsoleTransport";
4
+
5
+ export interface EnvLogConfig {
6
+ LOG_LEVEL?: string;
7
+ LOG_CONSOLE_LEVELS?: string;
8
+ LOG_NAMESPACES?: string;
9
+ LOG_DATABASE_ENABLED?: string;
10
+ LOG_DATABASE_LEVELS?: string;
11
+ }
12
+
13
+ /**
14
+ * Environment variable'lardan LogService config'i oluşturur
15
+ *
16
+ * Örnek .env:
17
+ * LOG_LEVEL=info
18
+ * LOG_CONSOLE_LEVELS=debug,info,success,warn,error
19
+ * LOG_NAMESPACES=DatabaseService,AuthService
20
+ * LOG_DATABASE_ENABLED=true
21
+ * LOG_DATABASE_LEVELS=warn,error
22
+ */
23
+ export function parseLogConfigFromEnv(env: EnvLogConfig): Partial<LogServiceConfig> {
24
+ const config: Partial<LogServiceConfig> = {
25
+ transports: []
26
+ };
27
+
28
+ // Minimum log level
29
+ if (env.LOG_LEVEL) {
30
+ const level = env.LOG_LEVEL.toLowerCase();
31
+ if (['debug', 'info', 'success', 'warn', 'error'].includes(level)) {
32
+ config.minLevel = level as LogLevel;
33
+ }
34
+ }
35
+
36
+ // Namespace filtreleme
37
+ if (env.LOG_NAMESPACES) {
38
+ config.enabledNamespaces = env.LOG_NAMESPACES
39
+ .split(',')
40
+ .map(s => s.trim())
41
+ .filter(s => s.length > 0);
42
+ }
43
+
44
+ // ConsoleTransport (varsayılan olarak her zaman var)
45
+ let consoleLevels: LogLevel[] | undefined;
46
+ if (env.LOG_CONSOLE_LEVELS) {
47
+ consoleLevels = env.LOG_CONSOLE_LEVELS
48
+ .split(',')
49
+ .map(s => s.trim().toLowerCase())
50
+ .filter(s => ['debug', 'info', 'success', 'warn', 'error'].includes(s)) as LogLevel[];
51
+ }
52
+
53
+ config.transports!.push(new ConsoleTransport({
54
+ levels: consoleLevels
55
+ }));
56
+
57
+ return config;
58
+ }
59
+
60
+ /**
61
+ * DatabaseTransport için config döner
62
+ */
63
+ export function getDatabaseTransportConfigFromEnv(env: EnvLogConfig): { enabled: boolean, levels?: LogLevel[] } {
64
+ const enabled = env.LOG_DATABASE_ENABLED === 'true';
65
+
66
+ let levels: LogLevel[] | undefined;
67
+ if (env.LOG_DATABASE_LEVELS) {
68
+ levels = env.LOG_DATABASE_LEVELS
69
+ .split(',')
70
+ .map(s => s.trim().toLowerCase())
71
+ .filter(s => ['debug', 'info', 'success', 'warn', 'error'].includes(s)) as LogLevel[];
72
+ } else {
73
+ // Varsayılan: sadece warn ve error
74
+ levels = ['warn', 'error'];
75
+ }
76
+
77
+ return { enabled, levels };
78
+ }
@@ -46,11 +46,11 @@ export class RemoteApiControllerService extends Service {
46
46
  }
47
47
  addApi(apiName: string, serviceRef: any, apiConfig: apiConfig): void {
48
48
  if (this.apis[apiName]) {
49
- console.warn(`API ${apiName} already exists. Overwriting.`);
49
+ this.log.warn(`API ${apiName} already exists. Overwriting.`);
50
50
  }
51
51
  this.apis[apiName] = apiConfig;
52
52
  this.apis[apiName].serviceRef = serviceRef;
53
- console.log(`API ${apiName} added with config:`, apiConfig);
53
+ this.log.info(`API ${apiName} added with config:`, apiConfig);
54
54
 
55
55
  // Create a service for each API
56
56
  Object.keys(this.apis).forEach(async apiName => {
@@ -13,7 +13,7 @@ export class Test2Service extends Service {
13
13
  serviceInfo: { name: string; requiredServices: string[]; };
14
14
  constructor(ots:Test2Ots) {
15
15
  super({...ots});
16
- console.log("Test2Service initialized");
16
+ this.log.info("Test2Service initialized");
17
17
  }
18
18
 
19
19
  protected async onSetup(options?: ServiceSetupOptions): Promise<ServiceResponse> {
@@ -2,6 +2,21 @@ import { ServiceOts } from "./ServiceOts";
2
2
  import { ServiceResponse } from "./ServiceResponse";
3
3
  import { ServiceSetupOptions } from "./ServiceSetupOptions";
4
4
 
5
+ export type LogLevel = 'debug' | 'info' | 'success' | 'warn' | 'error';
6
+
7
+ export interface ServiceLogger {
8
+ debug: (...args: any[]) => void;
9
+ info: (...args: any[]) => void;
10
+ success: (...args: any[]) => void;
11
+ warn: (...args: any[]) => void;
12
+ error: (...args: any[]) => void;
13
+ // Backward compatibility
14
+ OK: (...args: any[]) => void;
15
+ ERROR: (...args: any[]) => void;
16
+ WARN: (...args: any[]) => void;
17
+ l: (...args: any[]) => void;
18
+ }
19
+
5
20
  export abstract class Service {
6
21
 
7
22
  static serviceInfo: {
@@ -9,12 +24,8 @@ export abstract class Service {
9
24
  requiredServices: string[];
10
25
  }
11
26
  public tag: string = "";
12
- public log: {
13
- OK: Function,
14
- ERROR: Function,
15
- l: Function,
16
- WARN: Function
17
- }
27
+ public namespace?: string;
28
+ public log: ServiceLogger;
18
29
 
19
30
  protected abstract onSetup(options?: ServiceSetupOptions):Promise<ServiceResponse>;
20
31
  protected abstract onStart(): Promise<ServiceResponse>;
@@ -40,22 +51,51 @@ export abstract class Service {
40
51
 
41
52
  constructor(private opts: ServiceOts) {
42
53
  this.tag = opts.tag;
54
+ this.namespace = opts.namespace;
55
+
43
56
  if (!opts.usedService["LogService"]) {
44
- //console.error("LogService not found for", opts.tag);
45
57
  this.log = this.logSetup();
46
58
  return;
47
59
  }
48
60
  else {
49
- //console.log("LogService found for", opts.usedService["LogService"]);
50
- this.log = (opts.usedService["LogService"] as unknown as any).logSetupForService(this.tag);
61
+ this.log = (opts.usedService["LogService"] as unknown as any).logSetupForService(this.tag, this.namespace);
51
62
  }
52
63
  }
53
- logSetup() {
64
+
65
+ private getLogPrefix(): string {
66
+ if (this.namespace) {
67
+ return `[${this.namespace}:${this.tag}]`;
68
+ }
69
+ return `[${this.tag}]`;
70
+ }
71
+
72
+ private formatMessage(level: LogLevel, ...args: any[]): any[] {
73
+ const timestamp = new Date().toLocaleTimeString('tr-TR', { hour12: false });
74
+ const prefix = this.getLogPrefix();
75
+
76
+ const icons: Record<LogLevel, string> = {
77
+ debug: '🔍',
78
+ info: 'ℹ️',
79
+ success: '✅',
80
+ warn: '⚠️',
81
+ error: '❌'
82
+ };
83
+
84
+ return [`${icons[level]} ${timestamp} ${prefix}`, ...args];
85
+ }
86
+
87
+ logSetup(): ServiceLogger {
54
88
  return {
55
- OK: console.log.bind(console, `[${this.tag}]` + "-[OK]"),
56
- ERROR: console.error.bind(console, `[${this.tag}]` + "-[ERROR]"),
57
- WARN: console.warn.bind(console, `[${this.tag}]` + "-[WARN]"),
58
- l: console.log.bind(console, `[${this.tag}]`),
89
+ debug: (...args: any[]) => console.log(...this.formatMessage('debug', ...args)),
90
+ info: (...args: any[]) => console.log(...this.formatMessage('info', ...args)),
91
+ success: (...args: any[]) => console.log(...this.formatMessage('success', ...args)),
92
+ warn: (...args: any[]) => console.warn(...this.formatMessage('warn', ...args)),
93
+ error: (...args: any[]) => console.error(...this.formatMessage('error', ...args)),
94
+ // Backward compatibility
95
+ OK: (...args: any[]) => console.log(...this.formatMessage('success', ...args)),
96
+ ERROR: (...args: any[]) => console.error(...this.formatMessage('error', ...args)),
97
+ WARN: (...args: any[]) => console.warn(...this.formatMessage('warn', ...args)),
98
+ l: (...args: any[]) => console.log(...this.formatMessage('info', ...args)),
59
99
  }
60
100
  }
61
101
  }
@@ -6,6 +6,7 @@ export type ServiceOts = {
6
6
  [key: string]: () => Service
7
7
  },
8
8
  tag:string,
9
+ namespace?: string,
9
10
  abilities?: {
10
11
  createChildService?: (tag:string, PageCtor: ServiceConstructor<Service>)=> Service,
11
12
  }