From a9fdf64aac6c3eba3d751de654bd4fa54aa4d0d1 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Tue, 19 Apr 2016 11:14:38 -0400 Subject: [PATCH] Adds logger on cloud code request object --- spec/CloudCodeLogger.spec.js | 66 ++++++++++++++++++++++++++++++++++ spec/LoggerController.spec.js | 5 +++ src/Routers/FunctionsRouter.js | 6 +++- src/logger.js | 25 +++++++++++++ src/triggers.js | 3 ++ 5 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 spec/CloudCodeLogger.spec.js diff --git a/spec/CloudCodeLogger.spec.js b/spec/CloudCodeLogger.spec.js new file mode 100644 index 0000000000..c12ef50184 --- /dev/null +++ b/spec/CloudCodeLogger.spec.js @@ -0,0 +1,66 @@ +'use strict'; +var LoggerController = require('../src/Controllers/LoggerController').LoggerController; +var FileLoggerAdapter = require('../src/Adapters/Logger/FileLoggerAdapter').FileLoggerAdapter; + +var clearLogs = require('../src/logger').clearLogs; +var loggerController = new LoggerController(new FileLoggerAdapter()); + +describe("Cloud Code Logger", () => { + beforeAll(() => { + clearLogs(); + }); + + afterAll(() => { + clearLogs(); + }); + + it("should expose log to functions", (done) => { + Parse.Cloud.define("loggerTest", (req, res) => { + req.logger.info('loggerTest', 'info log', { info: 'some log' }); + req.logger.error('loggerTest','error log', {error: 'there was an error'}); + res.success({}); + }); + + Parse.Cloud.run('loggerTest').then(() => { + Parse.Cloud._removeHook('Functions', 'loggerTest'); + return loggerController.getLogs({}) + }).then((res) => { + expect(res.length).not.toBe(0); + let lastLogs = res.slice(0, 2); + let errorMessage = lastLogs[0]; + let infoMessage = lastLogs[1]; + expect(errorMessage.level).toBe('error'); + expect(errorMessage.error).toBe('there was an error'); + expect(errorMessage.message).toBe('loggerTest error log'); + expect(infoMessage.level).toBe('info'); + expect(infoMessage.info).toBe('some log'); + expect(infoMessage.message).toBe('loggerTest info log'); + done(); + }); + }); + + it("should expose log to trigger", (done) => { + Parse.Cloud.beforeSave("MyObject", (req, res) => { + req.logger.info('beforeSave MyObject', 'info log', { info: 'some log' }); + req.logger.error('beforeSave MyObject','error log', {error: 'there was an error'}); + res.success({}); + }); + let obj = new Parse.Object('MyObject') + obj.save().then(() => { + Parse.Cloud._removeHook('Triggers', 'beforeSave', 'MyObject'); + return loggerController.getLogs({}) + }).then((res) => { + expect(res.length).not.toBe(0); + let lastLogs = res.slice(0, 2); + let errorMessage = lastLogs[0]; + let infoMessage = lastLogs[1]; + expect(errorMessage.level).toBe('error'); + expect(errorMessage.error).toBe('there was an error'); + expect(errorMessage.message).toBe('beforeSave MyObject error log'); + expect(infoMessage.level).toBe('info'); + expect(infoMessage.info).toBe('some log'); + expect(infoMessage.message).toBe('beforeSave MyObject info log'); + done(); + }); + }); +}); diff --git a/spec/LoggerController.spec.js b/spec/LoggerController.spec.js index f609041299..a2b8fc47e4 100644 --- a/spec/LoggerController.spec.js +++ b/spec/LoggerController.spec.js @@ -1,7 +1,12 @@ var LoggerController = require('../src/Controllers/LoggerController').LoggerController; var FileLoggerAdapter = require('../src/Adapters/Logger/FileLoggerAdapter').FileLoggerAdapter; +var clearLogs = require('../src/logger').clearLogs; + describe('LoggerController', () => { + afterEach(() => { + clearLogs(); + }); it('can check process a query witout throwing', (done) => { // Make mock request var query = {}; diff --git a/src/Routers/FunctionsRouter.js b/src/Routers/FunctionsRouter.js index 0902b871da..849f605d8d 100644 --- a/src/Routers/FunctionsRouter.js +++ b/src/Routers/FunctionsRouter.js @@ -4,8 +4,11 @@ var express = require('express'), Parse = require('parse/node').Parse, triggers = require('../triggers'); +import { addGroup } from '../logger'; import PromiseRouter from '../PromiseRouter'; +let logger = addGroup('cloud-code'); + export class FunctionsRouter extends PromiseRouter { mountRoutes() { @@ -38,7 +41,8 @@ export class FunctionsRouter extends PromiseRouter { params: params, master: req.auth && req.auth.isMaster, user: req.auth && req.auth.user, - installationId: req.info.installationId + installationId: req.info.installationId, + logger }; if (theValidator && typeof theValidator === "function") { diff --git a/src/logger.js b/src/logger.js index e0556bf7d9..1e17ae25ac 100644 --- a/src/logger.js +++ b/src/logger.js @@ -10,6 +10,31 @@ if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') { } let currentLogsFolder = LOGS_FOLDER; +let clearLogs; +if (process.env.TESTING) { + + var rmDirContents = function(dirPath) { + try { var files = fs.readdirSync(dirPath); } + catch(e) { return; } + if (files.length > 0) + for (var i = 0; i < files.length; i++) { + var filePath = dirPath + '/' + files[i]; + if (fs.statSync(filePath).isFile()) + fs.unlinkSync(filePath); + else + rmDir(filePath); + } + }; + clearLogs = function() { + let folder = currentLogsFolder; + if (!path.isAbsolute(folder)) { + folder = path.resolve(process.cwd(), folder); + } + rmDirContents(folder); + } +} + +export { clearLogs }; function generateTransports(level) { let transports = [ diff --git a/src/triggers.js b/src/triggers.js index 8622df87a5..e1c26425fa 100644 --- a/src/triggers.js +++ b/src/triggers.js @@ -1,6 +1,7 @@ // triggers.js import Parse from 'parse/node'; import cache from './cache'; +import { addGroup } from './logger'; export const Types = { beforeSave: 'beforeSave', @@ -113,6 +114,8 @@ export function getRequestObject(triggerType, auth, parseObject, originalParseOb if (auth.installationId) { request['installationId'] = auth.installationId; } + let ccLogger = addGroup('cloud-code'); + request.logger = ccLogger; return request; }