chore: add config for logging and update dockerfile

This commit is contained in:
Darkraise
2026-02-01 11:40:07 +07:00
parent 9e9a116f7f
commit f76f731efe
7 changed files with 62 additions and 18 deletions
+4 -1
View File
@@ -44,7 +44,10 @@
"mcp__ide__getDiagnostics",
"Bash(done)",
"Bash(npm run lint:*)",
"Bash(wc:*)"
"Bash(wc:*)",
"Bash(ls:*)",
"Bash(docker build:*)",
"Bash(find:*)"
]
}
}
+5 -4
View File
@@ -20,9 +20,10 @@ RUN npm ci --workspace=backend --include-workspace-root --prefer-offline --no-au
# Copy backend source code
COPY backend ./backend/
# Build TypeScript (run from backend directory)
# Build TypeScript (run from backend directory) and prune dev dependencies
WORKDIR /app/backend
RUN npm run build
RUN npm run build && \
npm prune --omit=dev --workspace=backend --include-workspace-root
# =============================================================================
# Stage 2: Production - Optimized runtime
@@ -46,8 +47,8 @@ COPY --from=builder /app/package.json /app/package-lock.json ./
# Copy backend package files
COPY --from=builder /app/backend/package.json ./backend/
# Install production dependencies only for backend workspace
RUN npm ci --workspace=backend --include-workspace-root --omit=dev --prefer-offline --no-audit
# Copy production node_modules from builder to leverage cached install
COPY --from=builder /app/node_modules ./node_modules
# Copy built application
COPY --from=builder /app/backend/dist ./backend/dist
+34 -8
View File
@@ -1,15 +1,41 @@
import { Router, Request, Response } from 'express';
import { promises as fs } from 'fs';
import fsSync from 'fs';
import path from 'path';
import winston from 'winston';
import { authenticate } from '../middleware/auth';
import { requirePermission } from '../middleware/rbac';
import { logger } from '../utils/logger';
import { config } from '../config';
const router = Router();
const LOG_DIR = path.join(__dirname, '../../logs');
const LOG_DIR = config.logFile ? path.dirname(config.logFile) : path.join(__dirname, '../../logs');
const ERROR_LOG_FILE = path.join(LOG_DIR, 'client-errors.log');
// Ensure logs directory exists for file transport at startup
if (!fsSync.existsSync(LOG_DIR)) {
fsSync.mkdirSync(LOG_DIR, { recursive: true });
}
const clientErrorLogger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
winston.format.errors({ stack: true }),
winston.format.json()
),
defaultMeta: { service: 'flashpoint-web-client-errors' },
transports: [
new winston.transports.File({
filename: ERROR_LOG_FILE,
maxsize: 10485760, // 10MB
maxFiles: 5,
tailable: true
})
]
});
interface ErrorReport {
type: 'client_error' | 'network_error' | 'api_error' | 'route_error';
message: string;
@@ -18,9 +44,11 @@ interface ErrorReport {
timestamp: string;
userAgent: string;
userId?: number;
context?: Record<string, any>;
context?: Record<string, unknown>;
}
type AuthenticatedRequest = Request & { user?: { id: number } };
/**
* Ensure logs directory exists
*/
@@ -37,10 +65,7 @@ async function ensureLogDir(): Promise<void> {
*/
async function logError(report: ErrorReport): Promise<void> {
try {
await ensureLogDir();
const logLine = JSON.stringify(report) + '\n';
await fs.appendFile(ERROR_LOG_FILE, logLine, 'utf8');
clientErrorLogger.info('client_error', report);
} catch (error) {
logger.error('Failed to log client error:', error);
}
@@ -106,8 +131,9 @@ router.post('/report', async (req: Request, res: Response) => {
}
// Add user ID if authenticated
if ((req as any).user) {
report.userId = (req as any).user.id;
const authReq = req as AuthenticatedRequest;
if (authReq.user) {
report.userId = authReq.user.id;
}
// Add timestamp if not provided
+6
View File
@@ -37,6 +37,9 @@ services:
- ${FLASHPOINT_HOST_PATH:?FLASHPOINT_HOST_PATH environment variable must be set}:/data/flashpoint:ro
# User database (persistent)
- backend-db:/app/data
# Application logs (persistent)
# Set BACKEND_LOGS_PATH to bind-mount a host directory
- ${BACKEND_LOGS_PATH:-backend-logs}:/app/logs
environment:
- NODE_ENV=${NODE_ENV:-production}
- TZ=${TZ:-UTC}
@@ -126,6 +129,9 @@ volumes:
# Persistent volume for user database
backend-db:
driver: local
# Persistent volume for backend logs
backend-logs:
driver: local
# =============================================================================
# Quick Start with Pre-built Images
+6
View File
@@ -11,6 +11,9 @@ services:
- ${FLASHPOINT_HOST_PATH:?FLASHPOINT_HOST_PATH environment variable must be set}:/data/flashpoint:ro
# User database (persistent)
- backend-db:/app/data
# Application logs (persistent)
# Set BACKEND_LOGS_PATH to bind-mount a host directory
- ${BACKEND_LOGS_PATH:-backend-logs}:/app/logs
environment:
- NODE_ENV=${NODE_ENV:-production}
- TZ=${TZ:-UTC}
@@ -158,6 +161,9 @@ volumes:
# Persistent volume for user database
backend-db:
driver: local
# Persistent volume for backend logs
backend-logs:
driver: local
# =============================================================================
# Flashpoint Web App - Production Docker Compose Configuration
+2 -1
View File
@@ -17,7 +17,8 @@ services:
# User database (persistent)
- backend-db:/app/data
# Application logs (persistent)
- backend-logs:/app/logs
# Set BACKEND_LOGS_PATH to bind-mount a host directory
- ${BACKEND_LOGS_PATH:-backend-logs}:/app/logs
environment:
- NODE_ENV=${NODE_ENV:-production}
- TZ=${TZ:-UTC}
+5 -4
View File
@@ -23,9 +23,10 @@ RUN npm ci --workspace=game-service --include-workspace-root --prefer-offline --
# Copy game-service source code
COPY game-service ./game-service/
# Build TypeScript (run from game-service directory)
# Build TypeScript (run from game-service directory) and prune dev dependencies
WORKDIR /app/game-service
RUN npm run build
RUN npm run build && \
npm prune --omit=dev --workspace=game-service --include-workspace-root
# =============================================================================
# Stage 2: Production - Optimized runtime
@@ -49,8 +50,8 @@ COPY --from=builder /app/package.json /app/package-lock.json ./
# Copy game-service package files
COPY --from=builder /app/game-service/package.json ./game-service/
# Install production dependencies only for game-service workspace
RUN npm ci --workspace=game-service --include-workspace-root --omit=dev --prefer-offline --no-audit
# Copy production node_modules from builder to leverage cached install
COPY --from=builder /app/node_modules ./node_modules
# Copy built application
COPY --from=builder /app/game-service/dist ./game-service/dist