wip: removing console log

This commit is contained in:
Lin, Hung-Shin committed 2023-11-20 14:59:14 +08:00
1 parent 515aefcadc
commit 82d1004ecf
16 files changed
+57 -34

No files matched your search

+1 -1
View File
@@ -17,7 +17,7 @@ module.exports = {
sourceType: 'module', sourceType: 'module',
}, },
rules: { rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-console': 'error',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'import/extensions': 'off', 'import/extensions': 'off',
camelcase: ['error', { properties: 'never', ignoreDestructuring: true }], camelcase: ['error', { properties: 'never', ignoreDestructuring: true }],
+1
View File
@@ -33,6 +33,7 @@ services:
- ./server/swagger.yaml:/app/server/swagger.yaml - ./server/swagger.yaml:/app/server/swagger.yaml
- ./packages:/app/packages - ./packages:/app/packages
- ./quests:/app/quests - ./quests:/app/quests
- ./logs:/app/logs
environment: environment:
- BASE_URL=http://localhost:5173 - BASE_URL=http://localhost:5173
- MONGO_URL=mongodb://db:27017/odyssey-test - MONGO_URL=mongodb://db:27017/odyssey-test
+2 -1
View File
@@ -2,6 +2,7 @@ import { matchedData } from 'express-validator'
import { genJWT } from '../../utils/auth.js' import { genJWT } from '../../utils/auth.js'
import { createUser } from '../../models/userManager.js' import { createUser } from '../../models/userManager.js'
import { asyncHandler } from '../../middleware/error.js' import { asyncHandler } from '../../middleware/error.js'
import logger from '../../utils/logger.js'
export const issueToken = asyncHandler(async (req, res) => { export const issueToken = asyncHandler(async (req, res) => {
const { user } = req const { user } = req
@@ -31,7 +32,7 @@ export const register = asyncHandler(async (req, res, next) => {
export function logout(req, res) { export function logout(req, res) {
req.logout((err) => { req.logout((err) => {
if (err) { if (err) {
console.error(err) logger.error(err)
res.status(500).json({ res.status(500).json({
message: 'error logging out', message: 'error logging out',
}) })
+4 -3
View File
@@ -4,6 +4,7 @@ import { Session } from '@linux-odyssey/models'
import { getAndStartContainer, attachContainer } from '../containers/docker.js' import { getAndStartContainer, attachContainer } from '../containers/docker.js'
import SessionMiddleware from '../middleware/session.js' import SessionMiddleware from '../middleware/session.js'
import { genJWT } from '../utils/auth.js' import { genJWT } from '../utils/auth.js'
import logger from '../utils/logger.js'
const sessions = new Map() const sessions = new Map()
@@ -37,7 +38,7 @@ async function connectContainer(socket, next) {
// console.log(socket.handshake) // console.log(socket.handshake)
const { sessionId } = socket.handshake.query const { sessionId } = socket.handshake.query
if (!(sessionId && validator.isMongoId(sessionId))) { if (!(sessionId && validator.isMongoId(sessionId))) {
console.warn('Invalid Session ID.', sessionId) logger.warn('Invalid Session ID.', user.username, sessionId)
next(new Error('Invalid Session ID.')) next(new Error('Invalid Session ID.'))
return return
} }
@@ -71,7 +72,7 @@ function onConnect(socket) {
socket.emit('terminal', chunk.toString()) socket.emit('terminal', chunk.toString())
}) })
socket.on('message', console.log) socket.on('message', logger.info)
socket.on('terminal', function incoming(message) { socket.on('terminal', function incoming(message) {
stream.socket.write(message) stream.socket.write(message)
@@ -98,6 +99,6 @@ export default (server) => {
io.on('connection', onConnect) io.on('connection', onConnect)
io.on('connect_error', (err) => { io.on('connect_error', (err) => {
console.error(err) logger.error('Socket connect error: ', err)
}) })
} }
+2 -1
View File
@@ -4,6 +4,7 @@ import passwordStrategy from './passwordStrategy.js'
import jwtStrategy from './jwtStrategy.js' import jwtStrategy from './jwtStrategy.js'
import googleStrategy from './googleStrategy.js' import googleStrategy from './googleStrategy.js'
import githubStrategy from './githubStrategy.js' import githubStrategy from './githubStrategy.js'
import logger from '../utils/logger.js'
passport.use(passwordStrategy) passport.use(passwordStrategy)
passport.use(jwtStrategy) passport.use(jwtStrategy)
@@ -14,7 +15,7 @@ const enabledMethods = {
github: githubStrategy !== null, github: githubStrategy !== null,
} }
console.log('Enabled login methods', enabledMethods) logger.info('Enabled login methods', enabledMethods)
if (enabledMethods.google) { if (enabledMethods.google) {
passport.use(googleStrategy) passport.use(googleStrategy)
+6 -5
View File
@@ -1,12 +1,13 @@
import { getQuestDockerfiles } from '../utils/quest.js' import { getQuestDockerfiles } from '../utils/quest.js'
import { buildQuestImage } from '../containers/docker.js' import { buildQuestImage } from '../containers/docker.js'
import logger from '../utils/logger.js'
async function buildImages() { async function buildImages() {
const quests = await getQuestDockerfiles() const quests = await getQuestDockerfiles()
console.log(`Building ${quests.length} images`) logger.info(`Building ${quests.length} images`)
return Promise.all( return Promise.all(
quests.map(({ id, questPath }) => { quests.map(({ id, questPath }) => {
console.log(`Building image for ${id}`) logger.info(`Building image for ${id}`)
return buildQuestImage(questPath, id) return buildQuestImage(questPath, id)
}) })
) )
@@ -14,11 +15,11 @@ async function buildImages() {
buildImages() buildImages()
.then((result) => { .then((result) => {
console.log(result) logger.info(result)
console.log('Done!') logger.info('Done!')
process.exit(0) process.exit(0)
}) })
.catch((err) => { .catch((err) => {
console.error(err) logger.error(err)
process.exit(1) process.exit(1)
}) })
+2 -1
View File
@@ -1,6 +1,7 @@
import connectDB from '@linux-odyssey/models' import connectDB from '@linux-odyssey/models'
import { removeExpired } from '../containers/expiryChecker.js' import { removeExpired } from '../containers/expiryChecker.js'
import config from '../config.js' import config from '../config.js'
import logger from '../utils/logger.js'
connectDB(config.db) connectDB(config.db)
.then(removeExpired) .then(removeExpired)
@@ -8,6 +9,6 @@ connectDB(config.db)
process.exit(0) process.exit(0)
}) })
.catch((err) => { .catch((err) => {
console.error(err) logger.error(err)
process.exit(1) process.exit(1)
}) })
+1
View File
@@ -1,3 +1,4 @@
/* eslint-disable no-console */
import { genSecret } from '../utils/env.js' import { genSecret } from '../utils/env.js'
function setup() { function setup() {
+4
View File
@@ -46,6 +46,10 @@ const config = {
imagePrefix: get('DOCKER_PREFIX', 'linuxodyssey/quest-'), imagePrefix: get('DOCKER_PREFIX', 'linuxodyssey/quest-'),
mountQuest: get('MOUNT_QUEST', ''), mountQuest: get('MOUNT_QUEST', ''),
}, },
log: {
path: get('LOG_PATH', '../logs'),
},
} }
config.baseUrl = get('BASE_URL', `http://${config.host}:${config.port}`) config.baseUrl = get('BASE_URL', `http://${config.host}:${config.port}`)
+7 -6
View File
@@ -1,5 +1,6 @@
import Docker from 'dockerode' import Docker from 'dockerode'
import config, { getQuestImage } from '../config.js' import config, { getQuestImage } from '../config.js'
import logger from '../utils/logger.js'
const engine = new Docker() const engine = new Docker()
@@ -33,7 +34,7 @@ export function createContainer(name, questId) {
} }
export async function getAndStartContainer(id) { export async function getAndStartContainer(id) {
console.log(`Getting container: ${id}`) logger.debug(`Getting container: ${id}`)
const container = engine.getContainer(id) const container = engine.getContainer(id)
if (!container) { if (!container) {
throw new Error(`Container ${id} not found`) throw new Error(`Container ${id} not found`)
@@ -74,7 +75,7 @@ export async function deleteContainer(id) {
try { try {
await container.stop() await container.stop()
} catch (error) { } catch (error) {
console.log(error) logger.warn(error)
} }
await container.remove() await container.remove()
} }
@@ -99,21 +100,21 @@ export function buildQuestImage(questPath, questId) {
// Process the data (this could be Docker build output) // Process the data (this could be Docker build output)
const { stream, error } = JSON.parse(data.toString()) const { stream, error } = JSON.parse(data.toString())
if (stream) { if (stream) {
console.log(stream) logger.info(stream)
} }
if (error) { if (error) {
console.error(error) logger.error(error)
reject(error) reject(error)
} }
}) })
response.on('end', () => { response.on('end', () => {
console.log(`Build completed for ${questId}`) logger.info(`Build completed for ${questId}`)
resolve(questId) resolve(questId)
}) })
response.on('error', (error) => { response.on('error', (error) => {
console.error(`Build failed for ${questId}:`, error) logger.error(`Build failed for ${questId}:`, error)
reject(error) reject(error)
}) })
} }
+3 -4
View File
@@ -2,19 +2,19 @@ import schedule from 'node-schedule'
import { Session } from '@linux-odyssey/models' import { Session } from '@linux-odyssey/models'
import config from '../config.js' import config from '../config.js'
import { deleteContainer } from './docker.js' import { deleteContainer } from './docker.js'
import logger from '../utils/logger.js'
export async function removeExpired() { export async function removeExpired() {
// Find all sessions that are containerId is not null and lastActivityAt is // Find all sessions that are containerId is not null and lastActivityAt is
// less than the current time minus the expiry time // less than the current time minus the expiry time
try { try {
console.log('Checking for expired sessions')
const sessions = await Session.find({ const sessions = await Session.find({
containerId: { $ne: null }, containerId: { $ne: null },
lastActivityAt: { $lt: new Date(Date.now() - config.containerExpiry) }, lastActivityAt: { $lt: new Date(Date.now() - config.containerExpiry) },
}) })
await Promise.all( await Promise.all(
sessions.map(async (session) => { sessions.map(async (session) => {
console.log('Expiring session: ', session._id, session.containerId) logger.info('Expiring session: ', session._id, session.containerId)
try { try {
await deleteContainer(session.containerId) await deleteContainer(session.containerId)
} catch (err) { } catch (err) {
@@ -29,9 +29,8 @@ export async function removeExpired() {
await session.save() await session.save()
}) })
) )
console.log('Done checking for expired sessions')
} catch (err) { } catch (err) {
console.error(err) logger.error(err)
} }
} }
+2 -1
View File
@@ -4,6 +4,7 @@ import { Quest } from '@linux-odyssey/models'
import { pushToSession } from '../api/socket.js' import { pushToSession } from '../api/socket.js'
import SessionHandler from './sessionHandler.js' import SessionHandler from './sessionHandler.js'
import { checkFile } from '../containers/cli.js' import { checkFile } from '../containers/cli.js'
import logger from '../utils/logger.js'
// 檢查 pattern 是否符合 input // 檢查 pattern 是否符合 input
const checkMatch = (pattern, input) => { const checkMatch = (pattern, input) => {
@@ -101,7 +102,7 @@ export default class CommandHandler extends SessionHandler {
this.quest = await Quest.findById(this.session.quest) this.quest = await Quest.findById(this.session.quest)
const stages = this.getStages() const stages = this.getStages()
if (stages.length === 0) { if (stages.length === 0) {
console.error('stage not found', this.session.tasks) logger.warn('stage not found', this.session.tasks)
return {} return {}
} }
+5 -5
View File
@@ -28,9 +28,9 @@ async function main() {
try { try {
await connectDB(config.db) await connectDB(config.db)
console.log('Connected to MongoDB') logger.info('Connected to MongoDB')
} catch (err) { } catch (err) {
console.error(err) logger.error(err)
process.exit(1) process.exit(1)
} }
@@ -53,7 +53,7 @@ async function main() {
'uniquelocal', 'uniquelocal',
...config.trustedProxies, ...config.trustedProxies,
]) ])
console.log('Trusted proxies:', config.trustedProxies) logger.info('Trusted proxies:', config.trustedProxies)
app.use(globalRateLimit) app.use(globalRateLimit)
app.use(sessionMiddleware) app.use(sessionMiddleware)
app.use(passport.session()) app.use(passport.session())
@@ -74,8 +74,8 @@ async function main() {
app.use(errorHandler) app.use(errorHandler)
server.listen(config.port, config.host, () => { server.listen(config.port, config.host, () => {
console.log(`Server listening at ${config.baseUrl}`) logger.info(`Server listening at ${config.baseUrl}`)
}) })
} }
main().catch((err) => console.log(err)) main().catch((err) => logger.error(err))
+3 -1
View File
@@ -1,3 +1,5 @@
import logger from '../utils/logger.js'
export function asyncHandler(fn) { export function asyncHandler(fn) {
return (req, res, next) => { return (req, res, next) => {
fn(req, res, next).catch(next) fn(req, res, next).catch(next)
@@ -6,6 +8,6 @@ export function asyncHandler(fn) {
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
export default function errorHandler(err, req, res, next) { export default function errorHandler(err, req, res, next) {
console.error(err.stack) // Log error stack trace to the console logger.error(err) // Log error stack trace to the console
res.status(500).send({ message: 'Something broke!' }) // Send error response res.status(500).send({ message: 'Something broke!' }) // Send error response
} }
+3 -2
View File
@@ -1,6 +1,7 @@
import { Session, Quest, UserProfile } from '@linux-odyssey/models' import { Session, Quest, UserProfile } from '@linux-odyssey/models'
import { createContainer, deleteContainer } from '../containers/docker.js' import { createContainer, deleteContainer } from '../containers/docker.js'
import SessionHandler from '../game/sessionHandler.js' import SessionHandler from '../game/sessionHandler.js'
import logger from '../utils/logger.js'
async function deactivateSessions(user, quest) { async function deactivateSessions(user, quest) {
const sessions = await Session.find({ const sessions = await Session.find({
@@ -11,7 +12,7 @@ async function deactivateSessions(user, quest) {
return Promise.all( return Promise.all(
sessions.map((session) => { sessions.map((session) => {
return deleteContainer(session.containerId) return deleteContainer(session.containerId)
.catch(console.error) .catch(logger.error)
.finally(() => { .finally(() => {
session.status = 'inactive' session.status = 'inactive'
session.containerId = null session.containerId = null
@@ -29,7 +30,7 @@ export async function createNewSession(user, questId) {
// deactivate all active sessions // deactivate all active sessions
deactivateSessions(user._id, quest._id).catch((err) => { deactivateSessions(user._id, quest._id).catch((err) => {
console.error(err) logger.error(err)
}) })
const container = await createContainer( const container = await createContainer(
+11 -3
View File
@@ -1,16 +1,24 @@
import winston from 'winston' import winston from 'winston'
import config from '../config.js'
const logger = winston.createLogger({ const logger = winston.createLogger({
level: 'info', level: 'info',
format: winston.format.json(), format: winston.format.json(),
defaultMeta: { service: 'user-service' }, defaultMeta: { service: 'backend', timestamp: new Date().toISOString() },
transports: [ transports: [
// //
// - Write all logs with importance level of `error` or less to `error.log` // - Write all logs with importance level of `error` or less to `error.log`
// - Write all logs with importance level of `info` or less to `combined.log` // - Write all logs with importance level of `info` or less to `combined.log`
// //
new winston.transports.File({ filename: 'error.log', level: 'error' }), new winston.transports.File({
new winston.transports.File({ filename: 'combined.log' }), dirname: config.log.path,
filename: 'error.log',
level: 'error',
}),
new winston.transports.File({
dirname: config.log.path,
filename: 'combined.log',
}),
], ],
}) })