@0xobelisk/graphql-server 1.2.0-pre.24
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/Dockerfile +31 -0
- package/EXPRESS_MIGRATION.md +176 -0
- package/LICENSE +92 -0
- package/README.md +908 -0
- package/dist/config/subscription-config.d.ts +47 -0
- package/dist/config/subscription-config.d.ts.map +1 -0
- package/dist/config/subscription-config.js +133 -0
- package/dist/config/subscription-config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +217 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/all-fields-filter-plugin.d.ts +4 -0
- package/dist/plugins/all-fields-filter-plugin.d.ts.map +1 -0
- package/dist/plugins/all-fields-filter-plugin.js +132 -0
- package/dist/plugins/all-fields-filter-plugin.js.map +1 -0
- package/dist/plugins/database-introspector.d.ts +23 -0
- package/dist/plugins/database-introspector.d.ts.map +1 -0
- package/dist/plugins/database-introspector.js +96 -0
- package/dist/plugins/database-introspector.js.map +1 -0
- package/dist/plugins/enhanced-playground.d.ts +9 -0
- package/dist/plugins/enhanced-playground.d.ts.map +1 -0
- package/dist/plugins/enhanced-playground.js +97 -0
- package/dist/plugins/enhanced-playground.js.map +1 -0
- package/dist/plugins/enhanced-server-manager.d.ts +28 -0
- package/dist/plugins/enhanced-server-manager.d.ts.map +1 -0
- package/dist/plugins/enhanced-server-manager.js +232 -0
- package/dist/plugins/enhanced-server-manager.js.map +1 -0
- package/dist/plugins/index.d.ts +9 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +26 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/postgraphile-config.d.ts +94 -0
- package/dist/plugins/postgraphile-config.d.ts.map +1 -0
- package/dist/plugins/postgraphile-config.js +183 -0
- package/dist/plugins/postgraphile-config.js.map +1 -0
- package/dist/plugins/query-filter.d.ts +4 -0
- package/dist/plugins/query-filter.d.ts.map +1 -0
- package/dist/plugins/query-filter.js +42 -0
- package/dist/plugins/query-filter.js.map +1 -0
- package/dist/plugins/simple-naming.d.ts +4 -0
- package/dist/plugins/simple-naming.d.ts.map +1 -0
- package/dist/plugins/simple-naming.js +79 -0
- package/dist/plugins/simple-naming.js.map +1 -0
- package/dist/plugins/welcome-page.d.ts +11 -0
- package/dist/plugins/welcome-page.d.ts.map +1 -0
- package/dist/plugins/welcome-page.js +203 -0
- package/dist/plugins/welcome-page.js.map +1 -0
- package/dist/universal-subscriptions.d.ts +32 -0
- package/dist/universal-subscriptions.d.ts.map +1 -0
- package/dist/universal-subscriptions.js +318 -0
- package/dist/universal-subscriptions.js.map +1 -0
- package/dist/utils/logger/index.d.ts +80 -0
- package/dist/utils/logger/index.d.ts.map +1 -0
- package/dist/utils/logger/index.js +232 -0
- package/dist/utils/logger/index.js.map +1 -0
- package/docker-compose.yml +87 -0
- package/package.json +71 -0
- package/server.log +62 -0
- package/src/config/subscription-config.ts +186 -0
- package/src/index.ts +239 -0
- package/src/plugins/README.md +123 -0
- package/src/plugins/all-fields-filter-plugin.ts +158 -0
- package/src/plugins/database-introspector.ts +126 -0
- package/src/plugins/enhanced-playground.ts +105 -0
- package/src/plugins/enhanced-server-manager.ts +282 -0
- package/src/plugins/index.ts +9 -0
- package/src/plugins/postgraphile-config.ts +226 -0
- package/src/plugins/query-filter.ts +50 -0
- package/src/plugins/simple-naming.ts +105 -0
- package/src/plugins/welcome-page.ts +218 -0
- package/src/universal-subscriptions.ts +397 -0
- package/src/utils/logger/README.md +193 -0
- package/src/utils/logger/index.ts +315 -0
- package/sui-indexer-schema.graphql +1004 -0
- package/test-express.js +124 -0
- package/test_listen_subscription.js +121 -0
- package/test_notification.js +63 -0
- package/tsconfig.json +28 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Dubhe Logger System
|
|
2
|
+
|
|
3
|
+
High-performance logging system based on Pino, featuring object-oriented design for better understanding and extensibility.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 High-performance logging based on Pino
|
|
8
|
+
- 📝 Support for structured logging
|
|
9
|
+
- 🎨 Colorful pretty printing in development environment
|
|
10
|
+
- 📁 File logging support in production environment
|
|
11
|
+
- 🔧 Flexible configuration options
|
|
12
|
+
- 📦 Component-based log management
|
|
13
|
+
- 🛡️ TypeScript type safety
|
|
14
|
+
|
|
15
|
+
## Basic Usage
|
|
16
|
+
|
|
17
|
+
### 1. Using Predefined Component Loggers
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { dbLogger, serverLogger, systemLogger } from './utils/logger';
|
|
21
|
+
|
|
22
|
+
// Database operation logs
|
|
23
|
+
dbLogger.info('Database connection successful', { host: 'localhost', port: 5432 });
|
|
24
|
+
dbLogger.error('Query failed', new Error('Connection timeout'), { query: 'SELECT * FROM users' });
|
|
25
|
+
|
|
26
|
+
// Server logs
|
|
27
|
+
serverLogger.info('Server started', { port: 4000, env: 'development' });
|
|
28
|
+
|
|
29
|
+
// System logs
|
|
30
|
+
systemLogger.warn('High memory usage', { usage: '85%' });
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. Creating Custom Component Loggers
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { createComponentLogger } from './utils/logger';
|
|
37
|
+
|
|
38
|
+
const apiLogger = createComponentLogger('api');
|
|
39
|
+
const cacheLogger = createComponentLogger('cache');
|
|
40
|
+
|
|
41
|
+
apiLogger.info('API request', { method: 'GET', path: '/users', userId: 123 });
|
|
42
|
+
cacheLogger.debug('Cache hit', { key: 'user:123', ttl: 3600 });
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 3. Using Logger Class to Create Custom Instances
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import { Logger } from './utils/logger';
|
|
49
|
+
|
|
50
|
+
// Create logger with custom configuration
|
|
51
|
+
const customLogger = new Logger({
|
|
52
|
+
level: 'debug',
|
|
53
|
+
service: 'my-service',
|
|
54
|
+
enableFileLogging: true,
|
|
55
|
+
logsDir: './custom-logs',
|
|
56
|
+
enablePrettyPrint: false
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const myLogger = customLogger.createComponentLogger('my-component');
|
|
60
|
+
myLogger.info('Custom log message');
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Configuration Options
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
interface LoggerConfig {
|
|
67
|
+
level?: string; // Log level (debug|info|warn|error)
|
|
68
|
+
service?: string; // Service name
|
|
69
|
+
component?: string; // Component name
|
|
70
|
+
enableFileLogging?: boolean; // Enable file logging
|
|
71
|
+
logsDir?: string; // Log file directory
|
|
72
|
+
enablePrettyPrint?: boolean; // Enable colorful output
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Utility Functions
|
|
77
|
+
|
|
78
|
+
### Performance Logging
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import { logPerformance } from './utils/logger';
|
|
82
|
+
|
|
83
|
+
const startTime = Date.now();
|
|
84
|
+
// ... perform operations
|
|
85
|
+
logPerformance('Database query', startTime, { table: 'users', rows: 1000 });
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Database Operation Logging
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { logDatabaseOperation } from './utils/logger';
|
|
92
|
+
|
|
93
|
+
logDatabaseOperation('SELECT', 'users', { limit: 10, offset: 0 });
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### WebSocket Event Logging
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { logWebSocketEvent } from './utils/logger';
|
|
100
|
+
|
|
101
|
+
logWebSocketEvent('client_connected', 5, { clientId: 'abc123' });
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### GraphQL Query Logging
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { logGraphQLQuery } from './utils/logger';
|
|
108
|
+
|
|
109
|
+
logGraphQLQuery('query', 'query GetUsers { users { id name } }', { limit: 10 });
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Predefined Component Loggers
|
|
113
|
+
|
|
114
|
+
| Logger | Component | Purpose |
|
|
115
|
+
|--------|-----------|---------|
|
|
116
|
+
| `dbLogger` | database | Database operations |
|
|
117
|
+
| `serverLogger` | server | Server related |
|
|
118
|
+
| `wsLogger` | websocket | WebSocket connections |
|
|
119
|
+
| `gqlLogger` | graphql | GraphQL queries |
|
|
120
|
+
| `subscriptionLogger` | subscription | Subscription features |
|
|
121
|
+
| `systemLogger` | system | System level |
|
|
122
|
+
| `authLogger` | auth | Authentication |
|
|
123
|
+
| `perfLogger` | performance | Performance monitoring |
|
|
124
|
+
|
|
125
|
+
## Environment Variables
|
|
126
|
+
|
|
127
|
+
- `LOG_LEVEL`: Set log level (debug|info|warn|error)
|
|
128
|
+
- `NODE_ENV`: Set environment mode, enables pretty printing in development
|
|
129
|
+
|
|
130
|
+
## Log Format
|
|
131
|
+
|
|
132
|
+
### Development Environment (Pretty Print)
|
|
133
|
+
```
|
|
134
|
+
2024-01-15 10:30:45 [INFO] dubhe-graphql-server [database]: Database connection successful {"host": "localhost", "port": 5432}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Production Environment (JSON)
|
|
138
|
+
```json
|
|
139
|
+
{"level":30,"time":"2024-01-15T10:30:45.123Z","service":"dubhe-graphql-server","component":"database","msg":"Database connection successful","host":"localhost","port":5432}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Advanced Usage
|
|
143
|
+
|
|
144
|
+
### Extending Logger Class
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import { Logger, LoggerConfig } from './utils/logger';
|
|
148
|
+
|
|
149
|
+
class CustomLogger extends Logger {
|
|
150
|
+
constructor(config: LoggerConfig) {
|
|
151
|
+
super(config);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Add custom methods
|
|
155
|
+
public audit(action: string, userId: string, meta?: any) {
|
|
156
|
+
const auditLogger = this.createComponentLogger('audit');
|
|
157
|
+
auditLogger.info(`User action: ${action}`, { userId, timestamp: new Date().toISOString(), ...meta });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const logger = new CustomLogger({ service: 'audit-service' });
|
|
162
|
+
logger.audit('login', 'user123', { ip: '192.168.1.1' });
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Getting Raw Pino Instance
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
import { Logger } from './utils/logger';
|
|
169
|
+
|
|
170
|
+
const logger = new Logger();
|
|
171
|
+
const pinoInstance = logger.getPinoInstance();
|
|
172
|
+
|
|
173
|
+
// Use Pino API directly
|
|
174
|
+
pinoInstance.info({ customField: 'value' }, 'Using Pino directly');
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Migration Guide
|
|
178
|
+
|
|
179
|
+
Migrating from winston to the new Logger system:
|
|
180
|
+
|
|
181
|
+
### Before (Winston)
|
|
182
|
+
```typescript
|
|
183
|
+
import logger from './logger';
|
|
184
|
+
logger.info('Message', { meta: 'data' });
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Now (Pino + Class)
|
|
188
|
+
```typescript
|
|
189
|
+
import { systemLogger } from './utils/logger';
|
|
190
|
+
systemLogger.info('Message', { meta: 'data' });
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Most APIs remain compatible, just need to update import paths.
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import pino from 'pino';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
|
|
5
|
+
export interface LoggerConfig {
|
|
6
|
+
level?: string;
|
|
7
|
+
service?: string;
|
|
8
|
+
component?: string;
|
|
9
|
+
enableFileLogging?: boolean;
|
|
10
|
+
logsDir?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface ComponentLoggerMethods {
|
|
14
|
+
debug: (message: string, meta?: any) => void;
|
|
15
|
+
info: (message: string, meta?: any) => void;
|
|
16
|
+
warn: (message: string, meta?: any) => void;
|
|
17
|
+
error: (message: string, error?: any, meta?: any) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 基于Pino的高性能日志系统
|
|
22
|
+
*/
|
|
23
|
+
export class Logger {
|
|
24
|
+
private pinoInstance: pino.Logger;
|
|
25
|
+
private config: Required<LoggerConfig>;
|
|
26
|
+
|
|
27
|
+
constructor(config: LoggerConfig = {}) {
|
|
28
|
+
this.config = {
|
|
29
|
+
level: config.level || process.env.LOG_LEVEL || 'info',
|
|
30
|
+
service: config.service || 'dubhe-graphql-server',
|
|
31
|
+
component: config.component || 'default',
|
|
32
|
+
enableFileLogging: config.enableFileLogging !== false,
|
|
33
|
+
logsDir: config.logsDir || path.join(process.cwd(), 'logs'),
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
this.ensureLogsDirectory();
|
|
37
|
+
this.pinoInstance = this.createPinoInstance();
|
|
38
|
+
this.setupExceptionHandlers();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 确保日志目录存在
|
|
43
|
+
*/
|
|
44
|
+
private ensureLogsDirectory(): void {
|
|
45
|
+
if (
|
|
46
|
+
this.config.enableFileLogging &&
|
|
47
|
+
!fs.existsSync(this.config.logsDir)
|
|
48
|
+
) {
|
|
49
|
+
fs.mkdirSync(this.config.logsDir, { recursive: true });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 创建Pino实例
|
|
55
|
+
*/
|
|
56
|
+
private createPinoInstance(): pino.Logger {
|
|
57
|
+
const pinoOptions: pino.LoggerOptions = {
|
|
58
|
+
level: this.config.level,
|
|
59
|
+
base: {
|
|
60
|
+
service: this.config.service,
|
|
61
|
+
pid: process.pid,
|
|
62
|
+
},
|
|
63
|
+
timestamp: pino.stdTimeFunctions.isoTime,
|
|
64
|
+
formatters: {
|
|
65
|
+
level(label: string) {
|
|
66
|
+
return { level: label };
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
serializers: {
|
|
70
|
+
error: pino.stdSerializers.err,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// 如果启用文件日志,使用multistream
|
|
75
|
+
if (this.config.enableFileLogging) {
|
|
76
|
+
const streams = [
|
|
77
|
+
// Pretty打印到控制台
|
|
78
|
+
{
|
|
79
|
+
stream: pino.transport({
|
|
80
|
+
target: 'pino-pretty',
|
|
81
|
+
options: {
|
|
82
|
+
colorize: true,
|
|
83
|
+
translateTime: 'yyyy-mm-dd HH:MM:ss.l',
|
|
84
|
+
ignore: 'pid,hostname,service,component',
|
|
85
|
+
messageFormat: '[{component}]: {msg}',
|
|
86
|
+
singleLine: true,
|
|
87
|
+
hideObject: false,
|
|
88
|
+
},
|
|
89
|
+
}),
|
|
90
|
+
},
|
|
91
|
+
// JSON格式到文件
|
|
92
|
+
{
|
|
93
|
+
stream: pino.destination({
|
|
94
|
+
dest: path.join(this.config.logsDir, 'combined.log'),
|
|
95
|
+
sync: false,
|
|
96
|
+
}),
|
|
97
|
+
},
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
return pino(pinoOptions, pino.multistream(streams));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// 只输出到控制台的pretty格式
|
|
104
|
+
return pino({
|
|
105
|
+
...pinoOptions,
|
|
106
|
+
transport: {
|
|
107
|
+
target: 'pino-pretty',
|
|
108
|
+
options: {
|
|
109
|
+
colorize: true,
|
|
110
|
+
translateTime: 'yyyy-mm-dd HH:MM:ss.l',
|
|
111
|
+
ignore: 'pid,hostname,service',
|
|
112
|
+
messageFormat: '[{component}]: {msg}',
|
|
113
|
+
singleLine: true,
|
|
114
|
+
hideObject: false,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* 设置异常处理器
|
|
122
|
+
*/
|
|
123
|
+
private setupExceptionHandlers(): void {
|
|
124
|
+
process.on('uncaughtException', error => {
|
|
125
|
+
this.pinoInstance.fatal({ error }, 'Uncaught Exception');
|
|
126
|
+
process.exit(1);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
130
|
+
this.pinoInstance.fatal(
|
|
131
|
+
{ reason, promise },
|
|
132
|
+
'Unhandled Promise Rejection'
|
|
133
|
+
);
|
|
134
|
+
process.exit(1);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* 创建带组件上下文的logger
|
|
140
|
+
*/
|
|
141
|
+
public createComponentLogger(component: string): ComponentLoggerMethods {
|
|
142
|
+
const componentLogger = this.pinoInstance.child({ component });
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
debug: (message: string, meta?: any) =>
|
|
146
|
+
componentLogger.debug(meta || {}, message),
|
|
147
|
+
info: (message: string, meta?: any) =>
|
|
148
|
+
componentLogger.info(meta || {}, message),
|
|
149
|
+
warn: (message: string, meta?: any) =>
|
|
150
|
+
componentLogger.warn(meta || {}, message),
|
|
151
|
+
error: (message: string, error?: any, meta?: any) => {
|
|
152
|
+
const errorData =
|
|
153
|
+
error instanceof Error
|
|
154
|
+
? {
|
|
155
|
+
error: {
|
|
156
|
+
message: error.message,
|
|
157
|
+
stack: error.stack,
|
|
158
|
+
name: error.name,
|
|
159
|
+
},
|
|
160
|
+
...meta,
|
|
161
|
+
}
|
|
162
|
+
: { error, ...meta };
|
|
163
|
+
componentLogger.error(errorData, message);
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* 获取原始Pino实例
|
|
170
|
+
*/
|
|
171
|
+
public getPinoInstance(): pino.Logger {
|
|
172
|
+
return this.pinoInstance;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* 记录性能指标
|
|
177
|
+
*/
|
|
178
|
+
public logPerformance(
|
|
179
|
+
operation: string,
|
|
180
|
+
startTime: number,
|
|
181
|
+
meta?: any
|
|
182
|
+
): void {
|
|
183
|
+
const duration = Date.now() - startTime;
|
|
184
|
+
const perfLogger = this.createComponentLogger('performance');
|
|
185
|
+
perfLogger.info(operation, {
|
|
186
|
+
duration: `${duration}ms`,
|
|
187
|
+
...meta,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* 记录Express HTTP请求
|
|
193
|
+
*/
|
|
194
|
+
public logExpress(
|
|
195
|
+
method: string,
|
|
196
|
+
path: string,
|
|
197
|
+
statusCode: number,
|
|
198
|
+
startTime: number,
|
|
199
|
+
meta?: any
|
|
200
|
+
): void {
|
|
201
|
+
const duration = Date.now() - startTime;
|
|
202
|
+
const httpLogger = this.createComponentLogger('express');
|
|
203
|
+
const message = `${method} ${path} - ${statusCode} (${duration}ms)`;
|
|
204
|
+
|
|
205
|
+
// 根据状态码选择日志级别
|
|
206
|
+
if (statusCode >= 500) {
|
|
207
|
+
httpLogger.error(message, meta);
|
|
208
|
+
} else if (statusCode >= 400) {
|
|
209
|
+
httpLogger.warn(message, meta);
|
|
210
|
+
} else {
|
|
211
|
+
httpLogger.info(message, meta);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* 记录数据库操作
|
|
217
|
+
*/
|
|
218
|
+
public logDatabaseOperation(
|
|
219
|
+
operation: string,
|
|
220
|
+
table?: string,
|
|
221
|
+
meta?: any
|
|
222
|
+
): void {
|
|
223
|
+
const dbLogger = this.createComponentLogger('database');
|
|
224
|
+
dbLogger.info(`Database operation: ${operation}`, {
|
|
225
|
+
table,
|
|
226
|
+
...meta,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* 记录WebSocket事件
|
|
232
|
+
*/
|
|
233
|
+
public logWebSocketEvent(
|
|
234
|
+
event: string,
|
|
235
|
+
clientCount?: number,
|
|
236
|
+
meta?: any
|
|
237
|
+
): void {
|
|
238
|
+
const wsLogger = this.createComponentLogger('websocket');
|
|
239
|
+
wsLogger.info(`WebSocket event: ${event}`, {
|
|
240
|
+
clientCount,
|
|
241
|
+
...meta,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* 记录GraphQL查询
|
|
247
|
+
*/
|
|
248
|
+
public logGraphQLQuery(
|
|
249
|
+
operation: string,
|
|
250
|
+
query?: string,
|
|
251
|
+
variables?: any
|
|
252
|
+
): void {
|
|
253
|
+
const gqlLogger = this.createComponentLogger('graphql');
|
|
254
|
+
gqlLogger.info(`GraphQL ${operation}`, {
|
|
255
|
+
query:
|
|
256
|
+
query?.substring(0, 200) +
|
|
257
|
+
(query && query.length > 200 ? '...' : ''),
|
|
258
|
+
variableCount: variables ? Object.keys(variables).length : 0,
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// 创建默认logger实例
|
|
264
|
+
const defaultLogger = new Logger();
|
|
265
|
+
|
|
266
|
+
// 导出预定义的组件logger(保持向后兼容)
|
|
267
|
+
export const dbLogger = defaultLogger.createComponentLogger('database');
|
|
268
|
+
export const serverLogger = defaultLogger.createComponentLogger('server');
|
|
269
|
+
export const httpLogger = defaultLogger.createComponentLogger('express');
|
|
270
|
+
export const wsLogger = defaultLogger.createComponentLogger('websocket');
|
|
271
|
+
export const gqlLogger = defaultLogger.createComponentLogger('graphql');
|
|
272
|
+
export const subscriptionLogger =
|
|
273
|
+
defaultLogger.createComponentLogger('subscription');
|
|
274
|
+
export const systemLogger = defaultLogger.createComponentLogger('system');
|
|
275
|
+
export const authLogger = defaultLogger.createComponentLogger('auth');
|
|
276
|
+
export const perfLogger = defaultLogger.createComponentLogger('performance');
|
|
277
|
+
|
|
278
|
+
// 导出工具函数(保持向后兼容)
|
|
279
|
+
export const createComponentLogger = (component: string) =>
|
|
280
|
+
defaultLogger.createComponentLogger(component);
|
|
281
|
+
|
|
282
|
+
export const logPerformance = (
|
|
283
|
+
operation: string,
|
|
284
|
+
startTime: number,
|
|
285
|
+
meta?: any
|
|
286
|
+
) => defaultLogger.logPerformance(operation, startTime, meta);
|
|
287
|
+
|
|
288
|
+
export const logExpress = (
|
|
289
|
+
method: string,
|
|
290
|
+
path: string,
|
|
291
|
+
statusCode: number,
|
|
292
|
+
startTime: number,
|
|
293
|
+
meta?: any
|
|
294
|
+
) => defaultLogger.logExpress(method, path, statusCode, startTime, meta);
|
|
295
|
+
|
|
296
|
+
export const logDatabaseOperation = (
|
|
297
|
+
operation: string,
|
|
298
|
+
table?: string,
|
|
299
|
+
meta?: any
|
|
300
|
+
) => defaultLogger.logDatabaseOperation(operation, table, meta);
|
|
301
|
+
|
|
302
|
+
export const logWebSocketEvent = (
|
|
303
|
+
event: string,
|
|
304
|
+
clientCount?: number,
|
|
305
|
+
meta?: any
|
|
306
|
+
) => defaultLogger.logWebSocketEvent(event, clientCount, meta);
|
|
307
|
+
|
|
308
|
+
export const logGraphQLQuery = (
|
|
309
|
+
operation: string,
|
|
310
|
+
query?: string,
|
|
311
|
+
variables?: any
|
|
312
|
+
) => defaultLogger.logGraphQLQuery(operation, query, variables);
|
|
313
|
+
|
|
314
|
+
// 默认导出(保持向后兼容)
|
|
315
|
+
export default defaultLogger.getPinoInstance();
|