m2-inno-bedpressure/utils/logger.ts
Siwat Sirichai a767dc3635 feat: restructure backend with Elysia framework and add MQTT adapter
- Updated .gitignore to exclude generated files and database
- Modified package.json to change dev script and add new dependencies
- Removed src/index.ts and created app.ts for Elysia server initialization
- Added environment variable configuration in config/env.ts
- Implemented MQTT adapter in adapter/mqtt.ts for message handling
- Created Prisma client in prisma/client.ts and defined schema in prisma/schema.prisma
- Added seeding script in prisma/seed.ts for measurement points
- Established logging utility in utils/logger.ts for structured logging
- Created bed router in routes/bed.ts for handling bed-related routes
2025-06-21 18:24:54 +07:00

83 lines
2.3 KiB
TypeScript

import { createLogger, format, transports, Logger, LeveledLogMethod } from 'winston';
import * as fs from 'fs';
import * as path from 'path';
// Define log directory
const LOG_DIR = path.join(process.cwd(), 'logs');
// Ensure log directory exists
if (!fs.existsSync(LOG_DIR)) {
fs.mkdirSync(LOG_DIR, { recursive: true });
}
// Interface for topic logger options
interface TopicLoggerOptions {
topic: string;
level?: string;
}
// Create the base logger
const createBaseLogger = (level: string = 'debug') => {
return createLogger({
level,
format: format.combine(
format.timestamp(),
format.json()
),
transports: [
new transports.Console({
format: format.combine(
format.colorize(),
format.printf(({ timestamp, level, message, topic, ...meta }) => {
const topicStr = topic ? `[${topic}] ` : '';
return `${timestamp} ${level}: ${topicStr}${message} ${Object.keys(meta).length ? JSON.stringify(meta) : ''}`;
})
)
}),
new transports.File({
filename: path.join(LOG_DIR, 'combined.log')
})
]
});
};
// Main logger instance
const logger = createBaseLogger();
// Create a topic-specific logger
const createTopicLogger = (options: TopicLoggerOptions): Logger => {
const topicLogger = createBaseLogger(options.level);
// Create a wrapper that adds topic to all log messages
const wrappedLogger = {
...topicLogger,
};
// Wrap each log level method to include topic
(['error', 'warn', 'info', 'http', 'verbose', 'debug', 'silly'] as const).forEach((level) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
wrappedLogger[level] = ((...args: any[]) => {
// Handle different call patterns
if (typeof args[0] === 'string') {
const message = args[0];
const meta = args[1] || {};
return topicLogger[level]({
message,
topic: options.topic,
...meta
});
} else {
// If first argument is an object, add topic to it
return topicLogger[level]({
...args[0],
topic: options.topic
});
}
}) as LeveledLogMethod;
});
return wrappedLogger as Logger;
};
export { logger, createTopicLogger };
export default logger;