Skip to content

Commit

Permalink
Issue #23: WIP serialization
Browse files Browse the repository at this point in the history
- currently broken
- processors report trusted keys on logger construct
- but senders, which use them, are created before processors
  • Loading branch information
fgm committed Mar 6, 2017
1 parent 771e16c commit 8e1a534
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 11 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

### 0.1.12

- LeveledStrategy.constructor() no longer accepts non-Senders as sender arguments.
* Messages are now stored serialized by default in MongoDB too, not just Syslog (#23).
* LeveledStrategy.constructor() no longer accepts non-Senders as sender arguments.
* Logger.log() no longer accepts invalid log levels (#26), to match PSR-3.
* Loggers no longer modify the message context (#25).
* Removed incorrect `readme` clause in `package.json`.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"scripts": {
"compile": "rm -r lib/* ; npm i && babel --presets es2015,stage-0 -d lib/ src/",
"doc": "rm -fr out ; jsdoc -c jsdoc.json",
"test": "npm run test-compile && time -p mocha --compilers js:babel-core/register test/*",
"test": "npm run test-compile && time -p mocha --compilers js:babel-core/register test/unit/* -w",
"test-compile": "time -p babel --presets es2015,stage-0 -d lib/ src/",
"test-integration": "npm run test-compile && time -p mocha --compilers js:babel-core/register test/integration",
"test-unit": "npm run test-compile && time -p mocha --compilers js:babel-core/register test/unit"
Expand Down
33 changes: 29 additions & 4 deletions src/Logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,17 @@ const Logger = class {
*
* @param {StrategyBase} strategy
* The sender selection strategy to apply.
* @param {Processor[]} processors
* An array of processor instances.
*/
constructor(strategy) {
this.processors = [];
constructor(strategy, processors) {
this.processors = processors;
this.strategy = strategy;
this.tk = TraceKit;

this.formatOptions = {
trustedKeys: this.processors.reduce(this.processorTrustReducer, [])
};
this.strategy.customizeLogger(this);
}

Expand Down Expand Up @@ -132,6 +137,24 @@ const Logger = class {
return result;
}

/**
* Reduce callback for processor trust.
*
* @see Logger.constructor()
*
* @param {Object} accu
* The reduction accumulator.
* @param {ProcessorBase} current
* The current process to apply in the reduction.
*
* @returns {Object}
* The result of the current reduction step.
*/
processorTrustReducer(accu, current) {
const result = [...accu, ...current.getTrustedKeys()];
return result;
}

/**
* Log an event. This is the *MAIN* method in the whole package.
*
Expand All @@ -145,7 +168,9 @@ const Logger = class {
* @param {Object} rawContext
* (Optional). An object complementing the message.
* @param {Boolean} cooked
* (Optional). Is the context already reduced ?
* (Optional). Is the context already reduced ? This is typically the case
* on the server logger when it comes from the client logger: it should not
* usually be set by the user.
*
* @returns {void}
*
Expand All @@ -169,7 +194,7 @@ const Logger = class {

const senders = this.strategy.selectSenders(level, message, context);
senders.forEach(sender => {
sender.send(level, message, context);
sender.send(level, message, context, this.formatOptions);
});
}

Expand Down
6 changes: 6 additions & 0 deletions src/Processors/BrowserProcessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ const BrowserProcessor = class extends ProcessorBase {
}
}

/** @inheritdoc */
getTrustedKeys() {
return ['browser'];
}


/**
* The only required method for processor implementations.
*
Expand Down
5 changes: 5 additions & 0 deletions src/Processors/MeteorUserProcessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ const MeteorUserProcessor = class extends ProcessorBase {
return result;
}

/** @inheritdoc */
getTrustedKeys() {
return ['meteor'];
}

/**
* Return the current user information, as far as possible.
*
Expand Down
12 changes: 12 additions & 0 deletions src/Processors/ProcessorBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* It exists only to document the processor interface.
*/
const ProcessorBase = class {

/**
* The only required method for processor implementations.
*
Expand All @@ -23,6 +24,17 @@ const ProcessorBase = class {
process(context) {
return context;
}

/**
* Provide the list of context keys this processor recommends not serializing.
*
* @returns {Array}
* An array of context keys which will not be serialized by default if this
* processor is involved.
*/
getTrustedKeys() {
return [];
}
};

export default ProcessorBase;
5 changes: 5 additions & 0 deletions src/Processors/RoutingProcessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ const RoutingProcessor = class extends ProcessorBase {
}
}

/** @inheritdoc */
getTrustedKeys() {
return ['routing'];
}

/**
* Overwrite any previous routing information in context.
*
Expand Down
21 changes: 18 additions & 3 deletions src/Senders/MongodbSender.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/**
* @fileOverview MongoDB Sender class.
*/

import * as util from "util";
import SenderBase from "./SenderBase";

/**
Expand All @@ -17,8 +19,10 @@ const MongodbSender = class extends SenderBase {
* The Meteor Mongo service.
* @param {(String|Collection)} collection
* The collection or the name of the collection in which to log.
* @param {Object} formatOptions
* Optional : The options used to format the message (default to { depth: 5 }).
*/
constructor(mongo, collection = "logger") {
constructor(mongo, collection = "logger", formatOptions = null) {
super();
if (collection instanceof mongo.Collection) {
this.store = collection;
Expand All @@ -30,19 +34,30 @@ const MongodbSender = class extends SenderBase {
else {
throw new Error("MongodbSender requires a Collection or a collection name");
}

this.formatOptions = formatOptions || {
depth: 5,
rawKeys: []
};
}

send(level, message, context) {
let defaultedContext = context || {};
let doc = { level, message };
let doc = {level, message};

// It should contain a timestamp object if it comes from ClientLogger.
if (typeof defaultedContext.timestamp === "undefined") {
defaultedContext.timestamp = {};
}
doc.context = defaultedContext;
doc.context.timestamp.store = Date.now();
this.store.insert(doc);
try {
this.store.insert(doc);
}
catch (e) {
doc.context = util.inspect(doc, this.formatOptions);
this.store.insert(doc);
}
}
};

Expand Down
8 changes: 6 additions & 2 deletions src/ServerLogger.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import * as util from "util";
*
* Its main method is log(level, message, context).
*
* @extends Logger
*
* @see ServerLogger.log
*/
class ServerLogger extends Logger {
Expand All @@ -18,14 +20,16 @@ class ServerLogger extends Logger {
*
* @param {StrategyBase} strategy
* A logging strategy instance.
* @param {Processor[]} processors
* An array of processor instances.
* @param {Webapp} webapp
* The Meteor WebApp service.
* @param {Object} parameters
* - logRequestHeaders: add request headers to the log context. Defaults to true.
* - servePath: the path on which to expose the logger endpoint. Defaults to "/logger".
*/
constructor(strategy, webapp = null, parameters = {}) {
super(strategy);
constructor(strategy, processors, webapp = null, parameters = {}) {
super(strategy, processors);
const defaultParameters = {
logRequestHeaders: true,
servePath: "/logger"
Expand Down

0 comments on commit 8e1a534

Please sign in to comment.