From c55774eb391a2e07771ce40fec35e912c9a8b2fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Syn=C3=A1=C4=8Dek?= Date: Sun, 15 Nov 2020 21:33:16 +0100 Subject: [PATCH] feature: add loggers and save logs to DB when using Firebase --- database.rules.json | 6 ++++ firebase.json | 3 ++ functions/index.js | 21 ++++++++----- functions/logger.js | 68 ++++++++++++++++++++++++++++++++++++++++++ functions/package.json | 11 +++---- 5 files changed, 96 insertions(+), 13 deletions(-) create mode 100644 database.rules.json create mode 100644 functions/logger.js diff --git a/database.rules.json b/database.rules.json new file mode 100644 index 0000000..c0aa595 --- /dev/null +++ b/database.rules.json @@ -0,0 +1,6 @@ +{ + "rules": { + ".read": "auth != null", + ".write": "auth != null" + } +} \ No newline at end of file diff --git a/firebase.json b/firebase.json index 15d17eb..348508d 100644 --- a/firebase.json +++ b/firebase.json @@ -21,5 +21,8 @@ "function": "app" } ] + }, + "database": { + "rules": "database.rules.json" } } diff --git a/functions/index.js b/functions/index.js index 3b1c1ac..039e5f2 100644 --- a/functions/index.js +++ b/functions/index.js @@ -2,19 +2,21 @@ const functions = require('firebase-functions'); const admin = require('firebase-admin') const { configureApplication } = require('./lib/app') -// const { createAppLogger } = require('./lib/log-utils') -// const { -// createRouteLogger, -// createErrorLogger, -// } = require('./lib/middlewares') +const { + createRouteLogger, + createErrorLogger, + createAppLogger, +} = require('./logger') admin.initializeApp() const isDevelopment = process.env.NODE_ENV === 'development' -// const appLogger = createAppLogger({ dev: isDevelopment }) -// const errorLogger = createErrorLogger({ dev: isDevelopment }) -// const routeLogger = isDevelopment ? createRouteLogger({ dev: isDevelopment }) : null +const db = admin.database() + +const appLogger = createAppLogger({ db }) +const errorLogger = createErrorLogger({ db }) +const routeLogger = createRouteLogger({ db }) const corsOptions = isDevelopment ? { origin: 'http://localhost:5000', } : null @@ -22,6 +24,9 @@ const corsOptions = isDevelopment ? { const app = configureApplication({ rateLimitEnabled: false, corsOptions, + appLogger, + errorLogger, + routeLogger, }) exports.app = functions.https.onRequest(app) diff --git a/functions/logger.js b/functions/logger.js new file mode 100644 index 0000000..db59880 --- /dev/null +++ b/functions/logger.js @@ -0,0 +1,68 @@ +const winston = require('winston') +const expressWinston = require('express-winston') +const Transport = require('winston-transport') + +class FirebaseTransport extends Transport { + constructor(options) { + super(options) + this._db = options.db + } + + log(info, callback) { + try { + this._db.ref(`log-${new Date().getTime()}`).set(info) + callback(null, info) + this.emit('logged', info) + } catch (err) { + callback(error) + this.emit('error', error) + } + + return info + } +} + +const createRouteLogger = (db) => { + return expressWinston.logger({ + transports: [ + new FirebaseTransport({ db }) + ], + format: winston.format.combine( + winston.format.timestamp(), + winston.format.json() + ), + meta: true, + expressFormat: true, + }) +} + +const createErrorLogger = ({ db }) => { + return expressWinston.errorLogger({ + transports: [ + new FirebaseTransport({ db }) + ], + format: winston.format.combine( + winston.format.timestamp(), + winston.format.json() + ), + }) +} + +const createAppLogger = ({ db }) => { + return winston.createLogger({ + format: winston.format.combine( + winston.format.timestamp(), + winston.format.json() + ), + transports: [ + new FirebaseTransport({ db }), + new winston.transports.Console(), + ] + }) +} + +module.exports = { + createRouteLogger, + createErrorLogger, + createAppLogger, +} diff --git a/functions/package.json b/functions/package.json index 5fbb77e..a2f682c 100644 --- a/functions/package.json +++ b/functions/package.json @@ -13,8 +13,6 @@ }, "main": "index.js", "dependencies": { - "firebase-admin": "^9.2.0", - "firebase-functions": "^3.11.0", "body-parser": "^1.19.0", "cheerio": "^1.0.0-rc.3", "cors": "^2.8.5", @@ -22,12 +20,15 @@ "ejs": "^2.7.1", "express": "^4.17.1", "express-rate-limit": "^5.0.0", - "express-winston": "^4.0.1", + "express-winston": "^4.0.5", + "firebase-admin": "^9.2.0", + "firebase-functions": "^3.11.0", "ics": "^2.22.1", "request": "^2.88.0", "serve-favicon": "^2.5.0", - "winston": "^3.2.1", - "winston-daily-rotate-file": "^4.2.1" + "winston": "^3.3.3", + "winston-daily-rotate-file": "^4.2.1", + "winston-transport": "^4.4.0" }, "devDependencies": { "firebase-functions-test": "^0.2.0"