feat: WWJCloud 企业级全栈框架 v0.3.5 完整更新

🚀 核心更新:
-  完善 NestJS 企业级架构设计
-  优化配置中心和基础设施层
-  增强第三方服务集成能力
-  完善多租户架构支持
- 🎯 对标 Java Spring Boot 和 PHP ThinkPHP

📦 新增文件:
- wwjcloud-nest 完整框架结构
- Docker 容器化配置
- 管理后台界面
- 数据库迁移脚本

🔑 Key: ebb38b43ec39f355f071294fd1cf9c42
This commit is contained in:
wanwu
2025-10-13 01:27:37 +08:00
parent 10bcd7f624
commit 1ed0085d15
1697 changed files with 260750 additions and 127 deletions

View File

@@ -0,0 +1,542 @@
import { Injectable, Inject, Logger } from '@nestjs/common';
import type {
LoggingInterface,
StructuredLoggingInterface,
StructuredLogData,
RequestLogData,
ResponseLogData,
DatabaseQueryLogData,
CacheOperationLogData,
ExternalApiCallLogData,
BusinessEventLogData,
UserLogData,
ErrorLogData,
LoggingOptions,
} from './logging.interface';
import { LogLevel } from './logging.interface';
/**
* 日志服务
* 基于 NestJS 官方示例实现
* 参考: https://docs.nestjs.cn/fundamentals/dependency-injection
* 对应 Java: 日志服务
*/
@Injectable()
export class LoggingService
implements LoggingInterface, StructuredLoggingInterface
{
private readonly logger = new Logger(LoggingService.name);
private currentLevel: LogLevel = LogLevel.INFO;
constructor(
@Inject('LOGGING_PROVIDER')
private readonly loggingProvider: LoggingInterface,
@Inject('STRUCTURED_LOGGING_PROVIDER')
private readonly structuredLoggingProvider: StructuredLoggingInterface,
) {}
// ==================== 基础日志接口 ====================
/**
* 记录调试日志
*/
debug(message: string, context?: string, meta?: Record<string, any>): void {
try {
this.loggingProvider.debug(message, context, meta);
} catch (error) {
this.logger.error(`Failed to log debug message: ${message}`, error);
}
}
/**
* 记录信息日志
*/
info(message: string, context?: string, meta?: Record<string, any>): void {
try {
this.loggingProvider.info(message, context, meta);
} catch (error) {
this.logger.error(`Failed to log info message: ${message}`, error);
}
}
/**
* 记录警告日志
*/
warn(message: string, context?: string, meta?: Record<string, any>): void {
try {
this.loggingProvider.warn(message, context, meta);
} catch (error) {
this.logger.error(`Failed to log warn message: ${message}`, error);
}
}
/**
* 记录错误日志
*/
error(message: string, context?: string, meta?: Record<string, any>): void {
try {
this.loggingProvider.error(message, context, meta);
} catch (error) {
this.logger.error(`Failed to log error message: ${message}`, error);
}
}
/**
* 记录致命错误日志
*/
fatal(message: string, context?: string, meta?: Record<string, any>): void {
try {
this.loggingProvider.fatal(message, context, meta);
} catch (error) {
this.logger.error(`Failed to log fatal message: ${message}`, error);
}
}
/**
* 记录日志
*/
log(
level: LogLevel,
message: string,
context?: string,
meta?: Record<string, any>,
): void {
try {
this.loggingProvider.log(level, message, context, meta);
} catch (error) {
this.logger.error(`Failed to log message: ${message}`, error);
}
}
/**
* 设置日志级别
*/
setLevel(level: LogLevel): void {
try {
this.currentLevel = level;
this.loggingProvider.setLevel(level);
} catch (error) {
this.logger.error(`Failed to set log level: ${level}`, error);
}
}
/**
* 获取当前日志级别
*/
getLevel(): LogLevel {
return this.currentLevel;
}
/**
* 创建子日志器
*/
child(context: string): LoggingInterface {
try {
return this.loggingProvider.child(context);
} catch (error) {
this.logger.error(`Failed to create child logger: ${context}`, error);
return this;
}
}
// ==================== 结构化日志接口 ====================
/**
* 记录结构化日志
*/
logStructured(
level: LogLevel,
message: string,
structuredData: StructuredLogData,
): void {
try {
this.structuredLoggingProvider.logStructured(
level,
message,
structuredData,
);
} catch (error) {
this.logger.error(`Failed to log structured message: ${message}`, error);
}
}
/**
* 记录请求日志
*/
logRequest(
request: RequestLogData,
response: ResponseLogData,
duration: number,
): void {
try {
this.structuredLoggingProvider.logRequest(request, response, duration);
} catch (error) {
this.logger.error('Failed to log request', error);
}
}
/**
* 记录数据库查询日志
*/
logDatabaseQuery(
query: DatabaseQueryLogData,
duration: number,
result?: any,
): void {
try {
this.structuredLoggingProvider.logDatabaseQuery(query, duration, result);
} catch (error) {
this.logger.error('Failed to log database query', error);
}
}
/**
* 记录缓存操作日志
*/
logCacheOperation(
operation: CacheOperationLogData,
hit: boolean,
duration: number,
): void {
try {
this.structuredLoggingProvider.logCacheOperation(
operation,
hit,
duration,
);
} catch (error) {
this.logger.error('Failed to log cache operation', error);
}
}
/**
* 记录外部API调用日志
*/
logExternalApiCall(
apiCall: ExternalApiCallLogData,
response: any,
duration: number,
): void {
try {
this.structuredLoggingProvider.logExternalApiCall(
apiCall,
response,
duration,
);
} catch (error) {
this.logger.error('Failed to log external API call', error);
}
}
/**
* 记录业务事件日志
*/
logBusinessEvent(
event: BusinessEventLogData,
user?: UserLogData,
meta?: Record<string, any>,
): void {
try {
this.structuredLoggingProvider.logBusinessEvent(event, user, meta);
} catch (error) {
this.logger.error('Failed to log business event', error);
}
}
// ==================== 装饰器支持 ====================
/**
* 日志装饰器实现
*/
async logMethod<T>(
options: LoggingOptions,
fn: () => T | Promise<T>,
args: any[] = [],
): Promise<T> {
const {
level = LogLevel.INFO,
context = 'Method',
logArgs = false,
logResult = false,
logDuration = true,
logError = true,
enabled = true,
message,
meta = {},
} = options;
if (!enabled) {
return await fn();
}
const startTime = Date.now();
const logMessage = message || `${context} execution`;
const logMeta = { ...meta };
try {
// 记录方法开始
if (logArgs) {
logMeta.args = args;
}
this.log(level, `${logMessage} started`, context, logMeta);
// 执行方法
const result = await fn();
// 记录方法完成
const duration = Date.now() - startTime;
const successMeta = { ...logMeta };
if (logResult) {
successMeta.result = result;
}
if (logDuration) {
successMeta.duration = duration;
}
this.log(level, `${logMessage} completed`, context, successMeta);
return result;
} catch (error) {
const duration = Date.now() - startTime;
const errorMeta = { ...logMeta };
if (logDuration) {
errorMeta.duration = duration;
}
if (logError) {
errorMeta.error = this.serializeError(error);
}
this.error(`${logMessage} failed`, context, errorMeta);
throw error;
}
}
// ==================== 工具方法 ====================
/**
* 序列化错误
*/
private serializeError(error: any): ErrorLogData {
if (error instanceof Error) {
return {
name: error.name,
message: error.message,
stack: error.stack,
code: (error as any).code,
cause: (error as any).cause,
context: (error as any).context,
};
}
return {
name: 'UnknownError',
message: String(error),
context: { originalError: error },
};
}
/**
* 记录HTTP请求
*/
logHttpRequest(
method: string,
url: string,
statusCode: number,
duration: number,
userAgent?: string,
ip?: string,
userId?: string,
): void {
const request: RequestLogData = {
method,
url,
headers: {},
ip,
userAgent,
userId,
};
const response: ResponseLogData = {
statusCode,
headers: {},
};
this.logRequest(request, response, duration);
}
/**
* 记录数据库操作
*/
logDatabaseOperation(
operation: string,
table: string,
query: string,
duration: number,
params?: any[],
result?: any,
): void {
const queryData: DatabaseQueryLogData = {
operation,
table,
query,
params,
};
this.logDatabaseQuery(queryData, duration, result);
}
/**
* 记录缓存操作
*/
logCacheOperationSimple(
operation: string,
key: string,
hit: boolean,
duration: number,
ttl?: number,
size?: number,
): void {
const operationData: CacheOperationLogData = {
operation,
key,
ttl,
size,
};
this.logCacheOperation(operationData, hit, duration);
}
/**
* 记录外部API调用
*/
logExternalApiCallSimple(
service: string,
endpoint: string,
method: string,
statusCode: number,
duration: number,
headers?: Record<string, string>,
body?: any,
): void {
const apiCall: ExternalApiCallLogData = {
service,
endpoint,
method,
headers: headers || {},
body,
};
const response = { statusCode };
this.logExternalApiCall(apiCall, response, duration);
}
/**
* 记录业务事件
*/
logBusinessEventSimple(
event: string,
action: string,
resource: string,
resourceId?: string,
result?: 'success' | 'failure' | 'partial',
data?: Record<string, any>,
userId?: string,
): void {
const eventData: BusinessEventLogData = {
event,
action,
resource,
resourceId,
result,
data,
};
const userData: UserLogData | undefined = userId
? { id: userId }
: undefined;
this.logBusinessEvent(eventData, userData);
}
/**
* 记录性能指标
*/
logPerformance(
operation: string,
duration: number,
context?: string,
meta?: Record<string, any>,
): void {
const performanceMeta = {
operation,
duration,
...meta,
};
if (duration > 1000) {
this.warn(`Slow operation: ${operation}`, context, performanceMeta);
} else if (duration > 500) {
this.info(`Operation: ${operation}`, context, performanceMeta);
} else {
this.debug(`Operation: ${operation}`, context, performanceMeta);
}
}
/**
* 记录安全事件
*/
logSecurityEvent(
event: string,
severity: 'low' | 'medium' | 'high' | 'critical',
context?: string,
meta?: Record<string, any>,
): void {
const securityMeta = {
event,
severity,
...meta,
};
switch (severity) {
case 'critical':
this.fatal(`Security event: ${event}`, context, securityMeta);
break;
case 'high':
this.error(`Security event: ${event}`, context, securityMeta);
break;
case 'medium':
this.warn(`Security event: ${event}`, context, securityMeta);
break;
case 'low':
this.info(`Security event: ${event}`, context, securityMeta);
break;
}
}
/**
* 记录审计日志
*/
logAudit(
action: string,
resource: string,
resourceId?: string,
userId?: string,
result?: 'success' | 'failure',
meta?: Record<string, any>,
): void {
const auditMeta = {
action,
resource,
resourceId,
userId,
result,
...meta,
};
this.info(`Audit: ${action} on ${resource}`, 'audit', auditMeta);
}
}