Improve the runtime environment detection to fix running under NW.js.

Contributions by Adam Lynch (#310), Jeremy Ruppel (#311),
and Aleksey Timchenko (#302).
master
Trent Mick 2016-02-21 13:31:57 -08:00
parent 8b94e81fa7
commit cd7dc6a92c
5 changed files with 85 additions and 32 deletions

View File

@ -32,3 +32,4 @@ David M. Lee (https://github.com/leedm777)
Marc Udoff (https://github.com/mlucool) Marc Udoff (https://github.com/mlucool)
Mark Stosberg (https://github.com/markstos) Mark Stosberg (https://github.com/markstos)
Alexander Ray (https://github.com/aray12) Alexander Ray (https://github.com/aray12)
Adam Lynch (https://github.com/adam-lynch)

View File

@ -8,6 +8,10 @@ Known issues:
## 1.7.0 (not yet released) ## 1.7.0 (not yet released)
- [pull #311, #302, #310] Improve the runtime environment detection to fix
running under [NW.js](http://nwjs.io/). Contributions by Adam Lynch, Jeremy
Ruppel, and Aleksey Timchenko.
- [pull #318] Add `reemitErrorEvents` optional boolean for streams added to a - [pull #318] Add `reemitErrorEvents` optional boolean for streams added to a
Bunyan logger to control whether an "error" event on the stream will be Bunyan logger to control whether an "error" event on the stream will be
re-emitted on the `Logger` instance. re-emitted on the `Logger` instance.

View File

@ -55,8 +55,8 @@ node.js library usage of bunyan in your apps.
- lightweight specialization of Logger instances with [`log.child`](#logchild) - lightweight specialization of Logger instances with [`log.child`](#logchild)
- custom rendering of logged objects with ["serializers"](#serializers) - custom rendering of logged objects with ["serializers"](#serializers)
- [Runtime log snooping via DTrace support](#runtime-log-snooping-via-dtrace) - [Runtime log snooping via DTrace support](#runtime-log-snooping-via-dtrace)
- Support for [browserify](http://browserify.org/). See [Browserify - Support for a few [runtime environments](#runtime-environments): Node.js,
section](#browserify) below. [Browserify](http://browserify.org/), [NW.js](http://nwjs.io/).
# Introduction # Introduction
@ -1139,7 +1139,27 @@ Output of the above might be:
node`_start+0x83 node`_start+0x83
``` ```
# Browserify
# Runtime environments
Node-bunyan supports running in a few runtime environments:
- [Node.js](https://nodejs.org/)
- [Browserify](http://browserify.org/): See the
[Browserify section](#browserify) below.
- [NW.js](http://nwjs.io/)
Support for other runtime environments is welcome. If you have suggestions,
fixes, or mentions that node-bunyan already works in some other JavaScript
runtime, please open an [issue](https://github.com/trentm/node-bunyan/issues/new)
or a pull request.
The primary target is Node.js. It is the only environment in which I
regularly test. If you have suggestions for how to automate testing for other
environments, I'd appreciate feedback on [this automated testing
issue](https://github.com/trentm/node-bunyan/issues/342).
## Browserify
As the [Browserify](http://browserify.org/) site says it "lets you As the [Browserify](http://browserify.org/) site says it "lets you
`require('modules')` in the browser by bundling up all of your dependencies." `require('modules')` in the browser by bundling up all of your dependencies."
@ -1236,12 +1256,10 @@ log.info('hi on info');
# Versioning # Versioning
The scheme I follow is most succinctly described by the bootstrap guys All versions are `<major>.<minor>.<patch>` which will be incremented for
[here](https://github.com/twitter/bootstrap#versioning).
tl;dr: All versions are `<major>.<minor>.<patch>` which will be incremented for
breaking backward compat and major reworks, new features without breaking breaking backward compat and major reworks, new features without breaking
change, and bug fixes, respectively. change, and bug fixes, respectively. tl;dr: [Semantic
versioning](http://semver.org/).
# License # License

View File

@ -26,23 +26,60 @@ var xxx = function xxx(s) { // internal dev/debug logging
var xxx = function xxx() {}; // comment out to turn on debug logging var xxx = function xxx() {}; // comment out to turn on debug logging
if (typeof (window) === 'undefined') { /*
var os = require('os'); * Runtime environment notes:
var fs = require('fs'); *
try { * Bunyan is intended to run in a number of runtime environments. Here are
/* Use `+ ''` to hide this import from browserify. */ * some notes on differences for those envs and how the code copes.
var dtrace = require('dtrace-provider' + ''); *
} catch (e) { * - node.js: The primary target environment.
dtrace = null; * - NW.js: http://nwjs.io/ An *app* environment that feels like both a
* node env -- it has node-like globals (`process`, `global`) and
* browser-like globals (`window`, `navigator`). My *understanding* is that
* bunyan can operate as if this is vanilla node.js.
* - browser: Failing the above, we sniff using the `window` global
* <https://developer.mozilla.org/en-US/docs/Web/API/Window/window>.
* - browserify: http://browserify.org/ A browser-targetting bundler of
* node.js deps. The runtime is a browser env, so can't use fs access,
* etc. Browserify's build looks for `require(<single-string>)` imports
* to bundle. For some imports it won't be able to handle, we "hide"
* from browserify with `require('frobshizzle' + '')`.
* - Other? Please open issues if things are broken.
*/
var runtimeEnv;
if (typeof (process) !== 'undefined' && process.versions) {
if (process.versions.nw) {
runtimeEnv = 'nw';
} else if (process.versions.node) {
runtimeEnv = 'node';
} }
} else { }
var os = { if (!runtimeEnv && typeof (window) !== 'undefined' &&
window.window === window) {
runtimeEnv = 'browser';
}
if (!runtimeEnv) {
throw new Error('unknown runtime environment');
}
var os, fs, dtrace;
if (runtimeEnv === 'browser') {
os = {
hostname: function () { hostname: function () {
return window.location.host; return window.location.host;
} }
}; };
var fs = {}; fs = {};
var dtrace = null; dtrace = null;
} else {
os = require('os');
fs = require('fs');
try {
dtrace = require('dtrace-provider' + '');
} catch (e) {
dtrace = null;
}
} }
var util = require('util'); var util = require('util');
var assert = require('assert'); var assert = require('assert');
@ -59,25 +96,18 @@ if (process.env.BUNYAN_TEST_NO_SAFE_JSON_STRINGIFY) {
// The 'mv' module is required for rotating-file stream support. // The 'mv' module is required for rotating-file stream support.
try { try {
/* Use `+ ''` to hide this import from browserify. */
var mv = require('mv' + ''); var mv = require('mv' + '');
} catch (e) { } catch (e) {
mv = null; mv = null;
} }
// Are we in the browser (e.g. running via browserify)?
var isBrowser = function () {
return typeof (window) !== 'undefined'; }();
try { try {
/* Use `+ ''` to hide this import from browserify. */
var sourceMapSupport = require('source-map-support' + ''); var sourceMapSupport = require('source-map-support' + '');
} catch (_) { } catch (_) {
sourceMapSupport = null; sourceMapSupport = null;
} }
//---- Internal support stuff //---- Internal support stuff
/** /**
@ -433,7 +463,7 @@ function Logger(options, _childOptions, _childSimple) {
} else if (parent && options.level) { } else if (parent && options.level) {
this.level(options.level); this.level(options.level);
} else if (!parent) { } else if (!parent) {
if (isBrowser) { if (runtimeEnv === 'browser') {
/* /*
* In the browser we'll be emitting to console.log by default. * In the browser we'll be emitting to console.log by default.
* Any console.log worth its salt these days can nicely render * Any console.log worth its salt these days can nicely render

View File

@ -38,10 +38,10 @@ test('error event on file stream (reemitErrorEvents=undefined)', function (t) {
test('error event on file stream (reemitErrorEvents=true)', function (t) { test('error event on file stream (reemitErrorEvents=true)', function (t) {
var log = bunyan.createLogger({ var log = bunyan.createLogger({
name: 'error-event-2', name: 'error-event-2',
streams: [{ streams: [ {
path: BOGUS_PATH, path: BOGUS_PATH,
reemitErrorEvents: true reemitErrorEvents: true
}] } ]
}); });
log.on('error', function (err, stream) { log.on('error', function (err, stream) {
t.ok(err, 'got err in error event: ' + err); t.ok(err, 'got err in error event: ' + err);
@ -58,10 +58,10 @@ test('error event on file stream (reemitErrorEvents=false)',
function (t) { function (t) {
var log = bunyan.createLogger({ var log = bunyan.createLogger({
name: 'error-event-3', name: 'error-event-3',
streams: [{ streams: [ {
path: BOGUS_PATH, path: BOGUS_PATH,
reemitErrorEvents: false reemitErrorEvents: false
}] } ]
}); });
// Hack into the underlying created file stream to catch the error event. // Hack into the underlying created file stream to catch the error event.
log.streams[0].stream.on('error', function (err) { log.streams[0].stream.on('error', function (err) {