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
This commit is contained in:
parent
b76d6b99ee
commit
a767dc3635
14 changed files with 801 additions and 14 deletions
83
utils/logger.ts
Normal file
83
utils/logger.ts
Normal file
|
@ -0,0 +1,83 @@
|
|||
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;
|
Loading…
Add table
Add a link
Reference in a new issue