Skip to content

Commit

Permalink
Merge pull request #11 from flowcore-io/added-logger
Browse files Browse the repository at this point in the history
feat: Added a generic logger
  • Loading branch information
argilzar authored May 15, 2024
2 parents 3026239 + 51d8778 commit 22682d7
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const envSchema = z.object({
CLEAR_TABLE_ON_START: z.string().default("false"),
MATCH_KEY: z.string().optional().default(""),
CONVERT_VALUES: z.string().optional().default("false"),
LOG_LEVEL: z.string().optional().default("INFO"),
});

export const env = envSchema.parse(process.env);
6 changes: 3 additions & 3 deletions src/functions/start.entrypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@

import { db } from "../db";
import { env } from "../env";
import { Logger } from "../utils/logger";

const TABLE_NAME = env.TABLE_NAME;
const CLEAR_TABLE_ON_START = env.CLEAR_TABLE_ON_START.toLowerCase() === "true";

export default async function() {
console.log("Hello from start");

if (CLEAR_TABLE_ON_START) {
console.info("CLEAR_TABLE_ON_START tag detected! dropping table if it exists...");
Logger.info("CLEAR_TABLE_ON_START tag detected! dropping table if it exists...");
await db.schema.dropTableIfExists(TABLE_NAME);
console.info(`Table ${TABLE_NAME} dropped!`);
Logger.info(`Table ${TABLE_NAME} dropped!`);
}
}
23 changes: 13 additions & 10 deletions src/functions/transform.entrypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { db } from "../db";
import { base64Decode } from "../utils/base-64-decode";
import { createTable } from "../utils/create-table";
import { getSchema, tryExtendSchemaWithKeyValue } from "../utils/get-schema";
import { Logger } from "../utils/logger";


export interface Input<T = any> {
eventId: string;
Expand All @@ -22,17 +24,17 @@ const TABLE_SCHEMA = env.TABLE_SCHEMA_BASE64 && base64Decode(env.TABLE_SCHEMA_BA
const CONVERT_VALUES = env.CONVERT_VALUES;

export default async function(input: Input) {
console.debug(`Received event ${input.eventId}, with payload ${JSON.stringify(input.payload)} and valid time ${input.validTime}`);
Logger.debug(`Received event ${input.eventId}, with payload ${JSON.stringify(input.payload)} and valid time ${input.validTime}`);

const combinedPayload = { eventid: input.eventId, validTime: input.validTime, ...input.payload };

const schema = getSchema(TABLE_SCHEMA, combinedPayload);
if (schema.error) {
console.error("Failed to parse schema:", schema.error);
Logger.error("Failed to parse schema:", schema.error);
return;
}
if (!schema.value) {
console.error("Schema is empty");
Logger.error("Schema is empty");
return;
}

Expand All @@ -50,7 +52,7 @@ export default async function(input: Input) {

const tableMissing = !await db.schema.hasTable(TABLE_NAME);
if (tableMissing) {
console.info(`Table "${TABLE_NAME}" does not exist! creating it now...`);
Logger.info(`Table "${TABLE_NAME}" does not exist! creating it now...`);
await createTable(TABLE_NAME, finalSchema);
}

Expand All @@ -61,22 +63,23 @@ export default async function(input: Input) {
const finalName = value.mapFrom || name;
const entry = combinedPayload[finalName];
if (!entry && value.required) {
console.warn(`Missing entry for ${finalName}`);
Logger.warn(`Missing entry for ${finalName}`);
continue;
}



if (typeof entry === "object") {
console.debug(`Converting ${finalName} to JSON`);
Logger.debug(`Converting ${finalName} to JSON`);
finalPayload[name] = JSON.stringify(entry);
continue;
}
if(CONVERT_VALUES === "true" && value.type === "integer") {
try {
console.debug(`Converting ${finalName} to integer`);
Logger.debug(`Converting ${finalName} to integer`);
finalPayload[name] = parseInt(entry, 10);
}catch (e) {
console.error(`Failed to convert ${finalName} to integer, setting to null`);
Logger.error(`Failed to convert ${finalName} to integer, setting to null`);
finalPayload[name] = null;
}
continue;
Expand All @@ -87,12 +90,12 @@ export default async function(input: Input) {
if (MATCH_KEY) {
const result = await db(TABLE_NAME).insert(finalPayload).onConflict(MATCH_KEY).merge(finalPayload);
if (result.length <= 0) {
console.error("Failed to update data");
Logger.error("Failed to update data");
}
} else {
const result = await db(TABLE_NAME).insert(finalPayload);
if (result.length <= 0) {
console.error("Failed to insert data");
Logger.error("Failed to insert data");
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import express, {Request, Response} from "express";
import health from "@functions/health.entrypoint";
import transform from "@functions/transform.entrypoint";
import start from "@functions/start.entrypoint";
import { Logger } from "./utils/logger";

const app = express();

Expand All @@ -30,10 +31,10 @@ const run = async (): Promise<void> => {
try {
await start();
app.listen(port, () => {
console.log(`Server started on port ${port}`);
Logger.info(`Server started on port ${port}`);
});
} catch (error) {
console.error(error);
Logger.error(error);
process.exit(1);
}
};
Expand Down
7 changes: 4 additions & 3 deletions src/utils/create-table.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { TableSchema } from "../contracts/tableSchema";
import { db } from "../db";
import { Knex } from "knex";
import { Logger } from "./logger";


// todo: adjust this code to be more context aware once we support multiple dbs (e.g. not all dbs support json, so instead, it would be stringified and stored as a text or string)
Expand Down Expand Up @@ -29,13 +30,13 @@ export async function createTable(tableName: string, schema: TableSchema) {
for (const [key, value] of Object.entries(schema)) {

if (!value.type) {
console.error(`Type missing for key ${key}`);
Logger.error(`Type missing for key ${key}`);
continue;
}

const factory = COLUMN_FACTORY[value.type.toLowerCase()];
if (!factory) {
console.error(`Unknown type ${value.type} for key ${key}`);
Logger.error(`Unknown type ${value.type} for key ${key}`);
continue;
}

Expand All @@ -46,7 +47,7 @@ export async function createTable(tableName: string, schema: TableSchema) {

}
});
console.info(`Table ${tableName} created successfully.`);
Logger.info(`Table ${tableName} created successfully.`);
}

type TableMapper = {
Expand Down
5 changes: 3 additions & 2 deletions src/utils/get-schema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ColumnDefinition, TableSchema } from "../contracts/tableSchema";
import { jsonTryParse, JsonTryParseResult } from "./json-try-parse";
import { Logger } from "./logger";

const AUTO_SCHEMA_FACTORY: Record<string, (value: unknown) => ColumnDefinition> = {
"string": () => ({ type: "string" }),
Expand All @@ -16,7 +17,7 @@ export function getSchema<T extends object>(schemaString: string | undefined, fa
return jsonTryParse<TableSchema>(schemaString);
}

console.info("No schema provided, generating schema from input");
Logger.info("No schema provided, generating schema from input");

return {
value: generateSchemaFromInput(fallbackObject),
Expand All @@ -26,7 +27,7 @@ export function getSchema<T extends object>(schemaString: string | undefined, fa

export function tryExtendSchemaWithKeyValue(schema: TableSchema, key: string, value: unknown, definition?: Partial<ColumnDefinition>): TableSchema {
if (value === undefined) {
console.warn(`Value associated with key "${key}" was undefined, skipping...`);
Logger.warn(`Value associated with key "${key}" was undefined, skipping...`);
return schema;
}

Expand Down
36 changes: 36 additions & 0 deletions src/utils/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { env } from "../env";

export enum LogLevel {
ERROR = 0,
WARN = 1,
INFO = 2,
DEBUG = 3
}

export class Logger {
private static logLevel: LogLevel = LogLevel[env.LOG_LEVEL.toUpperCase() as keyof typeof LogLevel] || LogLevel.INFO;

static error(...args: any[]) {
if (this.logLevel >= LogLevel.ERROR) {
console.error(...args);
}
}

static warn(...args: any[]) {
if (this.logLevel >= LogLevel.WARN) {
console.warn(...args);
}
}

static info(...args: any[]) {
if (this.logLevel >= LogLevel.INFO) {
console.info(...args);
}
}

static debug(...args: any[]) {
if (this.logLevel >= LogLevel.DEBUG) {
console.debug(...args);
}
}
}

0 comments on commit 22682d7

Please sign in to comment.