Node example with Realm and Express/Winston to demonstrate interprocess communication.

This commit is contained in:
Adam Fish 2016-11-15 12:57:35 +01:00
parent c8e4dc39c0
commit 6b6b2fa11a
5 changed files with 142 additions and 0 deletions

View File

@ -0,0 +1,22 @@
# Realm-JS Interprocess Example
Small example of interprocess support with Realm and Node.js
The example makes use of [Winston](https://github.com/winstonjs/winston), a
logging library, and includes `winston-realm.js` which defines a custom transport
utilizing Realm for storage. The main file, `index.js` is a basic
[Express](https://github.com/expressjs/express) app. The app listens on port
3000 and responds with "Hello World!" at the base path `/` and logs at `info`
"Handled Hello World" to Winston. At any other path it returns a `404` error and
logs an error message to Winston with URL in question.
Since the log messages are being stored in a Realm (`winston.realm`), we can
listen for changes on another process. The `listener.js` is a small example of
this. When running, this listens to the `winston.realm` for changes and writes
to the console the latest error level log message.
To test:
1. `npm install`
2. `node .` to run the Express app
3. In another process: `node listener.js`
4. Go to `http://localhost:3000/whatever` to see error message across processes

View File

@ -0,0 +1,25 @@
var express = require('express'),
util = require('util'),
winston = require('winston');
RealmWinston = require('./winston-realm').Realm;
var app = express();
// Use custom Winston transport: RealmWinston
// Writes log data to winston.realm
winston.add(RealmWinston, {});
app.get('/', function (req, res) {
res.send('Hello World!');
winston.info('Handled Hello World');
});
app.use(function (req, res, next) {
res.status(404).send('Sorry can not find that!');
winston.error('404 Error at: ' + req.url);
})
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});

View File

@ -0,0 +1,16 @@
'use strict';
var Realm = require('realm');
let winstonRealm = new Realm({
path: 'winston.realm'
});
// Register listener to print out log messages at error level
winstonRealm.objects('Log').filtered('level = "error"').addListener((logs, changes) => {
changes.insertions.map((index) => {
let log = logs[index];
console.log(log.message);
})
});

View File

@ -0,0 +1,17 @@
{
"name": "winston-realm-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"express": "^4.14.0",
"winston": "^2.3.0"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

View File

@ -0,0 +1,62 @@
'use strict';
var util = require('util'),
winston = require('winston'),
Realm = require('realm');
var RealmLogger = exports.Realm = function (options) {
winston.Transport.call(this, options);
//
// Configure the Realm`
//
let LogSchema = {
name: 'Log',
properties: {
level: 'string',
message: 'string',
timestamp: 'date',
}
};
this.realm = new Realm({
path: 'winston.realm',
schema: [LogSchema]
});
};
//
// Inherit from `winston.Transport` so you can take advantage
// of the base functionality and `.handleExceptions()`.
//
util.inherits(RealmLogger, winston.Transport);
//
// Expose the name of this Transport on the prototype
//
RealmLogger.prototype.name = 'realm';
//
// Define a getter so that `winston.transports.Realm`
// is available and thus backwards compatible.
//
winston.transports.Realm = RealmLogger;
//
// ### function log (level, msg, [meta], callback)
// #### @level {string} Level at which to log the message.
// #### @msg {string} Message to log
// #### @meta {Object} **Optional** Additional metadata to attach
// #### @callback {function} Continuation to respond to when complete.
// Core logging method exposed to Winston. Metadata is optional.
//
RealmLogger.prototype.log = function (level, msg, meta, callback) {
let ts = new Date();
this.realm.write(() => {
this.realm.create('Log', {level: level, message: msg, timestamp: ts});
});
callback(null, true);
};