From 9b715a0732e0d2e6cbd99fea17cb59de76983c76 Mon Sep 17 00:00:00 2001 From: qejk Date: Tue, 19 Apr 2016 06:39:51 +0200 Subject: [PATCH 01/20] Refactors Space.Logger class to use arguments on Constructor, removes global var Space.log --- source/logger.js | 40 ++++------------------------------------ 1 file changed, 4 insertions(+), 36 deletions(-) diff --git a/source/logger.js b/source/logger.js index bf6488c..9ef664a 100644 --- a/source/logger.js +++ b/source/logger.js @@ -1,9 +1,3 @@ -let config = Space.configuration; - -if (Meteor.isServer) { - winston = Npm.require('winston'); -} - Space.Object.extend(Space, 'Logger', { _logger: null, @@ -18,31 +12,12 @@ Space.Object.extend(Space, 'Logger', { 'debug': 7 }, - Constructor() { - if (Meteor.isServer) { - this._logger = new winston.Logger({ - transports: [ - new winston.transports.Console({ - colorize: true, - prettyPrint: true - }) - ] - }); - this._logger.setLevels(winston.config.syslog.levels); - } - if (Meteor.isClient) { - this._logger = console; - } + Constructor(logger) { + this._logger = logger; }, - setMinLevel(name) { - let newCode = this._levelCode(name); - if (this._minLevel !== newCode) { - this._minLevel = newCode; - if (Meteor.isServer) { - this._logger.transports.console.level = name; - } - } + addTransport() { + this._logger.add.apply(this._logger, arguments); }, start() { @@ -95,10 +70,3 @@ Space.Object.extend(Space, 'Logger', { } }); - -Space.log = new Space.Logger(); - -if (config.log.enabled) { - Space.log.setMinLevel(config.log.minLevel); - Space.log.start(); -} From 03aef7d4ea86e1e6940afb54caa4397c282f84da Mon Sep 17 00:00:00 2001 From: qejk Date: Tue, 19 Apr 2016 06:41:19 +0200 Subject: [PATCH 02/20] Refactors Space.Module to: not use global Space.log, instantiate underlying library for Space.Logger --- source/module.coffee | 57 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/source/module.coffee b/source/module.coffee index 32719e6..9214fb7 100644 --- a/source/module.coffee +++ b/source/module.coffee @@ -22,7 +22,12 @@ class Space.Module extends Space.Object return if not @is('constructed') # only initialize once if not @injector? then throw new Error @ERRORS.injectorMissing @_state = 'configuring' - Space.log.debug("#{@constructor.publishedAs}: initialize") + unless isSubModule + @log = @_setupLogger() + else + @log = @injector.get('log') + @log.debug("#{@constructor.publishedAs}: initialize") + # Setup basic mappings required by all modules if this the top-level module unless isSubModule @injector.map('Injector').to @injector @@ -114,7 +119,7 @@ class Space.Module extends Space.Object # calling the instance hooks before, on, and after _runLifeCycleAction: (action, func) -> @_invokeActionOnRequiredModules action - Space.log.debug("#{@constructor.publishedAs}: #{action}") + @log.debug("#{@constructor.publishedAs}: #{action}") this["before#{Space.capitalizeString(action)}"]?() func?() this["on#{Space.capitalizeString(action)}"]?() @@ -125,7 +130,7 @@ class Space.Module extends Space.Object @_invokeActionOnRequiredModules '_runOnInitializeHooks' # Never run this hook twice if @is('configuring') - Space.log.debug("#{@constructor.publishedAs}: onInitialize") + @log.debug("#{@constructor.publishedAs}: onInitialize") @_state = 'initializing' # Inject required dependencies into this module @injector.injectInto this @@ -135,7 +140,7 @@ class Space.Module extends Space.Object _autoMapSingletons: -> @_invokeActionOnRequiredModules '_autoMapSingletons' if @is('initializing') - Space.log.debug("#{@constructor.publishedAs}: _autoMapSingletons") + @log.debug("#{@constructor.publishedAs}: _autoMapSingletons") @_state = 'auto-mapping-singletons' # Map classes that are declared as singletons @injector.map(singleton).asSingleton() for singleton in @singletons @@ -143,7 +148,7 @@ class Space.Module extends Space.Object _autoCreateSingletons: -> @_invokeActionOnRequiredModules '_autoCreateSingletons' if @is('auto-mapping-singletons') - Space.log.debug("#{@constructor.publishedAs}: _autoCreateSingletons") + @log.debug("#{@constructor.publishedAs}: _autoCreateSingletons") @_state = 'auto-creating-singletons' # Create singleton classes @injector.create(singleton) for singleton in @singletons @@ -153,7 +158,7 @@ class Space.Module extends Space.Object @_invokeActionOnRequiredModules '_runAfterInitializeHooks' # Never run this hook twice if @is('auto-creating-singletons') - Space.log.debug("#{@constructor.publishedAs}: afterInitialize") + @log.debug("#{@constructor.publishedAs}: afterInitialize") @_state = 'initialized' # Call custom lifecycle hook if existant @afterInitialize?() @@ -165,11 +170,47 @@ class Space.Module extends Space.Object this[hook] ?= -> this[hook] = _.wrap(this[hook], wrapper) + _setupLogger: -> + config = Space.configuration.log + + if Meteor.isServer + type = 'winston' + lib = @_setupWinstonLogger(config) + if Meteor.isClient + type = 'console' + lib = console + + logger = new Space.Logger(lib) + @_setupLoggerTransports(type, logger) + logger.start() if config.enabled == true + return logger + + _setupWinstonLogger: (config) -> + winston = Npm.require('winston') + options = + colorize: true + prettyPrint: true + options.level = config.minLevel if config.minLevel? + + lib = new (winston.Logger)(transports: [ + new (winston.transports.Console)(options) + ]) + lib.setLevels winston.config.syslog.levels + return lib + + _setupLoggerTransports: (type, logger) -> + config = @constructor.prototype.configuration + transports = config.log?[type]?.transports + return unless transports + + for transport in transports + logger.addTransport.apply(logger, transport) + _mapSpaceServices: -> - @injector.map('log').to Space.log + @injector.map('log').toStaticValue(@log) _mapMeteorApis: -> - Space.log.debug("#{@constructor.publishedAs}: _mapMeteorApis") + @log.debug("#{@constructor.publishedAs}: _mapMeteorApis") # Map Meteor standard packages @injector.map('Meteor').to Meteor if Package.ejson? From dd32c4ed9154925515d283fc9c2cc327af1b53bb Mon Sep 17 00:00:00 2001 From: qejk Date: Sun, 24 Apr 2016 13:47:33 +0200 Subject: [PATCH 03/20] Moves temporarily Space.Logger code to coffeescript, adds support for multiple logging adapters in Space.Logger, adds adapter for console, winston logging libraries, wires everything up in module.coffee --- package.js | 10 +++- source/logger.coffee | 80 +++++++++++++++++++++++++++ source/logger.js | 72 ------------------------ source/loggers/adapter.js | 3 + source/loggers/console-adapter.coffee | 28 ++++++++++ source/loggers/winston-adapter.coffee | 33 +++++++++++ source/module.coffee | 43 +++++++------- 7 files changed, 176 insertions(+), 93 deletions(-) create mode 100644 source/logger.coffee delete mode 100644 source/logger.js create mode 100644 source/loggers/adapter.js create mode 100644 source/loggers/console-adapter.coffee create mode 100644 source/loggers/winston-adapter.coffee diff --git a/package.js b/package.js index 6ac3c4a..c398c96 100644 --- a/package.js +++ b/package.js @@ -42,15 +42,21 @@ Package.onUse(function(api) { 'source/helpers.coffee', 'source/configuration.js', 'source/object.coffee', - 'source/logger.js', + 'source/logger.coffee', 'source/struct.coffee', 'source/error.js', 'source/injector.coffee', 'source/injector_annotations.coffee', 'source/module.coffee', - 'source/application.coffee' + 'source/application.coffee', + 'source/loggers/adapter.js', + 'source/loggers/console-adapter.coffee', ]); + api.addFiles([ + 'source/loggers/winston-adapter.coffee', + ], 'server'); + // Test helpers api.addFiles([ 'source/testing/bdd-api.coffee' diff --git a/source/logger.coffee b/source/logger.coffee new file mode 100644 index 0000000..6a13732 --- /dev/null +++ b/source/logger.coffee @@ -0,0 +1,80 @@ +Space.Object.extend Space, 'Logger', + + _minLevel: 6 + + _state: 'stopped' + + _levels: + 'error': 3 + 'warning': 4 + 'warn': 4 + 'info': 6 + 'debug': 7 + + Constructor: -> + @_adapters = {} + + addAdapter: (id, adapter, override=false) -> + if not id? + throw new Error(@ERRORS.cannotMapUndefinedId()) + if @existsAdapter(id) and !override + throw new Error(@ERRORS.mappingExists(id)) + check(adapter, Space.Logger.Adapter) + @_adapters[id] = adapter + + overrideAdapter: (id, item) -> + @addAdapter(id, item, true) + + adapter: (id) -> + return @_adapters[id] or null + + existsAdapter: (id) -> + return (@_adapters[id]?) + + removeAdapter: (id) -> + delete @_adapters[id] if @_adapters[id] + + adapters: -> + return @_adapters + + start: -> + if @_is('stopped') + @_state = 'running' + + stop: -> + if @_is('running') + @_state = 'stopped' + + debug: (message) -> + @_log 'debug', arguments + + info: (message) -> + @_log 'info', arguments + + warning: (message) -> + if Meteor.isClient + @_log 'warn', arguments + if Meteor.isServer + @_log 'warning', arguments + + error: (message) -> + @_log 'error', arguments + + _levelCode: (name) -> + @_levels[name] + + _is: (expectedState) -> + if @_state == expectedState + return true + + _log: (level, message) -> + if @_is('running') and @_levelCode(level) <= @_minLevel + for id, adapter of @_adapters + adapter[level].apply adapter, message + + ERRORS: + cannotMapUndefinedId: -> + return "Cannot add adapter with or id" + mappingExists: (id) -> + return "Adapter with id <#{id}> would be overwritten. + Use method for that" \ No newline at end of file diff --git a/source/logger.js b/source/logger.js deleted file mode 100644 index 9ef664a..0000000 --- a/source/logger.js +++ /dev/null @@ -1,72 +0,0 @@ -Space.Object.extend(Space, 'Logger', { - - _logger: null, - _minLevel: 6, - _state: 'stopped', - - _levels: { - 'error': 3, - 'warning': 4, - 'warn': 4, - 'info': 6, - 'debug': 7 - }, - - Constructor(logger) { - this._logger = logger; - }, - - addTransport() { - this._logger.add.apply(this._logger, arguments); - }, - - start() { - if (this._is('stopped')) { - this._state = 'running'; - } - }, - - stop() { - if (this._is('running')) { - this._state = 'stopped'; - } - }, - - debug(message) { - check(message, String); - this._log('debug', arguments); - }, - - info(message) { - check(message, String); - this._log('info', arguments); - }, - - warning(message) { - check(message, String); - if (Meteor.isClient) - this._log('warn', arguments); - if (Meteor.isServer) - this._log('warning', arguments); - }, - - error(message) { - check(message, String); - this._log('error', arguments); - }, - - _levelCode(name) { - return this._levels[name]; - }, - - _is(expectedState) { - if (this._state === expectedState) return true; - }, - - _log(level, message) { - if(this._is('running') && this._levelCode(level) <= this._minLevel) { - this._logger[level].apply(this._logger, message); - } - } - -}); diff --git a/source/loggers/adapter.js b/source/loggers/adapter.js new file mode 100644 index 0000000..c67b531 --- /dev/null +++ b/source/loggers/adapter.js @@ -0,0 +1,3 @@ +Space.Object.extend('Space.Logger.Adapter', {}) + + diff --git a/source/loggers/console-adapter.coffee b/source/loggers/console-adapter.coffee new file mode 100644 index 0000000..8550d7e --- /dev/null +++ b/source/loggers/console-adapter.coffee @@ -0,0 +1,28 @@ +Space.Logger.Adapter.extend 'Space.Logger.ConsoleAdapter', + + _lib: null + + Constructor: (transports=[]) -> + @_lib = console + + addTransport: -> + @_lib.add.apply @_lib, arguments + + debug: (message) -> + check message, String + @_log 'debug', arguments + + info: (message) -> + check message, String + @_log 'info', arguments + + warning: (message) -> + check message, String + @_log 'warn', arguments + + error: (message) -> + check message, String + @_log 'error', arguments + + _log: (level, message) -> + @_lib[level].apply @_lib, message diff --git a/source/loggers/winston-adapter.coffee b/source/loggers/winston-adapter.coffee new file mode 100644 index 0000000..7d4c89d --- /dev/null +++ b/source/loggers/winston-adapter.coffee @@ -0,0 +1,33 @@ +winston = Npm.require('winston') + +Space.Logger.Adapter.extend 'Space.Logger.WinstonAdapter', + + _lib: null + + Constructor: (transports) -> + @_lib = new winston.Logger({ + transports: transports or [] + }) + @_lib.setLevels(winston.config.syslog.levels) + + addTransport: -> + @_lib.add.apply @_lib, arguments + + debug: (message) -> + check message, String + @_log 'debug', arguments + + info: (message) -> + check message, String + @_log 'info', arguments + + warning: (message) -> + check message, String + @_log 'warning', arguments + + error: (message) -> + check message, String + @_log 'error', arguments + + _log: (level, message) -> + @_lib[level].apply @_lib, message diff --git a/source/module.coffee b/source/module.coffee index 9214fb7..faa3e0b 100644 --- a/source/module.coffee +++ b/source/module.coffee @@ -174,37 +174,42 @@ class Space.Module extends Space.Object config = Space.configuration.log if Meteor.isServer + winston = Npm.require('winston') type = 'winston' - lib = @_setupWinstonLogger(config) + adapterClass = Space.Logger.WinstonAdapter + + unless @_hasCustomTransports(type) + defaultTransports = [ + new winston.transports.Console({ + colorize: true, + prettyPrint: true + }) + ] if Meteor.isClient type = 'console' - lib = console + adapterClass = Space.Logger.ConsoleAdapter + defaultTransports = [] - logger = new Space.Logger(lib) - @_setupLoggerTransports(type, logger) - logger.start() if config.enabled == true - return logger + adapter = new adapterClass(defaultTransports) + logger = new Space.Logger() + logger.addAdapter(type, adapter) - _setupWinstonLogger: (config) -> - winston = Npm.require('winston') - options = - colorize: true - prettyPrint: true - options.level = config.minLevel if config.minLevel? + @_setupAdapterTransports(type, adapter) + logger.start() if config.enabled == true - lib = new (winston.Logger)(transports: [ - new (winston.transports.Console)(options) - ]) - lib.setLevels winston.config.syslog.levels - return lib + return logger - _setupLoggerTransports: (type, logger) -> + _setupAdapterTransports: (type, adapter) -> config = @constructor.prototype.configuration transports = config.log?[type]?.transports return unless transports for transport in transports - logger.addTransport.apply(logger, transport) + adapter.addTransport.apply(adapter, transport) + + _hasCustomTransports: (type) -> + config = Space.configuration.log + return (config.log?[type]?.transports?) _mapSpaceServices: -> @injector.map('log').toStaticValue(@log) From 193f43b1ff61f11e90fd77a30e408bf519c8070d Mon Sep 17 00:00:00 2001 From: qejk Date: Sun, 24 Apr 2016 17:12:52 +0200 Subject: [PATCH 04/20] Refactors code: moves methods to base Space.Logger.Addapter class, adds setMinLevel, adds removable transports at winston adapter --- source/logger.coffee | 7 ++++ source/loggers/adapter.js | 49 ++++++++++++++++++++++++++- source/loggers/console-adapter.coffee | 28 +++------------ source/loggers/winston-adapter.coffee | 29 +++++----------- 4 files changed, 67 insertions(+), 46 deletions(-) diff --git a/source/logger.coffee b/source/logger.coffee index 6a13732..1de1b3c 100644 --- a/source/logger.coffee +++ b/source/logger.coffee @@ -60,6 +60,13 @@ Space.Object.extend Space, 'Logger', error: (message) -> @_log 'error', arguments + setMinLevel: (name) -> + newCode = @_levelCode(name) + if @_minLevel != newCode + @_minLevel = newCode + for id, adapter of @_adapters + adapter.setMinLevel(name) + _levelCode: (name) -> @_levels[name] diff --git a/source/loggers/adapter.js b/source/loggers/adapter.js index c67b531..992e5f4 100644 --- a/source/loggers/adapter.js +++ b/source/loggers/adapter.js @@ -1,3 +1,50 @@ -Space.Object.extend('Space.Logger.Adapter', {}) +Space.Object.extend('Space.Logger.Adapter', { + + _lib: null, + + debug(message) { + check(message, String); + this._log('debug', arguments); + }, + + info(message) { + check(message, String); + this._log('info', arguments); + }, + + warning(message) { + check(message, String); + this._log('warning', arguments); + }, + + error(message) { + check(message, String); + this._log('error', arguments); + }, + + setMinLevel(name) { + return; + }, + + setLib(lib) { + this._lib = lib; + }, + + lib() { + if (!this._lib) { + throw new Error(this.ERRORS.undefinedLib); + } + return this._lib; + }, + + _log(level, message) { + this._lib[level].apply(this._lib, message); + }, + + ERRORS: { + undefinedLib: 'Logging library is not set on adapter' + } + +}) diff --git a/source/loggers/console-adapter.coffee b/source/loggers/console-adapter.coffee index 8550d7e..1d1d94c 100644 --- a/source/loggers/console-adapter.coffee +++ b/source/loggers/console-adapter.coffee @@ -1,28 +1,8 @@ Space.Logger.Adapter.extend 'Space.Logger.ConsoleAdapter', - _lib: null - - Constructor: (transports=[]) -> - @_lib = console - - addTransport: -> - @_lib.add.apply @_lib, arguments - - debug: (message) -> - check message, String - @_log 'debug', arguments - - info: (message) -> - check message, String - @_log 'info', arguments + Constructor: () -> + @setLib(console) warning: (message) -> - check message, String - @_log 'warn', arguments - - error: (message) -> - check message, String - @_log 'error', arguments - - _log: (level, message) -> - @_lib[level].apply @_lib, message + check(message, String) + @_log('warn', arguments) diff --git a/source/loggers/winston-adapter.coffee b/source/loggers/winston-adapter.coffee index 7d4c89d..ea46965 100644 --- a/source/loggers/winston-adapter.coffee +++ b/source/loggers/winston-adapter.coffee @@ -2,32 +2,19 @@ winston = Npm.require('winston') Space.Logger.Adapter.extend 'Space.Logger.WinstonAdapter', - _lib: null - Constructor: (transports) -> - @_lib = new winston.Logger({ + lib = new winston.Logger({ transports: transports or [] }) - @_lib.setLevels(winston.config.syslog.levels) + lib.setLevels(winston.config.syslog.levels) + @setLib(lib) addTransport: -> @_lib.add.apply @_lib, arguments - debug: (message) -> - check message, String - @_log 'debug', arguments - - info: (message) -> - check message, String - @_log 'info', arguments - - warning: (message) -> - check message, String - @_log 'warning', arguments - - error: (message) -> - check message, String - @_log 'error', arguments + removeTransport: -> + @_lib.remove.apply @_lib, arguments - _log: (level, message) -> - @_lib[level].apply @_lib, message + setMinLevel: (name) -> + for id, transports of @_lib.transports + @_lib.transports[id].level = name \ No newline at end of file From c71872c601996a6786de3653473b82e4c984eba8 Mon Sep 17 00:00:00 2001 From: qejk Date: Sun, 24 Apr 2016 17:14:14 +0200 Subject: [PATCH 05/20] Adds default configuration from ENV to module configuration, sets minLevel on logger --- source/module.coffee | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/module.coffee b/source/module.coffee index faa3e0b..bdb7030 100644 --- a/source/module.coffee +++ b/source/module.coffee @@ -21,6 +21,7 @@ class Space.Module extends Space.Object initialize: (@app, @injector, isSubModule=false) -> return if not @is('constructed') # only initialize once if not @injector? then throw new Error @ERRORS.injectorMissing + @_setDefaultsToConfiguration(@configuration) @_state = 'configuring' unless isSubModule @log = @_setupLogger() @@ -115,6 +116,14 @@ class Space.Module extends Space.Object else return module + _setDefaultsToConfiguration: (configuration) -> + _.defaults(configuration, Space.getenv.multi({ + log: { + enabled: ['SPACE_LOG_ENABLED', false, 'bool'], + minLevel: ['SPACE_LOG_MIN_LEVEL', 'info', 'string'] + } + })) + # Invokes the lifecycle action on all required modules, then on itself, # calling the instance hooks before, on, and after _runLifeCycleAction: (action, func) -> @@ -193,6 +202,7 @@ class Space.Module extends Space.Object adapter = new adapterClass(defaultTransports) logger = new Space.Logger() logger.addAdapter(type, adapter) + logger.setMinLevel(config.minLevel) if config.minLevel? @_setupAdapterTransports(type, adapter) logger.start() if config.enabled == true From a778812b42e296a9b2d6ef711d19f79e77ed3c7d Mon Sep 17 00:00:00 2001 From: qejk Date: Sun, 24 Apr 2016 18:22:09 +0200 Subject: [PATCH 06/20] Refactors --- source/configuration.js | 33 ---------------- source/logger.coffee | 26 ++---------- source/loggers/adapter.js | 4 -- source/loggers/winston-adapter.coffee | 14 +++++-- source/module.coffee | 57 +++++++++++++++------------ 5 files changed, 47 insertions(+), 87 deletions(-) diff --git a/source/configuration.js b/source/configuration.js index 3c7095b..bd67ee2 100644 --- a/source/configuration.js +++ b/source/configuration.js @@ -4,37 +4,4 @@ if (Meteor.isServer) { let getenv = Npm.require('getenv'); // Wrapper Space.getenv = getenv; - - Space.configuration = Space.getenv.multi({ - log: { - enabled: ['SPACE_LOG_ENABLED', false, 'bool'], - minLevel: ['SPACE_LOG_MIN_LEVEL', 'info', 'string'] - } - }); - - // Pass down to the client - _.deepExtend(Meteor.settings, { - public: { - log: { - enabled: Space.configuration.log.enabled, - minLevel: Space.configuration.log.minLevel - } - } - }); - - __meteor_runtime_config__.PUBLIC_SETTINGS = Meteor.settings.public; - -} - -if (Meteor.isClient) { - - let log = Meteor.settings.public.log; - - // Guard and defaults when not loaded on server - Space.configuration = { - log: { - enabled: log && log.enabled || false, - minLevel: log && log.minLevel || 'info' - } - }; } diff --git a/source/logger.coffee b/source/logger.coffee index 1de1b3c..4993195 100644 --- a/source/logger.coffee +++ b/source/logger.coffee @@ -1,16 +1,7 @@ Space.Object.extend Space, 'Logger', - _minLevel: 6 - _state: 'stopped' - _levels: - 'error': 3 - 'warning': 4 - 'warn': 4 - 'info': 6 - 'debug': 7 - Constructor: -> @_adapters = {} @@ -60,24 +51,15 @@ Space.Object.extend Space, 'Logger', error: (message) -> @_log 'error', arguments - setMinLevel: (name) -> - newCode = @_levelCode(name) - if @_minLevel != newCode - @_minLevel = newCode - for id, adapter of @_adapters - adapter.setMinLevel(name) - - _levelCode: (name) -> - @_levels[name] - _is: (expectedState) -> if @_state == expectedState return true _log: (level, message) -> - if @_is('running') and @_levelCode(level) <= @_minLevel - for id, adapter of @_adapters - adapter[level].apply adapter, message + return unless @_is('running') + + for id, adapter of @_adapters + adapter[level].apply adapter, message ERRORS: cannotMapUndefinedId: -> diff --git a/source/loggers/adapter.js b/source/loggers/adapter.js index 992e5f4..4ac1377 100644 --- a/source/loggers/adapter.js +++ b/source/loggers/adapter.js @@ -22,10 +22,6 @@ Space.Object.extend('Space.Logger.Adapter', { this._log('error', arguments); }, - setMinLevel(name) { - return; - }, - setLib(lib) { this._lib = lib; }, diff --git a/source/loggers/winston-adapter.coffee b/source/loggers/winston-adapter.coffee index ea46965..62bc5b7 100644 --- a/source/loggers/winston-adapter.coffee +++ b/source/loggers/winston-adapter.coffee @@ -15,6 +15,14 @@ Space.Logger.Adapter.extend 'Space.Logger.WinstonAdapter', removeTransport: -> @_lib.remove.apply @_lib, arguments - setMinLevel: (name) -> - for id, transports of @_lib.transports - @_lib.transports[id].level = name \ No newline at end of file + hasTransport: (name) -> + return @_lib.transports[transportName]? + + setMinLevel: (transportName, levelName) -> + unless @hasTransport(transportName) + throw new Error(@ERRORS.transportNotAdded(transportName)) + @_lib.transports[transportName].level = levelName + + ERRORS: + transportNotAdded: (transportName) -> + return "Winston transport with #{transportName} is not added" \ No newline at end of file diff --git a/source/module.coffee b/source/module.coffee index bdb7030..48aad55 100644 --- a/source/module.coffee +++ b/source/module.coffee @@ -21,7 +21,7 @@ class Space.Module extends Space.Object initialize: (@app, @injector, isSubModule=false) -> return if not @is('constructed') # only initialize once if not @injector? then throw new Error @ERRORS.injectorMissing - @_setDefaultsToConfiguration(@configuration) + @_setDefaultsOnConfiguration(@configuration) @_state = 'configuring' unless isSubModule @log = @_setupLogger() @@ -116,11 +116,14 @@ class Space.Module extends Space.Object else return module - _setDefaultsToConfiguration: (configuration) -> - _.defaults(configuration, Space.getenv.multi({ + _setDefaultsOnConfiguration: (configuration) -> + _.extend(configuration, Space.getenv.multi({ log: { enabled: ['SPACE_LOG_ENABLED', false, 'bool'], - minLevel: ['SPACE_LOG_MIN_LEVEL', 'info', 'string'] + console: { + enabled: ['SPACE_CONSOLE_LOG_ENABLED', false, 'bool'], + minLevel: ['SPACE_CONSOLE_LOG_MIN_LEVEL', 'info', 'string'] + } } })) @@ -180,46 +183,50 @@ class Space.Module extends Space.Object this[hook] = _.wrap(this[hook], wrapper) _setupLogger: -> - config = Space.configuration.log + config = @constructor.prototype.configuration.log or {} + defaultTransports = [] if Meteor.isServer - winston = Npm.require('winston') - type = 'winston' + adapterName = 'winston' adapterClass = Space.Logger.WinstonAdapter + unless @_areCustomAdapterTransportsConfigured(adapterName, config) + defaultTransports = @_getDefaultTransportsForWinston(config) - unless @_hasCustomTransports(type) - defaultTransports = [ - new winston.transports.Console({ - colorize: true, - prettyPrint: true - }) - ] if Meteor.isClient - type = 'console' + adapterName = 'console' adapterClass = Space.Logger.ConsoleAdapter - defaultTransports = [] adapter = new adapterClass(defaultTransports) logger = new Space.Logger() - logger.addAdapter(type, adapter) - logger.setMinLevel(config.minLevel) if config.minLevel? + logger.addAdapter(adapterName, adapter) - @_setupAdapterTransports(type, adapter) + @_setupAdapterTransports(adapterName, adapter, config) logger.start() if config.enabled == true return logger - _setupAdapterTransports: (type, adapter) -> - config = @constructor.prototype.configuration - transports = config.log?[type]?.transports + _setupAdapterTransports: (adapterName, adapter, config) -> + transports = config[adapterName]?.transports return unless transports for transport in transports adapter.addTransport.apply(adapter, transport) - _hasCustomTransports: (type) -> - config = Space.configuration.log - return (config.log?[type]?.transports?) + _getDefaultTransportsForWinston: (config) -> + winston = Npm.require('winston') + defaultTransports = [] + + if config.console?.enabled + options = + colorize: true + prettyPrint: true + options.level = config.console.minLevel if config.console?.minLevel? + defaultTransports.push(new winston.transports.Console(options)) + + return defaultTransports + + _areCustomAdapterTransportsConfigured: (adapterName, config) -> + return (config[adapterName]?.transports?) _mapSpaceServices: -> @injector.map('log').toStaticValue(@log) From c8ea9ea547673c5b4b597aaf7094507250b87950 Mon Sep 17 00:00:00 2001 From: qejk Date: Tue, 26 Apr 2016 09:48:34 +0200 Subject: [PATCH 07/20] Removes blank lines --- source/configuration.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/configuration.js b/source/configuration.js index bd67ee2..29f1c53 100644 --- a/source/configuration.js +++ b/source/configuration.js @@ -1,6 +1,4 @@ - if (Meteor.isServer) { - let getenv = Npm.require('getenv'); // Wrapper Space.getenv = getenv; From 89420548febc9ca7f73789d7fc295485b0576835 Mon Sep 17 00:00:00 2001 From: qejk Date: Tue, 26 Apr 2016 09:53:50 +0200 Subject: [PATCH 08/20] Moves instantiation of console transport to Space.Logger.WinstonAdapter --- source/loggers/winston-adapter.coffee | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source/loggers/winston-adapter.coffee b/source/loggers/winston-adapter.coffee index 62bc5b7..b7d1d6c 100644 --- a/source/loggers/winston-adapter.coffee +++ b/source/loggers/winston-adapter.coffee @@ -1,6 +1,6 @@ winston = Npm.require('winston') -Space.Logger.Adapter.extend 'Space.Logger.WinstonAdapter', +Space.Logger.WinstonAdapter = Space.Logger.Adapter.extend 'Space.Logger.WinstonAdapter', Constructor: (transports) -> lib = new winston.Logger({ @@ -25,4 +25,14 @@ Space.Logger.Adapter.extend 'Space.Logger.WinstonAdapter', ERRORS: transportNotAdded: (transportName) -> - return "Winston transport with #{transportName} is not added" \ No newline at end of file + return "Winston transport with #{transportName} is not added" + +Space.Logger.WinstonAdapter.console = (options) -> + unless options? + options = + colorize: true + prettyPrint: true + level: 'info' + + return new winston.transports.Console(options) + From 64f90e0bff5f83fff04f841aa024b4ae75fe902b Mon Sep 17 00:00:00 2001 From: qejk Date: Tue, 26 Apr 2016 09:54:43 +0200 Subject: [PATCH 09/20] Simplifies initialization of transports, adds dedicated method for preparing logging configuration --- source/module.coffee | 76 +++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/source/module.coffee b/source/module.coffee index 48aad55..eb6392f 100644 --- a/source/module.coffee +++ b/source/module.coffee @@ -21,7 +21,7 @@ class Space.Module extends Space.Object initialize: (@app, @injector, isSubModule=false) -> return if not @is('constructed') # only initialize once if not @injector? then throw new Error @ERRORS.injectorMissing - @_setDefaultsOnConfiguration(@configuration) + @_state = 'configuring' unless isSubModule @log = @_setupLogger() @@ -116,17 +116,6 @@ class Space.Module extends Space.Object else return module - _setDefaultsOnConfiguration: (configuration) -> - _.extend(configuration, Space.getenv.multi({ - log: { - enabled: ['SPACE_LOG_ENABLED', false, 'bool'], - console: { - enabled: ['SPACE_CONSOLE_LOG_ENABLED', false, 'bool'], - minLevel: ['SPACE_CONSOLE_LOG_MIN_LEVEL', 'info', 'string'] - } - } - })) - # Invokes the lifecycle action on all required modules, then on itself, # calling the instance hooks before, on, and after _runLifeCycleAction: (action, func) -> @@ -183,50 +172,63 @@ class Space.Module extends Space.Object this[hook] = _.wrap(this[hook], wrapper) _setupLogger: -> - config = @constructor.prototype.configuration.log or {} - defaultTransports = [] + if Meteor.isServer + config = @_loggingConfig(@configuration) + else + config = {} + transports = [] if Meteor.isServer adapterName = 'winston' adapterClass = Space.Logger.WinstonAdapter - unless @_areCustomAdapterTransportsConfigured(adapterName, config) - defaultTransports = @_getDefaultTransportsForWinston(config) + transports = config.winston?.transports or [] if Meteor.isClient adapterName = 'console' adapterClass = Space.Logger.ConsoleAdapter - adapter = new adapterClass(defaultTransports) + adapter = new adapterClass(transports) logger = new Space.Logger() logger.addAdapter(adapterName, adapter) - - @_setupAdapterTransports(adapterName, adapter, config) logger.start() if config.enabled == true return logger - _setupAdapterTransports: (adapterName, adapter, config) -> - transports = config[adapterName]?.transports - return unless transports - - for transport in transports - adapter.addTransport.apply(adapter, transport) + _loggingConfig: () -> + config = {} + _.deepExtend(config, Space.getenv.multi({ + log: { + enabled: ['SPACE_LOG_ENABLED', false, 'bool'], + winston: { + console: { + enabled: ['SPACE_CONSOLE_LOG_ENABLED', false, 'bool'], + minLevel: ['SPACE_CONSOLE_LOG_MIN_LEVEL', 'info', 'string'] + } + } + } + })) + _.deepExtend(config, @configuration) + _.deepExtend(config, @constructor.prototype.configuration) - _getDefaultTransportsForWinston: (config) -> - winston = Npm.require('winston') - defaultTransports = [] + winstonCfg = config.log?.winston or {} - if config.console?.enabled - options = - colorize: true - prettyPrint: true - options.level = config.console.minLevel if config.console?.minLevel? - defaultTransports.push(new winston.transports.Console(options)) + if _.isEmpty(winstonCfg.transports) and winstonCfg.console.enabled == true + _.deepExtend(config, log: { + winston: { + transports: [@_setupWinstonConsoleTransport( + winstonCfg.console.minLevel + )] + } + }) - return defaultTransports + return config.log or {} - _areCustomAdapterTransportsConfigured: (adapterName, config) -> - return (config[adapterName]?.transports?) + _setupWinstonConsoleTransport: (minLevel) -> + options = + colorize: true + prettyPrint: true + options.level = minLevel if minLevel? + return Space.Logger.WinstonAdapter.console(options) _mapSpaceServices: -> @injector.map('log').toStaticValue(@log) From 462bfef3be3647bbf368c77eca0aac4230c102be Mon Sep 17 00:00:00 2001 From: qejk Date: Tue, 26 Apr 2016 21:17:08 +0200 Subject: [PATCH 10/20] Removes winston npm dependency --- .npm/package/npm-shrinkwrap.json | 26 ------------------ package.js | 7 +---- source/loggers/winston-adapter.coffee | 38 --------------------------- 3 files changed, 1 insertion(+), 70 deletions(-) delete mode 100644 source/loggers/winston-adapter.coffee diff --git a/.npm/package/npm-shrinkwrap.json b/.npm/package/npm-shrinkwrap.json index 21e3e9c..58c8671 100644 --- a/.npm/package/npm-shrinkwrap.json +++ b/.npm/package/npm-shrinkwrap.json @@ -2,32 +2,6 @@ "dependencies": { "getenv": { "version": "0.5.0" - }, - "winston": { - "version": "2.1.0", - "dependencies": { - "async": { - "version": "1.0.0" - }, - "colors": { - "version": "1.0.3" - }, - "cycle": { - "version": "1.0.3" - }, - "eyes": { - "version": "0.1.8" - }, - "isstream": { - "version": "0.1.2" - }, - "pkginfo": { - "version": "0.3.1" - }, - "stack-trace": { - "version": "0.0.9" - } - } } } } diff --git a/package.js b/package.js index c398c96..b93eadb 100644 --- a/package.js +++ b/package.js @@ -7,8 +7,7 @@ Package.describe({ }); Npm.depends({ - "getenv": "0.5.0", - "winston": "2.1.0" + "getenv": "0.5.0" }); Package.onUse(function(api) { @@ -53,10 +52,6 @@ Package.onUse(function(api) { 'source/loggers/console-adapter.coffee', ]); - api.addFiles([ - 'source/loggers/winston-adapter.coffee', - ], 'server'); - // Test helpers api.addFiles([ 'source/testing/bdd-api.coffee' diff --git a/source/loggers/winston-adapter.coffee b/source/loggers/winston-adapter.coffee deleted file mode 100644 index b7d1d6c..0000000 --- a/source/loggers/winston-adapter.coffee +++ /dev/null @@ -1,38 +0,0 @@ -winston = Npm.require('winston') - -Space.Logger.WinstonAdapter = Space.Logger.Adapter.extend 'Space.Logger.WinstonAdapter', - - Constructor: (transports) -> - lib = new winston.Logger({ - transports: transports or [] - }) - lib.setLevels(winston.config.syslog.levels) - @setLib(lib) - - addTransport: -> - @_lib.add.apply @_lib, arguments - - removeTransport: -> - @_lib.remove.apply @_lib, arguments - - hasTransport: (name) -> - return @_lib.transports[transportName]? - - setMinLevel: (transportName, levelName) -> - unless @hasTransport(transportName) - throw new Error(@ERRORS.transportNotAdded(transportName)) - @_lib.transports[transportName].level = levelName - - ERRORS: - transportNotAdded: (transportName) -> - return "Winston transport with #{transportName} is not added" - -Space.Logger.WinstonAdapter.console = (options) -> - unless options? - options = - colorize: true - prettyPrint: true - level: 'info' - - return new winston.transports.Console(options) - From dc4914f2e7e822b939798176e6a9e69a80a6ab93 Mon Sep 17 00:00:00 2001 From: qejk Date: Tue, 26 Apr 2016 21:18:04 +0200 Subject: [PATCH 11/20] Simplifies logging initialization by moving it to separate modules contained in additional packages --- source/module.coffee | 49 +------------------------------------------- 1 file changed, 1 insertion(+), 48 deletions(-) diff --git a/source/module.coffee b/source/module.coffee index eb6392f..8be9175 100644 --- a/source/module.coffee +++ b/source/module.coffee @@ -172,64 +172,17 @@ class Space.Module extends Space.Object this[hook] = _.wrap(this[hook], wrapper) _setupLogger: -> - if Meteor.isServer - config = @_loggingConfig(@configuration) - else - config = {} - - transports = [] - if Meteor.isServer - adapterName = 'winston' - adapterClass = Space.Logger.WinstonAdapter - transports = config.winston?.transports or [] - - if Meteor.isClient - adapterName = 'console' - adapterClass = Space.Logger.ConsoleAdapter - - adapter = new adapterClass(transports) + config = @_loggingConfig(@configuration) logger = new Space.Logger() - logger.addAdapter(adapterName, adapter) logger.start() if config.enabled == true - return logger _loggingConfig: () -> config = {} - _.deepExtend(config, Space.getenv.multi({ - log: { - enabled: ['SPACE_LOG_ENABLED', false, 'bool'], - winston: { - console: { - enabled: ['SPACE_CONSOLE_LOG_ENABLED', false, 'bool'], - minLevel: ['SPACE_CONSOLE_LOG_MIN_LEVEL', 'info', 'string'] - } - } - } - })) _.deepExtend(config, @configuration) _.deepExtend(config, @constructor.prototype.configuration) - - winstonCfg = config.log?.winston or {} - - if _.isEmpty(winstonCfg.transports) and winstonCfg.console.enabled == true - _.deepExtend(config, log: { - winston: { - transports: [@_setupWinstonConsoleTransport( - winstonCfg.console.minLevel - )] - } - }) - return config.log or {} - _setupWinstonConsoleTransport: (minLevel) -> - options = - colorize: true - prettyPrint: true - options.level = minLevel if minLevel? - return Space.Logger.WinstonAdapter.console(options) - _mapSpaceServices: -> @injector.map('log').toStaticValue(@log) From a48baa34719d947b7226498b8aea6fcaa1cfeaca Mon Sep 17 00:00:00 2001 From: qejk Date: Tue, 26 Apr 2016 21:39:10 +0200 Subject: [PATCH 12/20] Moves coffeescript to ES6 /cry --- package.js | 4 +- source/logger.coffee | 69 ----------------- source/logger.js | 102 ++++++++++++++++++++++++++ source/loggers/adapter.js | 4 +- source/loggers/console-adapter.coffee | 8 -- source/loggers/console-adapter.js | 12 +++ 6 files changed, 117 insertions(+), 82 deletions(-) delete mode 100644 source/logger.coffee create mode 100644 source/logger.js delete mode 100644 source/loggers/console-adapter.coffee create mode 100644 source/loggers/console-adapter.js diff --git a/package.js b/package.js index b93eadb..e7d1340 100644 --- a/package.js +++ b/package.js @@ -41,7 +41,7 @@ Package.onUse(function(api) { 'source/helpers.coffee', 'source/configuration.js', 'source/object.coffee', - 'source/logger.coffee', + 'source/logger.js', 'source/struct.coffee', 'source/error.js', 'source/injector.coffee', @@ -49,7 +49,7 @@ Package.onUse(function(api) { 'source/module.coffee', 'source/application.coffee', 'source/loggers/adapter.js', - 'source/loggers/console-adapter.coffee', + 'source/loggers/console-adapter.js', ]); // Test helpers diff --git a/source/logger.coffee b/source/logger.coffee deleted file mode 100644 index 4993195..0000000 --- a/source/logger.coffee +++ /dev/null @@ -1,69 +0,0 @@ -Space.Object.extend Space, 'Logger', - - _state: 'stopped' - - Constructor: -> - @_adapters = {} - - addAdapter: (id, adapter, override=false) -> - if not id? - throw new Error(@ERRORS.cannotMapUndefinedId()) - if @existsAdapter(id) and !override - throw new Error(@ERRORS.mappingExists(id)) - check(adapter, Space.Logger.Adapter) - @_adapters[id] = adapter - - overrideAdapter: (id, item) -> - @addAdapter(id, item, true) - - adapter: (id) -> - return @_adapters[id] or null - - existsAdapter: (id) -> - return (@_adapters[id]?) - - removeAdapter: (id) -> - delete @_adapters[id] if @_adapters[id] - - adapters: -> - return @_adapters - - start: -> - if @_is('stopped') - @_state = 'running' - - stop: -> - if @_is('running') - @_state = 'stopped' - - debug: (message) -> - @_log 'debug', arguments - - info: (message) -> - @_log 'info', arguments - - warning: (message) -> - if Meteor.isClient - @_log 'warn', arguments - if Meteor.isServer - @_log 'warning', arguments - - error: (message) -> - @_log 'error', arguments - - _is: (expectedState) -> - if @_state == expectedState - return true - - _log: (level, message) -> - return unless @_is('running') - - for id, adapter of @_adapters - adapter[level].apply adapter, message - - ERRORS: - cannotMapUndefinedId: -> - return "Cannot add adapter with or id" - mappingExists: (id) -> - return "Adapter with id <#{id}> would be overwritten. - Use method for that" \ No newline at end of file diff --git a/source/logger.js b/source/logger.js new file mode 100644 index 0000000..3c71640 --- /dev/null +++ b/source/logger.js @@ -0,0 +1,102 @@ +Space.Object.extend('Space.Logger', { + + _state: 'stopped', + + Constructor() { + return this._adapters = {}; + }, + + addAdapter(id, adapter, override) { + if (override == null) { + let override = false; + } + if (id == null) { + throw new Error(this.ERRORS.cannotMapUndefinedId()); + } + if (this.existsAdapter(id) && !override) { + throw new Error(this.ERRORS.mappingExists(id)); + } + check(adapter, Space.Logger.Adapter); + return this._adapters[id] = adapter; + }, + + overrideAdapter(id, item) { + return this.addAdapter(id, item, true); + }, + + adapter(id) { + return this._adapters[id] || null; + }, + + existsAdapter(id) { + return (this._adapters[id] != null); + }, + + removeAdapter(id) { + if (this._adapters[id]) { + return delete this._adapters[id]; + } + }, + + adapters() { + return this._adapters; + }, + + start() { + if (this._is('stopped')) { + return this._state = 'running'; + } + }, + + stop() { + if (this._is('running')) { + return this._state = 'stopped'; + } + }, + + debug(message) { + return this._log('debug', arguments); + }, + + info(message) { + return this._log('info', arguments); + }, + + warning(message) { + if (Meteor.isClient) { + this._log('warn', arguments); + } + if (Meteor.isServer) { + return this._log('warning', arguments); + } + }, + + error(message) { + return this._log('error', arguments); + }, + + _is(expectedState) { + if (this._state === expectedState) { + return true; + } + }, + + _log(level, message) { + if (!this._is('running')) { + return; + } + + _.each(this._adapters, function(adapter, id) { + adapter[level].apply(adapter, message); + }); + }, + + ERRORS: { + cannotMapUndefinedId() { + return "Cannot add adapter with or id"; + }, + mappingExists(id) { + return `Adapter with id <${id}> would be overwritten. Use method for that`; + } + } +}); diff --git a/source/loggers/adapter.js b/source/loggers/adapter.js index 4ac1377..e6e6f66 100644 --- a/source/loggers/adapter.js +++ b/source/loggers/adapter.js @@ -41,6 +41,4 @@ Space.Object.extend('Space.Logger.Adapter', { undefinedLib: 'Logging library is not set on adapter' } -}) - - +}); \ No newline at end of file diff --git a/source/loggers/console-adapter.coffee b/source/loggers/console-adapter.coffee deleted file mode 100644 index 1d1d94c..0000000 --- a/source/loggers/console-adapter.coffee +++ /dev/null @@ -1,8 +0,0 @@ -Space.Logger.Adapter.extend 'Space.Logger.ConsoleAdapter', - - Constructor: () -> - @setLib(console) - - warning: (message) -> - check(message, String) - @_log('warn', arguments) diff --git a/source/loggers/console-adapter.js b/source/loggers/console-adapter.js new file mode 100644 index 0000000..5b86444 --- /dev/null +++ b/source/loggers/console-adapter.js @@ -0,0 +1,12 @@ +Space.Logger.Adapter.extend('Space.Logger.ConsoleAdapter', { + + Constructor() { + return this.setLib(console); + }, + + warning(message) { + check(message, String); + return this._log('warn', arguments); + } + +}); \ No newline at end of file From 0cd08c66d2bc32a47baeaf3f3c508d75aa093114 Mon Sep 17 00:00:00 2001 From: qejk Date: Sat, 7 May 2016 05:01:53 +0200 Subject: [PATCH 13/20] Removes unnecessary variable --- source/configuration.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/configuration.js b/source/configuration.js index 29f1c53..35ec25a 100644 --- a/source/configuration.js +++ b/source/configuration.js @@ -1,5 +1,3 @@ if (Meteor.isServer) { - let getenv = Npm.require('getenv'); - // Wrapper - Space.getenv = getenv; + Space.getenv = Npm.require('getenv'); } From e5a071acb6d0244b424c9d44870547ee6c12fd1e Mon Sep 17 00:00:00 2001 From: qejk Date: Sat, 7 May 2016 05:02:37 +0200 Subject: [PATCH 14/20] Adds state related additional helper methods to Space.Logger --- source/logger.js | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/source/logger.js b/source/logger.js index 3c71640..be47339 100644 --- a/source/logger.js +++ b/source/logger.js @@ -1,8 +1,12 @@ Space.Object.extend('Space.Logger', { - _state: 'stopped', + STATES: { + stopped: 'stopped', + running: 'running' + }, Constructor() { + this._state = this.STATES.stopped; return this._adapters = {}; }, @@ -10,9 +14,7 @@ Space.Object.extend('Space.Logger', { if (override == null) { let override = false; } - if (id == null) { - throw new Error(this.ERRORS.cannotMapUndefinedId()); - } + check(id, String); if (this.existsAdapter(id) && !override) { throw new Error(this.ERRORS.mappingExists(id)); } @@ -43,14 +45,14 @@ Space.Object.extend('Space.Logger', { }, start() { - if (this._is('stopped')) { - return this._state = 'running'; + if (this._is(this.STATES.stopped)) { + return this._state = this.STATES.running; } }, stop() { - if (this._is('running')) { - return this._state = 'stopped'; + if (this._is(this.STATES.running)) { + return this._state = this.STATES.stopped;; } }, @@ -63,12 +65,7 @@ Space.Object.extend('Space.Logger', { }, warning(message) { - if (Meteor.isClient) { - this._log('warn', arguments); - } - if (Meteor.isServer) { - return this._log('warning', arguments); - } + return this._log('warning', arguments); }, error(message) { @@ -76,13 +73,19 @@ Space.Object.extend('Space.Logger', { }, _is(expectedState) { - if (this._state === expectedState) { - return true; - } + return (this._state === expectedState); + }, + + isRunning() { + return this._is(this.STATES.running); + }, + + isStopped() { + return this._is(this.STATES.stopped); }, _log(level, message) { - if (!this._is('running')) { + if (!this._is(this.STATES.running)) { return; } @@ -92,9 +95,6 @@ Space.Object.extend('Space.Logger', { }, ERRORS: { - cannotMapUndefinedId() { - return "Cannot add adapter with or id"; - }, mappingExists(id) { return `Adapter with id <${id}> would be overwritten. Use method for that`; } From e06d2644d87049064f9bf7956ff76e6296121d9d Mon Sep 17 00:00:00 2001 From: qejk Date: Sat, 7 May 2016 05:03:04 +0200 Subject: [PATCH 15/20] Changes injector mapping type --- source/module.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/module.coffee b/source/module.coffee index 8be9175..4000f80 100644 --- a/source/module.coffee +++ b/source/module.coffee @@ -184,7 +184,7 @@ class Space.Module extends Space.Object return config.log or {} _mapSpaceServices: -> - @injector.map('log').toStaticValue(@log) + @injector.map('log').to @log _mapMeteorApis: -> @log.debug("#{@constructor.publishedAs}: _mapMeteorApis") From 37cafb0c31e6a3593889342c733e3ff968aeedaa Mon Sep 17 00:00:00 2001 From: qejk Date: Sat, 7 May 2016 05:03:25 +0200 Subject: [PATCH 16/20] Fixes module unit tests --- tests/unit/module.unit.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/unit/module.unit.coffee b/tests/unit/module.unit.coffee index 859ad5f..ea64987 100644 --- a/tests/unit/module.unit.coffee +++ b/tests/unit/module.unit.coffee @@ -103,6 +103,7 @@ describe 'Space.Module - #start', -> beforeEach -> @module = new Space.Module() + @module.log = {debug: sinon.spy()} @module.start() @module._runLifeCycleAction = sinon.spy() @@ -117,6 +118,7 @@ describe 'Space.Module - #stop', -> beforeEach -> @module = new Space.Module() + @module.log = {debug: sinon.spy()} @module.start() @module.stop() @module._runLifeCycleAction = sinon.spy() @@ -132,6 +134,7 @@ describe 'Space.Module - #reset', -> beforeEach -> @module = new Space.Module() + @module.log = {debug: sinon.spy()} @module._runLifeCycleAction = sinon.spy() it.server 'rejects attempts to reset when in production', -> From 319b5916d36c61fcb3ec55231ad64a89f09cd6d0 Mon Sep 17 00:00:00 2001 From: qejk Date: Sat, 7 May 2016 05:03:42 +0200 Subject: [PATCH 17/20] Refactors Space.Logger unit tests --- tests/unit/logger.tests.js | 267 +++++++++++++++++++++++++------------ 1 file changed, 181 insertions(+), 86 deletions(-) diff --git a/tests/unit/logger.tests.js b/tests/unit/logger.tests.js index acab9e7..0f6416c 100644 --- a/tests/unit/logger.tests.js +++ b/tests/unit/logger.tests.js @@ -1,112 +1,207 @@ -describe("Space.Logger", function() { +Space.Logger.Adapter.extend('TestAdapter', { + Constructor(lib) { + return this.setLib(lib); + }, +}); - beforeEach(function() { - this.log = new Space.Logger(); - }); +describe("Space.Logger", () => { - afterEach(function() { - this.log.stop(); + beforeEach(() => { + this.testLib = { + debug: sinon.spy(), + info: sinon.spy(), + warning: sinon.spy(), + error: sinon.spy() + }; + this.testAdapter = new TestAdapter(this.testLib); + this.log = new Space.Logger(); }); - it('extends Space.Object', function() { + it('extends Space.Object', () => { expect(Space.Logger).to.extend(Space.Object); }); - it("is available of both client and server", function() { + it("is available of both client and server", () => { if (Meteor.isServer || Meteor.isClient) expect(this.log).to.be.instanceOf(Space.Logger); }); - it("only logs after starting", function() { - this.log.start(); - this.log._logger.info = sinon.spy(); - let message = 'My Log Message'; - this.log.info(message); - expect(this.log._logger.info).to.be.calledWithExactly(message); - }); + describe('adapters', () => { + it('throws error if adding adapter without string id', () => { + const adapter = new TestAdapter(sinon.spy()); - it("it can log a debug message to the output channel when min level is equal but not less", function() { - this.log.start(); - this.log.setMinLevel('debug'); - this.log._logger.debug = sinon.spy(); - let message = 'My log message'; - this.log.debug(message); - expect(this.log._logger.debug).to.be.calledWithExactly(message); - this.log._logger.debug = sinon.spy(); - this.log.setMinLevel('info'); - this.log.debug(message); - expect(this.log._logger.debug).not.to.be.called; + const addAdapter = () => this.log.addAdapter(undefined, adapter); + expect(addAdapter).to.throw(Error); + }); + + it('throws error if adding adapter with non-string id', () => { + const adapter = new TestAdapter(sinon.spy()); + + const addAdapter = () => this.log.addAdapter(adapter); + expect(addAdapter).to.throw(Error); + }); + + it('throws error if adding would override adapter', () => { + const adapterId = 'testAdapter'; + const adapter = new TestAdapter(sinon.spy()); + + this.log.addAdapter(adapterId, adapter); + const overrideAdapter = () => this.log.addAdapter(adapterId, adapter); + expect(overrideAdapter).to.throw( + Space.Logger.prototype.ERRORS.mappingExists(adapterId) + ) + }); + + it('throws error if adding adapter without string id', () => { + const adapter = new TestAdapter(sinon.spy()); + + const addAdapter = () => this.log.addAdapter(undefined, adapter); + expect(addAdapter).to.throw(Error); + }); + + it('adds adapter', () => { + const adapterId = 'testAdapter'; + const adapter = new TestAdapter(sinon.spy()); + + this.log.addAdapter(adapterId, adapter); + expect(this.log.adapter(adapterId)).to.equal(adapter); + expect(this.log.existsAdapter(adapterId)).to.be.true; + }); + + it('overrides adapter', () => { + const adapterId = 'testAdapter'; + const adapter = new TestAdapter(sinon.spy()); + const overridingAdapter = new TestAdapter(sinon.spy()); + + this.log.addAdapter(adapterId, adapter); + const overrideAdapter = () => { + this.log.overrideAdapter(adapterId, overridingAdapter); + } + expect(overrideAdapter).to.not.throw(Error); + expect(this.log.adapter(adapterId)).to.equal(overridingAdapter); + }); + + it('resolves adapter by id', () => { + consoleAdapter = new TestAdapter(sinon.spy()); + fileAdapter = new TestAdapter(sinon.spy()); + + this.log.addAdapter('console', consoleAdapter); + this.log.addAdapter('file', fileAdapter); + expect(this.log.adapter('console')).to.equal(consoleAdapter); + expect(this.log.adapter('file')).to.equal(fileAdapter); + expect(this.log.adapter('totallyNotFakeAdapter')).to.be.null; + }); + + it('removes adapter', () => { + const adapterId = 'testAdapter'; + const adapter = new TestAdapter(sinon.spy()); + + this.log.addAdapter(adapterId, adapter); + this.log.removeAdapter(adapterId); + expect(this.log.adapter(adapterId)).to.be.null; + expect(this.log.existsAdapter(adapterId)).to.be.false; + }); + + it('returns adapters', () => { + const adapters = { + console: new TestAdapter(sinon.spy()), + file: new TestAdapter(sinon.spy()) + } + this.log.addAdapter('console', adapters['console']); + this.log.addAdapter('file', adapters['file']); + expect(this.log.adapters()).to.include(adapters); + }); }); - it("it can log an info message to the output channel when min level is equal or higher, but not less", function() { - this.log.start(); - this.log.setMinLevel('info'); - this.log._logger.info = sinon.spy(); - this.log._logger.debug = sinon.spy(); - let message = 'My log message'; - this.log.info(message); - expect(this.log._logger.info).to.be.calledWithExactly(message); - expect(this.log._logger.debug).not.to.be.called; - this.log._logger.info = sinon.spy(); - this.log.setMinLevel('warning'); + it("only logs after starting", () => { + this.log.addAdapter('test', this.testAdapter) + const message = 'My log message'; + + expect(this.log.isRunning()).to.be.false; + expect(this.log.isStopped()).to.be.true; this.log.info(message); - expect(this.log._logger.info).not.to.be.called; - }); + expect(this.testLib.info.calledWith(message)).to.not.true; - it.server("it can log a warning message to the output channel when min level is equal or higher, but not less", function() { this.log.start(); - this.log.setMinLevel('warning'); - this.log._logger.warning = sinon.spy(); - this.log._logger.info = sinon.spy(); - let message = 'My log message'; - this.log.warning(message); - expect(this.log._logger.warning).to.be.calledWithExactly(message); - expect(this.log._logger.info).not.to.be.called; - this.log._logger.warning = sinon.spy(); - this.log.setMinLevel('error'); - this.log.warning(message); - expect(this.log._logger.warning).not.to.be.called; + expect(this.log.isRunning()).to.be.true; + expect(this.log.isStopped()).to.be.false; + this.log.info(message); + expect(this.testLib.info.calledWith(message)).to.be.true; }); - it.client("it can log a warning message to the output channel when min level is equal or higher, but not less", function() { - this.log.start(); - this.log.setMinLevel('warning'); - this.log._logger.warn = sinon.spy(); - this.log._logger.info = sinon.spy(); - let message = 'My log message'; - this.log.warning(message); - expect(this.log._logger.warn).to.be.calledWithExactly(message); - expect(this.log._logger.info).not.to.be.called; - this.log._logger.warn = sinon.spy(); - this.log.setMinLevel('error'); - this.log.warning(message); - expect(this.log._logger.warn).not.to.be.called; - }); + it("allows logging output to be stopped", () => { + this.log.addAdapter('test', this.testAdapter) + const message = 'My log message'; - it("it can log an error message to the output channel when min level is equal", function() { - this.log.start(); - this.log.setMinLevel('error'); - this.log._logger.error = sinon.spy(); - this.log._logger.info = sinon.spy(); - let message = 'My log message'; - this.log.error(message); - expect(this.log._logger.error).to.be.calledWithExactly(message); - expect(this.log._logger.info).not.to.be.called; - this.log._logger.info = sinon.spy(); - this.log.setMinLevel('debug'); - this.log.error(message); - expect(this.log._logger.error).to.be.calledWithExactly(message); - }); + expect(this.log.isRunning()).to.be.false; + expect(this.log.isStopped()).to.be.true; + this.log.start() + expect(this.log.isRunning()).to.be.true; + expect(this.log.isStopped()).to.be.false; + this.log.info(message); + expect(this.testLib.info.calledWith(message)).to.be.true; - it("allows logging output to be stopped", function() { - this.log._logger.info = sinon.spy(); - this.log.start(); - expect(this.log._is('running')).to.be.true; this.log.stop(); - let message = 'My Log Message'; + expect(this.log.isRunning()).to.be.false; + expect(this.log.isStopped()).to.be.true; + this.log.info(message); - expect(this.log._logger.info).not.to.be.called; - expect(this.log._is('stopped')).to.be.true; + expect(this.testLib.info).to.not.be.calledTwice; }); + describe('logging', () => { + it('allows multiple logging adapters to log same message', () => { + const firstLib = {debug: sinon.spy()}; + const firstAdapter = new TestAdapter(firstLib); + const secondLib = {debug: sinon.spy()}; + const secondAdapter = new TestAdapter(secondLib); + const message = 'My log message'; + + this.log.addAdapter('first', firstAdapter); + this.log.addAdapter('second', secondAdapter); + this.log.start(); + + this.log.debug(message); + expect(firstLib.debug.calledWith(message)).to.be.true; + expect(secondLib.debug.calledWith(message)).to.be.true; + }); + + describe('logs message as', () => { + it("debug", () => { + this.log.addAdapter('test', this.testAdapter); + this.log.start(); + + const message = 'My log message'; + this.log.debug(message); + expect(this.testLib.debug.calledWith(message)).to.be.true; + }); + + it("info", () => { + this.log.addAdapter('test', this.testAdapter); + this.log.start(); + + const message = 'My log message'; + this.log.info(message); + expect(this.testLib.info.calledWith(message)).to.be.true; + }); + + it("warning", () => { + this.log.addAdapter('test', this.testAdapter); + this.log.start(); + + const message = 'My log message'; + this.log.warning(message); + expect(this.testLib.warning.calledWith(message)).to.be.true; + }); + + it("error", () => { + this.log.addAdapter('test', this.testAdapter); + this.log.start(); + + const message = 'My log message'; + this.log.error(message); + expect(this.testLib.error.calledWith(message)).to.be.true; + }); + }); + }); }); From fa9c2dc44a749f733c35fe8bf21d3720d918c200 Mon Sep 17 00:00:00 2001 From: qejk Date: Sat, 7 May 2016 05:11:41 +0200 Subject: [PATCH 18/20] One semicolon here, one semicolon there... --- source/logger.js | 2 +- tests/unit/logger.tests.js | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/source/logger.js b/source/logger.js index be47339..b9b7aae 100644 --- a/source/logger.js +++ b/source/logger.js @@ -52,7 +52,7 @@ Space.Object.extend('Space.Logger', { stop() { if (this._is(this.STATES.running)) { - return this._state = this.STATES.stopped;; + return this._state = this.STATES.stopped; } }, diff --git a/tests/unit/logger.tests.js b/tests/unit/logger.tests.js index 0f6416c..3902bcd 100644 --- a/tests/unit/logger.tests.js +++ b/tests/unit/logger.tests.js @@ -49,7 +49,7 @@ describe("Space.Logger", () => { const overrideAdapter = () => this.log.addAdapter(adapterId, adapter); expect(overrideAdapter).to.throw( Space.Logger.prototype.ERRORS.mappingExists(adapterId) - ) + ); }); it('throws error if adding adapter without string id', () => { @@ -76,7 +76,7 @@ describe("Space.Logger", () => { this.log.addAdapter(adapterId, adapter); const overrideAdapter = () => { this.log.overrideAdapter(adapterId, overridingAdapter); - } + }; expect(overrideAdapter).to.not.throw(Error); expect(this.log.adapter(adapterId)).to.equal(overridingAdapter); }); @@ -106,15 +106,15 @@ describe("Space.Logger", () => { const adapters = { console: new TestAdapter(sinon.spy()), file: new TestAdapter(sinon.spy()) - } - this.log.addAdapter('console', adapters['console']); - this.log.addAdapter('file', adapters['file']); + }; + this.log.addAdapter('console', adapters.console); + this.log.addAdapter('file', adapters.file); expect(this.log.adapters()).to.include(adapters); }); }); it("only logs after starting", () => { - this.log.addAdapter('test', this.testAdapter) + this.log.addAdapter('test', this.testAdapter); const message = 'My log message'; expect(this.log.isRunning()).to.be.false; @@ -130,12 +130,12 @@ describe("Space.Logger", () => { }); it("allows logging output to be stopped", () => { - this.log.addAdapter('test', this.testAdapter) + this.log.addAdapter('test', this.testAdapter); const message = 'My log message'; expect(this.log.isRunning()).to.be.false; expect(this.log.isStopped()).to.be.true; - this.log.start() + this.log.start(); expect(this.log.isRunning()).to.be.true; expect(this.log.isStopped()).to.be.false; this.log.info(message); From d886a5bd9059a98da494e476ae53968cd469ca6f Mon Sep 17 00:00:00 2001 From: qejk Date: Sat, 7 Jan 2017 04:10:28 +0100 Subject: [PATCH 19/20] Removes back winston dependency from meteor --- package.js | 1 - 1 file changed, 1 deletion(-) diff --git a/package.js b/package.js index ebfffbf..36bb3aa 100644 --- a/package.js +++ b/package.js @@ -8,7 +8,6 @@ Package.describe({ Npm.depends({ "getenv": "0.5.0", - "winston": "2.1.0", "babel-plugin-transform-decorators-legacy": "1.3.4" }); From cbb3ca56cc549769ee2faeb503e82825ffadae52 Mon Sep 17 00:00:00 2001 From: qejk Date: Sat, 7 Jan 2017 04:17:27 +0100 Subject: [PATCH 20/20] Refactors Logger --- source/logger.js | 90 +++++++------- source/loggers/adapter.js | 48 ++++---- source/loggers/console-adapter.js | 14 ++- tests/unit/logger.tests.js | 188 +++++++++++++++--------------- 4 files changed, 168 insertions(+), 172 deletions(-) diff --git a/source/logger.js b/source/logger.js index b9b7aae..d28ea89 100644 --- a/source/logger.js +++ b/source/logger.js @@ -1,4 +1,4 @@ -Space.Object.extend('Space.Logger', { +const Logger = Space.Object.extend('Space.Logger', { STATES: { stopped: 'stopped', @@ -7,96 +7,94 @@ Space.Object.extend('Space.Logger', { Constructor() { this._state = this.STATES.stopped; - return this._adapters = {}; + this._adapters = {}; }, - addAdapter(id, adapter, override) { - if (override == null) { - let override = false; + addAdapter(id, adapter, shouldOverride = false) { + if (!id || typeof id !== 'string') { + throw new Error(this.constructor.ERRORS.invalidId); } - check(id, String); - if (this.existsAdapter(id) && !override) { - throw new Error(this.ERRORS.mappingExists(id)); + if (this.hasAdapter(id) && !shouldOverride) { + throw new Error(this.constructor.ERRORS.mappingExists(id)); } - check(adapter, Space.Logger.Adapter); - return this._adapters[id] = adapter; + this._adapters[id] = adapter; }, - overrideAdapter(id, item) { - return this.addAdapter(id, item, true); + overrideAdapter(id, adapter) { + return this.addAdapter(id, adapter, true); }, - adapter(id) { + getAdapter(id) { return this._adapters[id] || null; }, - existsAdapter(id) { - return (this._adapters[id] != null); + hasAdapter(id) { + return (this._adapters[id] !== null && this._adapters[id] !== undefined); }, removeAdapter(id) { - if (this._adapters[id]) { - return delete this._adapters[id]; - } + if (this._adapters[id]) {delete this._adapters[id];} }, - adapters() { + getAdapters() { return this._adapters; }, start() { - if (this._is(this.STATES.stopped)) { - return this._state = this.STATES.running; + if (this.isInState(this.STATES.stopped)) { + this._state = this.STATES.running; } }, stop() { - if (this._is(this.STATES.running)) { - return this._state = this.STATES.stopped; + if (this.isInState(this.STATES.running)) { + this._state = this.STATES.stopped; } }, - debug(message) { - return this._log('debug', arguments); + debug(...args) { + this._log('debug', args); }, - info(message) { - return this._log('info', arguments); + info(...args) { + this._log('info', args); }, - warning(message) { - return this._log('warning', arguments); + warning(...args) { + this._log('warning', args); }, - error(message) { - return this._log('error', arguments); + error(...args) { + this._log('error', args); }, - _is(expectedState) { + isInState(expectedState) { return (this._state === expectedState); }, isRunning() { - return this._is(this.STATES.running); + return this.isInState(this.STATES.running); }, isStopped() { - return this._is(this.STATES.stopped); + return this.isInState(this.STATES.stopped); }, - _log(level, message) { - if (!this._is(this.STATES.running)) { - return; - } - - _.each(this._adapters, function(adapter, id) { - adapter[level].apply(adapter, message); - }); - }, + _log(level, args) { + if (!this.isInState(this.STATES.running)) {return;} - ERRORS: { - mappingExists(id) { - return `Adapter with id <${id}> would be overwritten. Use method for that`; + for (let adapter of Object.values(this.getAdapters())) { + adapter[level].apply(adapter, args); } } }); + +Logger.ERRORS = { + mappingExists(id) { + return `Adapter with id '${id}' would be overwritten. Use method + 'overrideAdapter' for that`; + }, + invalidId: 'Cannot map or or non string values' +}; + +export default Logger; diff --git a/source/loggers/adapter.js b/source/loggers/adapter.js index e6e6f66..6a10d66 100644 --- a/source/loggers/adapter.js +++ b/source/loggers/adapter.js @@ -1,44 +1,44 @@ -Space.Object.extend('Space.Logger.Adapter', { +const LoggingAdapter = Space.Object.extend('Space.Logger.LoggingAdapter', { _lib: null, + Constructor(lib) { + if (!lib) { + throw new Error(this.ERRORS.undefinedLibrary); + } + this.setLibrary(lib); + }, - debug(message) { - check(message, String); - this._log('debug', arguments); + setLibrary(lib) { + this._lib = lib; }, - info(message) { - check(message, String); - this._log('info', arguments); + getLibrary() { + return this._lib || null; }, - warning(message) { - check(message, String); - this._log('warning', arguments); + debug(...args) { + this._log('debug', args); }, - error(message) { - check(message, String); - this._log('error', arguments); + info(...args) { + this._log('info', args); }, - setLib(lib) { - this._lib = lib; + warning(...args) { + this._log('warning', args); }, - lib() { - if (!this._lib) { - throw new Error(this.ERRORS.undefinedLib); - } - return this._lib; + error(...args) { + this._log('error', args); }, - _log(level, message) { - this._lib[level].apply(this._lib, message); + _log(level, args) { + this._lib[level].apply(this._lib, args); }, ERRORS: { - undefinedLib: 'Logging library is not set on adapter' + undefinedLibrary: 'Logging library is required' } +}); -}); \ No newline at end of file +export default LoggingAdapter; diff --git a/source/loggers/console-adapter.js b/source/loggers/console-adapter.js index 5b86444..4d28e0a 100644 --- a/source/loggers/console-adapter.js +++ b/source/loggers/console-adapter.js @@ -1,12 +1,14 @@ -Space.Logger.Adapter.extend('Space.Logger.ConsoleAdapter', { +import LoggingAdapter from './adapter'; + +const ConsoleLogger = LoggingAdapter.extend('Space.Logger.ConsoleAdapter', { Constructor() { - return this.setLib(console); + LoggingAdapter.call(this, console); }, - warning(message) { - check(message, String); - return this._log('warn', arguments); + warning(...args) { + return this._log('warn', args); } +}); -}); \ No newline at end of file +export default ConsoleLogger; diff --git a/tests/unit/logger.tests.js b/tests/unit/logger.tests.js index 3902bcd..475e925 100644 --- a/tests/unit/logger.tests.js +++ b/tests/unit/logger.tests.js @@ -1,105 +1,98 @@ -Space.Logger.Adapter.extend('TestAdapter', { +import Logger from '../../source/logger.js'; +import LoggingAdapter from '../../source/loggers/adapter.js'; + +const TestAdapter = LoggingAdapter.extend('TestAdapter', { Constructor(lib) { - return this.setLib(lib); - }, + return this.setLibrary(lib); + } }); -describe("Space.Logger", () => { +describe("Logger", function() { beforeEach(() => { - this.testLib = { + this.lib = { debug: sinon.spy(), info: sinon.spy(), warning: sinon.spy(), error: sinon.spy() }; - this.testAdapter = new TestAdapter(this.testLib); - this.log = new Space.Logger(); + this.testAdapter = new TestAdapter(this.lib); + this.logger = new Logger(); }); it('extends Space.Object', () => { - expect(Space.Logger).to.extend(Space.Object); + expect(Logger).to.extend(Space.Object); }); it("is available of both client and server", () => { - if (Meteor.isServer || Meteor.isClient) - expect(this.log).to.be.instanceOf(Space.Logger); + expect(this.logger).to.be.instanceOf(Logger); }); describe('adapters', () => { - it('throws error if adding adapter without string id', () => { + it('throws error if id does not exists', () => { const adapter = new TestAdapter(sinon.spy()); - - const addAdapter = () => this.log.addAdapter(undefined, adapter); - expect(addAdapter).to.throw(Error); + expect(() => this.logger.addAdapter(undefined, adapter)).to.throw( + Logger.ERRORS.invalidId + ); }); - it('throws error if adding adapter with non-string id', () => { + it('throws error if id is not a string value', () => { const adapter = new TestAdapter(sinon.spy()); - - const addAdapter = () => this.log.addAdapter(adapter); - expect(addAdapter).to.throw(Error); + expect(() => this.logger.addAdapter(adapter)).to.throw( + Logger.ERRORS.invalidId + ); }); - it('throws error if adding would override adapter', () => { + it('throws error if adapter would be overridden', () => { const adapterId = 'testAdapter'; const adapter = new TestAdapter(sinon.spy()); - this.log.addAdapter(adapterId, adapter); - const overrideAdapter = () => this.log.addAdapter(adapterId, adapter); - expect(overrideAdapter).to.throw( - Space.Logger.prototype.ERRORS.mappingExists(adapterId) + this.logger.addAdapter(adapterId, adapter); + expect(() => this.logger.addAdapter(adapterId, adapter)).to.throw( + Logger.ERRORS.mappingExists(adapterId) ); }); - it('throws error if adding adapter without string id', () => { - const adapter = new TestAdapter(sinon.spy()); - - const addAdapter = () => this.log.addAdapter(undefined, adapter); - expect(addAdapter).to.throw(Error); - }); - it('adds adapter', () => { const adapterId = 'testAdapter'; const adapter = new TestAdapter(sinon.spy()); - this.log.addAdapter(adapterId, adapter); - expect(this.log.adapter(adapterId)).to.equal(adapter); - expect(this.log.existsAdapter(adapterId)).to.be.true; + this.logger.addAdapter(adapterId, adapter); + expect(this.logger.getAdapter(adapterId)).to.equal(adapter); + expect(this.logger.hasAdapter(adapterId)).to.be.true; }); - it('overrides adapter', () => { + it('allows to override adapter', () => { const adapterId = 'testAdapter'; const adapter = new TestAdapter(sinon.spy()); const overridingAdapter = new TestAdapter(sinon.spy()); - this.log.addAdapter(adapterId, adapter); - const overrideAdapter = () => { - this.log.overrideAdapter(adapterId, overridingAdapter); - }; - expect(overrideAdapter).to.not.throw(Error); - expect(this.log.adapter(adapterId)).to.equal(overridingAdapter); + this.logger.addAdapter(adapterId, adapter); + expect(() => { + this.logger.overrideAdapter(adapterId, overridingAdapter); + }).to.not.throw(Error); + expect(this.logger.getAdapter(adapterId)).to.equal(overridingAdapter); }); it('resolves adapter by id', () => { consoleAdapter = new TestAdapter(sinon.spy()); fileAdapter = new TestAdapter(sinon.spy()); - this.log.addAdapter('console', consoleAdapter); - this.log.addAdapter('file', fileAdapter); - expect(this.log.adapter('console')).to.equal(consoleAdapter); - expect(this.log.adapter('file')).to.equal(fileAdapter); - expect(this.log.adapter('totallyNotFakeAdapter')).to.be.null; + this.logger.addAdapter('console', consoleAdapter); + this.logger.addAdapter('file', fileAdapter); + expect(this.logger.getAdapter('console')).to.equal(consoleAdapter); + expect(this.logger.getAdapter('file')).to.equal(fileAdapter); + expect(this.logger.getAdapter('non-existing-adapter')).to.be.null; }); it('removes adapter', () => { const adapterId = 'testAdapter'; const adapter = new TestAdapter(sinon.spy()); - this.log.addAdapter(adapterId, adapter); - this.log.removeAdapter(adapterId); - expect(this.log.adapter(adapterId)).to.be.null; - expect(this.log.existsAdapter(adapterId)).to.be.false; + this.logger.addAdapter(adapterId, adapter); + this.logger.removeAdapter(adapterId); + expect(this.logger.getAdapter(adapterId)).to.be.null; + expect(this.logger.hasAdapter(adapterId)).to.be.false; }); it('returns adapters', () => { @@ -107,46 +100,47 @@ describe("Space.Logger", () => { console: new TestAdapter(sinon.spy()), file: new TestAdapter(sinon.spy()) }; - this.log.addAdapter('console', adapters.console); - this.log.addAdapter('file', adapters.file); - expect(this.log.adapters()).to.include(adapters); + this.logger.addAdapter('console', adapters.console); + this.logger.addAdapter('file', adapters.file); + expect(this.logger.getAdapters()).to.be.eql(adapters); }); }); it("only logs after starting", () => { - this.log.addAdapter('test', this.testAdapter); + this.logger.addAdapter('my-logger', this.testAdapter); const message = 'My log message'; - expect(this.log.isRunning()).to.be.false; - expect(this.log.isStopped()).to.be.true; - this.log.info(message); - expect(this.testLib.info.calledWith(message)).to.not.true; - - this.log.start(); - expect(this.log.isRunning()).to.be.true; - expect(this.log.isStopped()).to.be.false; - this.log.info(message); - expect(this.testLib.info.calledWith(message)).to.be.true; + expect(this.logger.isRunning()).to.be.false; + expect(this.logger.isStopped()).to.be.true; + this.logger.info(message); + expect(this.lib.info).to.not.be.called; + + this.logger.start(); + expect(this.logger.isRunning()).to.be.true; + expect(this.logger.isStopped()).to.be.false; + this.logger.info(message); + expect(this.lib.info).to.be.calledOnce; + expect(this.lib.info.calledWith(message)).to.be.true; }); it("allows logging output to be stopped", () => { - this.log.addAdapter('test', this.testAdapter); + this.logger.addAdapter('my-logger', this.testAdapter); const message = 'My log message'; - expect(this.log.isRunning()).to.be.false; - expect(this.log.isStopped()).to.be.true; - this.log.start(); - expect(this.log.isRunning()).to.be.true; - expect(this.log.isStopped()).to.be.false; - this.log.info(message); - expect(this.testLib.info.calledWith(message)).to.be.true; + expect(this.logger.isRunning()).to.be.false; + expect(this.logger.isStopped()).to.be.true; + this.logger.start(); + expect(this.logger.isRunning()).to.be.true; + expect(this.logger.isStopped()).to.be.false; + this.logger.info(message); + expect(this.lib.info.calledWith(message)).to.be.true; - this.log.stop(); - expect(this.log.isRunning()).to.be.false; - expect(this.log.isStopped()).to.be.true; + this.logger.stop(); + expect(this.logger.isRunning()).to.be.false; + expect(this.logger.isStopped()).to.be.true; - this.log.info(message); - expect(this.testLib.info).to.not.be.calledTwice; + this.logger.info(message); + expect(this.lib.info).to.not.be.calledTwice; }); describe('logging', () => { @@ -157,50 +151,52 @@ describe("Space.Logger", () => { const secondAdapter = new TestAdapter(secondLib); const message = 'My log message'; - this.log.addAdapter('first', firstAdapter); - this.log.addAdapter('second', secondAdapter); - this.log.start(); + this.logger.addAdapter('first', firstAdapter); + this.logger.addAdapter('second', secondAdapter); + this.logger.start(); - this.log.debug(message); + this.logger.debug(message); expect(firstLib.debug.calledWith(message)).to.be.true; + expect(firstLib.debug).to.be.calledOnce; expect(secondLib.debug.calledWith(message)).to.be.true; + expect(secondLib.debug).to.be.calledOnce; }); describe('logs message as', () => { it("debug", () => { - this.log.addAdapter('test', this.testAdapter); - this.log.start(); + this.logger.addAdapter('my-logger', this.testAdapter); + this.logger.start(); const message = 'My log message'; - this.log.debug(message); - expect(this.testLib.debug.calledWith(message)).to.be.true; + this.logger.debug(message); + expect(this.lib.debug.calledWith(message)).to.be.true; }); it("info", () => { - this.log.addAdapter('test', this.testAdapter); - this.log.start(); + this.logger.addAdapter('my-logger', this.testAdapter); + this.logger.start(); const message = 'My log message'; - this.log.info(message); - expect(this.testLib.info.calledWith(message)).to.be.true; + this.logger.info(message); + expect(this.lib.info.calledWith(message)).to.be.true; }); it("warning", () => { - this.log.addAdapter('test', this.testAdapter); - this.log.start(); + this.logger.addAdapter('my-logger', this.testAdapter); + this.logger.start(); const message = 'My log message'; - this.log.warning(message); - expect(this.testLib.warning.calledWith(message)).to.be.true; + this.logger.warning(message); + expect(this.lib.warning.calledWith(message)).to.be.true; }); it("error", () => { - this.log.addAdapter('test', this.testAdapter); - this.log.start(); + this.logger.addAdapter('my-logger', this.testAdapter); + this.logger.start(); const message = 'My log message'; - this.log.error(message); - expect(this.testLib.error.calledWith(message)).to.be.true; + this.logger.error(message); + expect(this.lib.error.calledWith(message)).to.be.true; }); }); });