diff --git a/runtimes/nodejs/Dockerfile b/runtimes/nodejs/Dockerfile index d09d33a4f0..8bd4a495f6 100644 --- a/runtimes/nodejs/Dockerfile +++ b/runtimes/nodejs/Dockerfile @@ -9,6 +9,10 @@ EXPOSE 9000 WORKDIR /app ENV LOG_LEVEL=debug + +# enable chalk colors +ENV FORCE_COLOR=1 + COPY . /app # COPY --chown=node:node . /app RUN mkdir /app/data || true diff --git a/runtimes/nodejs/src/config.ts b/runtimes/nodejs/src/config.ts index 7ace9516ec..8c22c0f234 100644 --- a/runtimes/nodejs/src/config.ts +++ b/runtimes/nodejs/src/config.ts @@ -31,16 +31,10 @@ export default class Config { } /** - * the logger level : 'fatal', 'error', 'warning', 'info', 'debug', 'trace' + * the logger level : 'debug', 'info', 'warn', 'error' */ - static get LOG_LEVEL(): - | 'fatal' - | 'error' - | 'warning' - | 'info' - | 'debug' - | 'trace' { - return (process.env['LOG_LEVEL'] as any) ?? (this.isProd ? 'info' : 'debug') + static get LOG_LEVEL(): 'debug' | 'info' | 'warn' | 'error' { + return (process.env['LOG_LEVEL'] as any) || 'debug' } /** diff --git a/runtimes/nodejs/src/db.ts b/runtimes/nodejs/src/db.ts index 1899917dca..0ffff2a917 100644 --- a/runtimes/nodejs/src/db.ts +++ b/runtimes/nodejs/src/db.ts @@ -5,10 +5,11 @@ * @Description: */ -import { MongoAccessor } from 'database-proxy' +import { LoggerInterface, MongoAccessor } from 'database-proxy' import Config from './config' -import { createLogger, logger } from './support/logger' import * as mongodb_uri from 'mongodb-uri' +import * as log4js from 'log4js' +import { logger } from './support/logger' /** * Database Management @@ -38,14 +39,16 @@ export class DatabaseAgent { const { database } = mongodb_uri.parse(Config.DB_URI) const accessor = new MongoAccessor(database, Config.DB_URI) - accessor.setLogger(createLogger('accessor', 'warning')) + const accessorLogger: any = log4js.getLogger('accessor') + accessorLogger.level = 'warning' + accessor.setLogger(accessorLogger as LoggerInterface) accessor .init() .then(async () => { logger.info('db connected') }) .catch((error) => { - logger.error(error) + accessorLogger.error(error) setTimeout(() => process.exit(101), 0) }) diff --git a/runtimes/nodejs/src/handler/db-proxy.ts b/runtimes/nodejs/src/handler/db-proxy.ts index bf158efc7d..d5bed061e8 100644 --- a/runtimes/nodejs/src/handler/db-proxy.ts +++ b/runtimes/nodejs/src/handler/db-proxy.ts @@ -43,7 +43,6 @@ export async function handleDatabaseProxy(req: IRequest, res: Response) { try { const data = await proxy.execute(params) logger.debug(requestId, 'executed query success with params: ', params) - logger.trace(requestId, `executed query: `, data) return res.send({ code: 0, diff --git a/runtimes/nodejs/src/support/engine/console.ts b/runtimes/nodejs/src/support/engine/console.ts index 7ca73adbda..91b179541d 100644 --- a/runtimes/nodejs/src/support/engine/console.ts +++ b/runtimes/nodejs/src/support/engine/console.ts @@ -1,7 +1,7 @@ import * as util from 'util' -import dayjs from 'dayjs' import chalk from 'chalk' import { padStart} from 'lodash' +import Config from '../../config' enum LogLevel { DEBUG = 'DEBUG', @@ -19,7 +19,7 @@ export class Console { } protected _format(level: LogLevel, ...params: any[]): string { - const time = chalk.gray(dayjs().format('YYYY-MM-DD HH:mm:ss.SSS')) + const time = chalk.gray(new Date().toISOString()) const levelStr = this._colorize(level, padStart(level, 5, ' ')) const fn = chalk.blue(`[${this.category}]`) @@ -36,26 +36,31 @@ export class Console { } debug(...params: any[]) { + if (!this._shouldLog(LogLevel.DEBUG)) return const data = this._format(LogLevel.DEBUG, ...params) console.debug(data) } info(...params: any[]) { + if (!this._shouldLog(LogLevel.INFO)) return const data = this._format(LogLevel.INFO, ...params) console.info(data) } log(...params: any[]) { + if (!this._shouldLog(LogLevel.INFO)) return const data = this._format(LogLevel.INFO, ...params) console.log(data) } warn(...params: any[]) { + if (!this._shouldLog(LogLevel.WARN)) return const data = this._format(LogLevel.WARN, ...params) console.warn(data) } error(...params: any[]) { + if (!this._shouldLog(LogLevel.ERROR)) return const data = this._format(LogLevel.ERROR, ...params) console.error(data) } @@ -82,6 +87,18 @@ export class Console { return result } + protected _shouldLog(level: LogLevel) { + const LogLevelValue = { + [LogLevel.DEBUG]: 0, + [LogLevel.INFO]: 1, + [LogLevel.WARN]: 2, + [LogLevel.ERROR]: 3, + } + const configLevel = (Config.LOG_LEVEL || 'debug').toUpperCase() + const configLevelValue = LogLevelValue[configLevel] ?? 0 + return LogLevelValue[level] >= configLevelValue + } + } export class DebugConsole extends Console { diff --git a/runtimes/nodejs/src/support/engine/function.ts b/runtimes/nodejs/src/support/engine/function.ts index b2fbec0b5c..77ed86dd67 100644 --- a/runtimes/nodejs/src/support/engine/function.ts +++ b/runtimes/nodejs/src/support/engine/function.ts @@ -15,7 +15,7 @@ export class CloudFunction { /** * execution timeout */ - timeout = 60 * 1000 + timeout = 600 * 1000 /** * function data struct diff --git a/runtimes/nodejs/src/support/engine/module.ts b/runtimes/nodejs/src/support/engine/module.ts index 9e8be91b54..f082cc2204 100644 --- a/runtimes/nodejs/src/support/engine/module.ts +++ b/runtimes/nodejs/src/support/engine/module.ts @@ -1,3 +1,4 @@ +import { RunningScriptOptions } from 'vm' import { FunctionCache, FunctionContext } from '.' import Config from '../../config' import { buildSandbox, createScript } from './utils' @@ -5,6 +6,11 @@ import { buildSandbox, createScript } from './utils' export class FunctionModule { private static cache: Map = new Map() + static get(functionName: string): any { + const moduleName = `@/${functionName}` + return FunctionModule.require(moduleName, []) + } + static require(name: string, fromModule: string[]): any { if (name === '@/cloud-sdk') { return require('@lafjs/cloud') @@ -60,8 +66,15 @@ export class FunctionModule { ): any { code = FunctionModule.wrap(code) const sandbox = buildSandbox(functionContext, fromModule) + const options: RunningScriptOptions = { + filename: `CloudFunction.${functionContext.__function_name}`, + displayErrors: true, + contextCodeGeneration: { + strings: false, + }, + } as any const script = createScript(code, {}) - return script.runInNewContext(sandbox, {}) + return script.runInNewContext(sandbox, options) } static deleteCache(name: string): void { diff --git a/runtimes/nodejs/src/support/logger.ts b/runtimes/nodejs/src/support/logger.ts index 5402dd01cf..fec043b393 100644 --- a/runtimes/nodejs/src/support/logger.ts +++ b/runtimes/nodejs/src/support/logger.ts @@ -5,27 +5,10 @@ * @Description: */ -import { LoggerInterface } from 'database-proxy' -import * as log4js from 'log4js' -import Config from '../config' +import { Console } from './engine' -/** - * Create logger instance - * @param category log category - * @param level the logger level : 'fatal', 'error', 'warning', 'info', 'debug', 'trace' - * @returns - */ -export function createLogger( - category: string, - level?: string, -): LoggerInterface { - const logger = log4js.getLogger(category) - logger.level = level ?? Config.LOG_LEVEL - - return logger as any -} /** * The global logger instance */ -export const logger = createLogger('server') +export const logger = new Console('*runtime*') diff --git a/runtimes/nodejs/src/support/ws.ts b/runtimes/nodejs/src/support/ws.ts index c5f6a3acc7..e01292e081 100644 --- a/runtimes/nodejs/src/support/ws.ts +++ b/runtimes/nodejs/src/support/ws.ts @@ -3,9 +3,9 @@ import { WebSocket, WebSocketServer } from 'ws' import { WEBSOCKET_FUNCTION_NAME, } from '../constants' -import { FunctionCache } from './engine' import { logger } from './logger' import { generateUUID } from './utils' +import { FunctionModule } from './engine/module' export class WebSocketAgent { private static _server = null @@ -78,11 +78,12 @@ async function handleWebSocketEvent( headers: request?.headers, } - // const cf = new CloudFunction(func) - const cf = FunctionCache.getEngine(WEBSOCKET_FUNCTION_NAME) - if (!cf) { - logger.error('WebSocket function not found') - return 'WebSocket handler not found' + const module = FunctionModule.get(WEBSOCKET_FUNCTION_NAME) + console.log(module) + const handler = module.default || module.main || module + if(typeof handler === 'function') { + await handler(param) + } else { + logger.error(`default function not found in ${WEBSOCKET_FUNCTION_NAME}`) } - await cf.execute(param) }