From cd7dc6a92c1c3a5af0b20d3f7234240235c1bb76 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Sun, 21 Feb 2016 13:31:57 -0800 Subject: [PATCH] Improve the runtime environment detection to fix running under NW.js. Contributions by Adam Lynch (#310), Jeremy Ruppel (#311), and Aleksey Timchenko (#302). --- AUTHORS | 1 + CHANGES.md | 4 +++ README.md | 34 ++++++++++++++----- lib/bunyan.js | 70 ++++++++++++++++++++++++++++------------ test/error-event.test.js | 8 ++--- 5 files changed, 85 insertions(+), 32 deletions(-) diff --git a/AUTHORS b/AUTHORS index f88dffe..33c6a24 100644 --- a/AUTHORS +++ b/AUTHORS @@ -32,3 +32,4 @@ David M. Lee (https://github.com/leedm777) Marc Udoff (https://github.com/mlucool) Mark Stosberg (https://github.com/markstos) Alexander Ray (https://github.com/aray12) +Adam Lynch (https://github.com/adam-lynch) diff --git a/CHANGES.md b/CHANGES.md index 201127a..3670f64 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,10 @@ Known issues: ## 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 Bunyan logger to control whether an "error" event on the stream will be re-emitted on the `Logger` instance. diff --git a/README.md b/README.md index fea7f9e..295c48b 100644 --- a/README.md +++ b/README.md @@ -55,8 +55,8 @@ node.js library usage of bunyan in your apps. - lightweight specialization of Logger instances with [`log.child`](#logchild) - custom rendering of logged objects with ["serializers"](#serializers) - [Runtime log snooping via DTrace support](#runtime-log-snooping-via-dtrace) -- Support for [browserify](http://browserify.org/). See [Browserify - section](#browserify) below. +- Support for a few [runtime environments](#runtime-environments): Node.js, + [Browserify](http://browserify.org/), [NW.js](http://nwjs.io/). # Introduction @@ -1139,7 +1139,27 @@ Output of the above might be: 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 `require('modules')` in the browser by bundling up all of your dependencies." @@ -1236,12 +1256,10 @@ log.info('hi on info'); # Versioning -The scheme I follow is most succinctly described by the bootstrap guys -[here](https://github.com/twitter/bootstrap#versioning). - -tl;dr: All versions are `..` which will be incremented for +All versions are `..` which will be incremented for 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 diff --git a/lib/bunyan.js b/lib/bunyan.js index 8263f58..70b09ad 100644 --- a/lib/bunyan.js +++ b/lib/bunyan.js @@ -26,23 +26,60 @@ var xxx = function xxx(s) { // internal dev/debug logging var xxx = function xxx() {}; // comment out to turn on debug logging -if (typeof (window) === 'undefined') { - var os = require('os'); - var fs = require('fs'); - try { - /* Use `+ ''` to hide this import from browserify. */ - var dtrace = require('dtrace-provider' + ''); - } catch (e) { - dtrace = null; +/* + * Runtime environment notes: + * + * Bunyan is intended to run in a number of runtime environments. Here are + * some notes on differences for those envs and how the code copes. + * + * - node.js: The primary target environment. + * - 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 + * . + * - 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()` 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 () { return window.location.host; } }; - var fs = {}; - var dtrace = null; + fs = {}; + dtrace = null; +} else { + os = require('os'); + fs = require('fs'); + try { + dtrace = require('dtrace-provider' + ''); + } catch (e) { + dtrace = null; + } } var util = require('util'); 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. try { - /* Use `+ ''` to hide this import from browserify. */ var mv = require('mv' + ''); } catch (e) { mv = null; } -// Are we in the browser (e.g. running via browserify)? -var isBrowser = function () { - return typeof (window) !== 'undefined'; }(); - try { - /* Use `+ ''` to hide this import from browserify. */ var sourceMapSupport = require('source-map-support' + ''); } catch (_) { sourceMapSupport = null; } - //---- Internal support stuff /** @@ -433,7 +463,7 @@ function Logger(options, _childOptions, _childSimple) { } else if (parent && options.level) { this.level(options.level); } else if (!parent) { - if (isBrowser) { + if (runtimeEnv === 'browser') { /* * In the browser we'll be emitting to console.log by default. * Any console.log worth its salt these days can nicely render diff --git a/test/error-event.test.js b/test/error-event.test.js index b981244..2318d42 100644 --- a/test/error-event.test.js +++ b/test/error-event.test.js @@ -38,10 +38,10 @@ test('error event on file stream (reemitErrorEvents=undefined)', function (t) { test('error event on file stream (reemitErrorEvents=true)', function (t) { var log = bunyan.createLogger({ name: 'error-event-2', - streams: [{ + streams: [ { path: BOGUS_PATH, reemitErrorEvents: true - }] + } ] }); log.on('error', function (err, stream) { t.ok(err, 'got err in error event: ' + err); @@ -58,10 +58,10 @@ test('error event on file stream (reemitErrorEvents=false)', function (t) { var log = bunyan.createLogger({ name: 'error-event-3', - streams: [{ + streams: [ { path: BOGUS_PATH, reemitErrorEvents: false - }] + } ] }); // Hack into the underlying created file stream to catch the error event. log.streams[0].stream.on('error', function (err) {