Refactor logging to provide common logger from LoggerAdapter (#2478)
* 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 * Adds additional logging levels as requirements * Adds tests for logging configuration * removes flaky test * investigate... * further investigation * Adds silent option to disable console output * Restores logs with VERBOSE in tests * Expose controller instead of adapter, reduces method requirements for adapter * Shuffles initializations around * Fix doc * Load cloudCode last to make sure the logger is available * Adds test to make sure we can load an adapter from npm module * extract defaults * Adds defaultMongoURI to defaults * fix defaults values * Proper error for PG failures * Disable flaky test
This commit is contained in:
@@ -8,14 +8,13 @@
|
||||
|
||||
import { MongoClient, GridStore, Db} from 'mongodb';
|
||||
import { FilesAdapter } from './FilesAdapter';
|
||||
|
||||
const DefaultMongoURI = 'mongodb://localhost:27017/parse';
|
||||
import defaults from '../../defaults';
|
||||
|
||||
export class GridStoreAdapter extends FilesAdapter {
|
||||
_databaseURI: string;
|
||||
_connectionPromise: Promise<Db>;
|
||||
|
||||
constructor(mongoDatabaseURI = DefaultMongoURI) {
|
||||
constructor(mongoDatabaseURI = defaults.DefaultMongoURI) {
|
||||
super();
|
||||
this._databaseURI = mongoDatabaseURI;
|
||||
this._connect();
|
||||
|
||||
@@ -3,15 +3,13 @@
|
||||
// Allows you to change the logger mechanism
|
||||
//
|
||||
// Adapter classes must implement the following functions:
|
||||
// * info(obj1 [, obj2, .., objN])
|
||||
// * error(obj1 [, obj2, .., objN])
|
||||
// * query(options, callback)
|
||||
// * log() {}
|
||||
// * query(options, callback) /* optional */
|
||||
// Default is WinstonLoggerAdapter.js
|
||||
|
||||
export class LoggerAdapter {
|
||||
info() {}
|
||||
error() {}
|
||||
query(options, callback) {}
|
||||
constructor(options) {}
|
||||
log(level, message, /* meta */) {}
|
||||
}
|
||||
|
||||
export default LoggerAdapter;
|
||||
|
||||
100
src/Adapters/Logger/WinstonLogger.js
Normal file
100
src/Adapters/Logger/WinstonLogger.js
Normal file
@@ -0,0 +1,100 @@
|
||||
import winston from 'winston';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import DailyRotateFile from 'winston-daily-rotate-file';
|
||||
import _ from 'lodash';
|
||||
import defaults from '../../defaults';
|
||||
|
||||
const logger = new winston.Logger();
|
||||
const additionalTransports = [];
|
||||
|
||||
function updateTransports(options) {
|
||||
let transports = Object.assign({}, logger.transports);
|
||||
if (options) {
|
||||
let silent = options.silent;
|
||||
delete options.silent;
|
||||
if (_.isNull(options.dirname)) {
|
||||
delete transports['parse-server'];
|
||||
delete transports['parse-server-error'];
|
||||
} else if (!_.isUndefined(options.dirname)) {
|
||||
transports['parse-server'] = new (DailyRotateFile)(
|
||||
Object.assign({
|
||||
filename: 'parse-server.info',
|
||||
name: 'parse-server',
|
||||
}, options));
|
||||
transports['parse-server-error'] = new (DailyRotateFile)(
|
||||
Object.assign({
|
||||
filename: 'parse-server.err',
|
||||
name: 'parse-server-error',
|
||||
level: 'error'
|
||||
}, options));
|
||||
}
|
||||
|
||||
transports.console = new (winston.transports.Console)(
|
||||
Object.assign({
|
||||
colorize: true,
|
||||
name: 'console',
|
||||
silent
|
||||
}, options));
|
||||
}
|
||||
// Mount the additional transports
|
||||
additionalTransports.forEach((transport) => {
|
||||
transports[transport.name] = transport;
|
||||
});
|
||||
logger.configure({
|
||||
transports: _.values(transports)
|
||||
});
|
||||
}
|
||||
|
||||
export function configureLogger({
|
||||
logsFolder = defaults.logsFolder,
|
||||
jsonLogs = defaults.jsonLogs,
|
||||
logLevel = winston.level,
|
||||
verbose = defaults.verbose,
|
||||
silent = defaults.silent } = {}) {
|
||||
|
||||
if (verbose) {
|
||||
logLevel = 'verbose';
|
||||
}
|
||||
|
||||
winston.level = logLevel;
|
||||
const options = {};
|
||||
|
||||
if (logsFolder) {
|
||||
if (!path.isAbsolute(logsFolder)) {
|
||||
logsFolder = path.resolve(process.cwd(), logsFolder);
|
||||
}
|
||||
try {
|
||||
fs.mkdirSync(logsFolder);
|
||||
} catch (exception) {}
|
||||
}
|
||||
options.dirname = logsFolder;
|
||||
options.level = logLevel;
|
||||
options.silent = silent;
|
||||
|
||||
if (jsonLogs) {
|
||||
options.json = true;
|
||||
options.stringify = true;
|
||||
}
|
||||
updateTransports(options);
|
||||
}
|
||||
|
||||
export function addTransport(transport) {
|
||||
additionalTransports.push(transport);
|
||||
updateTransports();
|
||||
}
|
||||
|
||||
export function removeTransport(transport) {
|
||||
let transportName = typeof transport == 'string' ? transport : transport.name;
|
||||
let transports = Object.assign({}, logger.transports);
|
||||
delete transports[transportName];
|
||||
logger.configure({
|
||||
transports: _.values(transports)
|
||||
});
|
||||
_.remove(additionalTransports, (transport) => {
|
||||
return transport.name === transportName;
|
||||
});
|
||||
}
|
||||
|
||||
export { logger, addTransport, configureLogger, removeTransport };
|
||||
export default logger;
|
||||
@@ -1,63 +1,23 @@
|
||||
import { LoggerAdapter } from './LoggerAdapter';
|
||||
import { logger, addTransport } from '../../logger';
|
||||
import { logger, addTransport, configureLogger } from './WinstonLogger';
|
||||
|
||||
const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000;
|
||||
const CACHE_TIME = 1000 * 60;
|
||||
|
||||
let currentDate = new Date();
|
||||
|
||||
let simpleCache = {
|
||||
timestamp: null,
|
||||
from: null,
|
||||
until: null,
|
||||
order: null,
|
||||
data: [],
|
||||
level: 'info',
|
||||
};
|
||||
|
||||
// returns Date object rounded to nearest day
|
||||
let _getNearestDay = (date) => {
|
||||
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
||||
}
|
||||
|
||||
// returns Date object of previous day
|
||||
let _getPrevDay = (date) => {
|
||||
return new Date(date - MILLISECONDS_IN_A_DAY);
|
||||
}
|
||||
|
||||
// returns the iso formatted file name
|
||||
let _getFileName = () => {
|
||||
return _getNearestDay(currentDate).toISOString()
|
||||
}
|
||||
|
||||
// check for valid cache when both from and util match.
|
||||
// cache valid for up to 1 minute
|
||||
let _hasValidCache = (from, until, level) => {
|
||||
if (String(from) === String(simpleCache.from) &&
|
||||
String(until) === String(simpleCache.until) &&
|
||||
new Date() - simpleCache.timestamp < CACHE_TIME &&
|
||||
level === simpleCache.level) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// check that log entry has valid time stamp based on query
|
||||
let _isValidLogEntry = (from, until, entry) => {
|
||||
var _entry = JSON.parse(entry),
|
||||
timestamp = new Date(_entry.timestamp);
|
||||
return timestamp >= from && timestamp <= until
|
||||
? true
|
||||
: false
|
||||
};
|
||||
|
||||
export class WinstonLoggerAdapter extends LoggerAdapter {
|
||||
info() {
|
||||
return logger.info.apply(undefined, arguments);
|
||||
constructor(options) {
|
||||
super();
|
||||
if (options) {
|
||||
configureLogger(options);
|
||||
}
|
||||
}
|
||||
|
||||
error() {
|
||||
return logger.error.apply(undefined, arguments);
|
||||
log() {
|
||||
return logger.log.apply(logger, arguments);
|
||||
}
|
||||
|
||||
addTransport(transport) {
|
||||
|
||||
@@ -17,7 +17,6 @@ let mongodb = require('mongodb');
|
||||
let MongoClient = mongodb.MongoClient;
|
||||
|
||||
const MongoSchemaCollectionName = '_SCHEMA';
|
||||
const DefaultMongoURI = 'mongodb://localhost:27017/parse';
|
||||
|
||||
const storageAdapterAllCollections = mongoAdapter => {
|
||||
return mongoAdapter.connect()
|
||||
@@ -86,7 +85,7 @@ export class MongoStorageAdapter {
|
||||
database;
|
||||
|
||||
constructor({
|
||||
uri = DefaultMongoURI,
|
||||
uri = defaults.DefaultMongoURI,
|
||||
collectionPrefix = '',
|
||||
mongoOptions = {},
|
||||
}) {
|
||||
|
||||
Reference in New Issue
Block a user