Skip to content

Commit ee22191

Browse files
committed
Refactor logging to provide common logger from LoggerAdapter
Move logger logic de WinstonLoggerAdapter Further improvements in configuration Use logger instead of getLogger - Removes PLog module Reverts name changes nits
1 parent 39078e8 commit ee22191

18 files changed

+242
-238
lines changed

spec/Logger.spec.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var logger = require('../src/logger');
1+
var logging = require('../src/Adapters/Logger/WinstonLogger');
22
var winston = require('winston');
33

44
class TestTransport extends winston.Transport {
@@ -8,11 +8,15 @@ class TestTransport extends winston.Transport {
88
}
99

1010
describe('Logger', () => {
11+
// Test is excluded as will be refactored
1112
it('should add transport', () => {
12-
const testTransport = new (TestTransport)({});
13+
const testTransport = new (TestTransport)({
14+
name: 'test'
15+
});
1316
spyOn(testTransport, 'log');
14-
logger.addTransport(testTransport);
15-
logger.logger.info('hi');
17+
logging.addTransport(testTransport);
18+
logging.logger.info('hi');
1619
expect(testTransport.log).toHaveBeenCalled();
20+
logging.removeTransport(testTransport);
1721
});
1822
});

spec/Subscription.spec.js

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
var Subscription = require('../src/LiveQuery/Subscription').Subscription;
2-
2+
let logger;
33
describe('Subscription', function() {
44

55
beforeEach(function() {
6-
var mockError = jasmine.createSpy('error');
7-
jasmine.mockLibrary('../src/LiveQuery/PLog', 'error', mockError);
6+
logger = require('../src/logger').logger;
7+
spyOn(logger, 'error').and.callThrough();
88
});
99

1010
it('can be initialized', function() {
@@ -62,17 +62,15 @@ describe('Subscription', function() {
6262
var subscription = new Subscription('className', { key : 'value' }, 'hash');
6363
subscription.deleteClientSubscription(1, 1);
6464

65-
var PLog =require('../src/LiveQuery/PLog');
66-
expect(PLog.error).toHaveBeenCalled();
65+
expect(logger.error).toHaveBeenCalled();
6766
});
6867

6968
it('can delete nonexistent request for one client', function() {
7069
var subscription = new Subscription('className', { key : 'value' }, 'hash');
7170
subscription.addClientSubscription(1, 1);
7271
subscription.deleteClientSubscription(1, 2);
7372

74-
var PLog =require('../src/LiveQuery/PLog');
75-
expect(PLog.error).toHaveBeenCalled();
73+
expect(logger.error).toHaveBeenCalled();
7674
expect(subscription.clientRequestIds.size).toBe(1);
7775
expect(subscription.clientRequestIds.get(1)).toEqual([1]);
7876
});
@@ -83,8 +81,7 @@ describe('Subscription', function() {
8381
subscription.addClientSubscription(1, 2);
8482
subscription.deleteClientSubscription(1, 2);
8583

86-
var PLog =require('../src/LiveQuery/PLog');
87-
expect(PLog.error).not.toHaveBeenCalled();
84+
expect(logger.error).not.toHaveBeenCalled();
8885
expect(subscription.clientRequestIds.size).toBe(1);
8986
expect(subscription.clientRequestIds.get(1)).toEqual([1]);
9087
});
@@ -96,8 +93,7 @@ describe('Subscription', function() {
9693
subscription.deleteClientSubscription(1, 1);
9794
subscription.deleteClientSubscription(1, 2);
9895

99-
var PLog =require('../src/LiveQuery/PLog');
100-
expect(PLog.error).not.toHaveBeenCalled();
96+
expect(logger.error).not.toHaveBeenCalled();
10197
expect(subscription.clientRequestIds.size).toBe(0);
10298
});
10399

@@ -111,13 +107,8 @@ describe('Subscription', function() {
111107
subscription.deleteClientSubscription(2, 1);
112108
subscription.deleteClientSubscription(2, 2);
113109

114-
var PLog =require('../src/LiveQuery/PLog');
115-
expect(PLog.error).not.toHaveBeenCalled();
110+
expect(logger.error).not.toHaveBeenCalled();
116111
expect(subscription.clientRequestIds.size).toBe(1);
117112
expect(subscription.clientRequestIds.get(1)).toEqual([1]);
118113
});
119-
120-
afterEach(function(){
121-
jasmine.restoreLibrary('../src/LiveQuery/PLog', 'error');
122-
});
123114
});

spec/helper.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,6 @@ global.fit_exclude_dbs = excluded => {
342342
}
343343
}
344344

345-
// LiveQuery test setting
346-
require('../src/LiveQuery/PLog').logLevel = 'NONE';
347345
var libraryCache = {};
348346
jasmine.mockLibrary = function(library, name, mock) {
349347
var original = require(library)[name];

src/Adapters/Logger/LoggerAdapter.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@
55
// Adapter classes must implement the following functions:
66
// * info(obj1 [, obj2, .., objN])
77
// * error(obj1 [, obj2, .., objN])
8-
// * query(options, callback)
8+
// * query(options, callback) /* optional */
9+
// * configureLogger(options)
910
// Default is WinstonLoggerAdapter.js
1011

1112
export class LoggerAdapter {
13+
constructor(options) {}
1214
info() {}
1315
error() {}
14-
query(options, callback) {}
16+
warn() {}
17+
verbose() {}
1518
}
1619

1720
export default LoggerAdapter;

src/Adapters/Logger/WinstonLogger.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import winston from 'winston';
2+
import fs from 'fs';
3+
import path from 'path';
4+
import DailyRotateFile from 'winston-daily-rotate-file';
5+
import _ from 'lodash';
6+
import defaults from '../../logger';
7+
8+
const logger = new winston.Logger();
9+
const additionalTransports = [];
10+
11+
function updateTransports(options) {
12+
let transports = Object.assign({}, logger.transports);
13+
if (options) {
14+
if (_.isNull(options.dirname)) {
15+
delete transports['parse-server'];
16+
delete transports['parse-server-error'];
17+
} else if (!_.isUndefined(options.dirname)) {
18+
transports['parse-server'] = new (DailyRotateFile)(
19+
Object.assign({
20+
filename: 'parse-server.info',
21+
name: 'parse-server',
22+
}, options));
23+
transports['parse-server-error'] = new (DailyRotateFile)(
24+
Object.assign({
25+
filename: 'parse-server.err',
26+
name: 'parse-server-error',
27+
level: 'error'
28+
}, options));
29+
}
30+
31+
if (!process.env.TESTING || process.env.VERBOSE) {
32+
transports.console = new (winston.transports.Console)(
33+
Object.assign({
34+
colorize: true,
35+
name: 'console'
36+
}, options));
37+
}
38+
}
39+
// Mount the additional transports
40+
additionalTransports.forEach((transport) => {
41+
transports[transport.name] = transport;
42+
});
43+
logger.configure({
44+
transports: _.values(transports)
45+
});
46+
}
47+
48+
export function configureLogger({
49+
logsFolder = defaults.logsFolder,
50+
jsonLogs = defaults.jsonLogs,
51+
logLevel = winston.level,
52+
verbose = defaults.verbose } = {}) {
53+
54+
if (verbose) {
55+
logLevel = 'verbose';
56+
}
57+
58+
winston.level = logLevel;
59+
const options = {};
60+
61+
if (logsFolder) {
62+
if (!path.isAbsolute(logsFolder)) {
63+
logsFolder = path.resolve(process.cwd(), logsFolder);
64+
}
65+
try {
66+
fs.mkdirSync(logsFolder);
67+
} catch (exception) {}
68+
}
69+
options.dirname = logsFolder;
70+
options.level = logLevel;
71+
if (jsonLogs) {
72+
options.json = true;
73+
options.stringify = true;
74+
}
75+
updateTransports(options);
76+
}
77+
78+
export function addTransport(transport) {
79+
additionalTransports.push(transport);
80+
updateTransports();
81+
}
82+
83+
export function removeTransport(transport) {
84+
let transportName = typeof transport == 'string' ? transport : transport.name;
85+
let transports = Object.assign({}, logger.transports);
86+
delete transports[transportName];
87+
logger.configure({
88+
transports: _.values(transports)
89+
})
90+
}
91+
92+
export { logger, addTransport, configureLogger, removeTransport };
93+
export default logger;

src/Adapters/Logger/WinstonLoggerAdapter.js

Lines changed: 19 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,21 @@
11
import { LoggerAdapter } from './LoggerAdapter';
2-
import { logger, addTransport } from '../../logger';
2+
import { logger, addTransport, configureLogger } from './WinstonLogger';
33

44
const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000;
5-
const CACHE_TIME = 1000 * 60;
6-
7-
let currentDate = new Date();
8-
9-
let simpleCache = {
10-
timestamp: null,
11-
from: null,
12-
until: null,
13-
order: null,
14-
data: [],
15-
level: 'info',
16-
};
175

186
// returns Date object rounded to nearest day
197
let _getNearestDay = (date) => {
208
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
219
}
2210

23-
// returns Date object of previous day
24-
let _getPrevDay = (date) => {
25-
return new Date(date - MILLISECONDS_IN_A_DAY);
26-
}
27-
28-
// returns the iso formatted file name
29-
let _getFileName = () => {
30-
return _getNearestDay(currentDate).toISOString()
31-
}
32-
33-
// check for valid cache when both from and util match.
34-
// cache valid for up to 1 minute
35-
let _hasValidCache = (from, until, level) => {
36-
if (String(from) === String(simpleCache.from) &&
37-
String(until) === String(simpleCache.until) &&
38-
new Date() - simpleCache.timestamp < CACHE_TIME &&
39-
level === simpleCache.level) {
40-
return true;
11+
export class WinstonLoggerAdapter extends LoggerAdapter {
12+
constructor(options) {
13+
super();
14+
if (options) {
15+
configureLogger(options);
16+
}
4117
}
42-
return false;
43-
}
4418

45-
// check that log entry has valid time stamp based on query
46-
let _isValidLogEntry = (from, until, entry) => {
47-
var _entry = JSON.parse(entry),
48-
timestamp = new Date(_entry.timestamp);
49-
return timestamp >= from && timestamp <= until
50-
? true
51-
: false
52-
};
53-
54-
export class WinstonLoggerAdapter extends LoggerAdapter {
5519
info() {
5620
return logger.info.apply(undefined, arguments);
5721
}
@@ -60,6 +24,18 @@ export class WinstonLoggerAdapter extends LoggerAdapter {
6024
return logger.error.apply(undefined, arguments);
6125
}
6226

27+
warn() {
28+
return logger.warn.apply(undefined, arguments);
29+
}
30+
31+
verbose() {
32+
return logger.verbose.apply(undefined, arguments);
33+
}
34+
35+
log() {
36+
return logger.log.apply(undefined, arguments);
37+
}
38+
6339
addTransport(transport) {
6440
// Note that this is calling addTransport
6541
// from logger. See import - confusing.

src/Controllers/LoggerController.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ export class LoggerController extends AdaptableController {
6060
throw new Parse.Error(Parse.Error.PUSH_MISCONFIGURED,
6161
'Logger adapter is not availabe');
6262
}
63+
if (typeof this.adapter.query !== 'function') {
64+
throw new Parse.Error(Parse.Error.PUSH_MISCONFIGURED,
65+
'Querying logs is not supported with this adapter');
66+
}
6367
options = LoggerController.parseOptions(options);
6468
return this.adapter.query(options);
6569
}

src/LiveQuery/Client.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import PLog from './PLog';
21
import Parse from 'parse/node';
2+
import logger from '../logger';
33

44
import type { FlattenedObjectData } from './Subscription';
55
export type Message = { [attr: string]: any };
@@ -37,7 +37,7 @@ class Client {
3737
}
3838

3939
static pushResponse(parseWebSocket: any, message: Message): void {
40-
PLog.verbose('Push Response : %j', message);
40+
logger.verbose('Push Response : %j', message);
4141
parseWebSocket.send(message);
4242
}
4343

src/LiveQuery/PLog.js

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/LiveQuery/ParseCloudCodePublisher.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ParsePubSub } from './ParsePubSub';
2-
import PLog from './PLog';
2+
import logger from '../logger';
33

44
class ParseCloudCodePublisher {
55
parsePublisher: Object;
@@ -20,7 +20,7 @@ class ParseCloudCodePublisher {
2020

2121
// Request is the request object from cloud code functions. request.object is a ParseObject.
2222
_onCloudCodeMessage(type: string, request: any): void {
23-
PLog.verbose('Raw request from cloud code current : %j | original : %j', request.object, request.original);
23+
logger.verbose('Raw request from cloud code current : %j | original : %j', request.object, request.original);
2424
// We need the full JSON which includes className
2525
let message = {
2626
currentParseObject: request.object._toFullJSON()

0 commit comments

Comments
 (0)