diff --git a/.gitdocs.json b/.gitdocs.json
new file mode 100644
index 0000000..0d50148
--- /dev/null
+++ b/.gitdocs.json
@@ -0,0 +1,4 @@
+{
+ "name": "Timber Node",
+ "root": "docs/"
+}
diff --git a/.gitignore b/.gitignore
index e273e67..59baadc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,4 +7,4 @@ logs
coverage
dist
notes.md
-docs
+.gitdocs_output
\ No newline at end of file
diff --git a/docs/api/index.md b/docs/api/index.md
new file mode 100644
index 0000000..9679546
--- /dev/null
+++ b/docs/api/index.md
@@ -0,0 +1 @@
+Describe the logger API here
\ No newline at end of file
diff --git a/docs/best-practices/data-usage.md b/docs/best-practices/data-usage.md
new file mode 100644
index 0000000..e69de29
diff --git a/docs/best-practices/environments.md b/docs/best-practices/environments.md
new file mode 100644
index 0000000..e69de29
diff --git a/docs/best-practices/errors.md b/docs/best-practices/errors.md
new file mode 100644
index 0000000..793036b
--- /dev/null
+++ b/docs/best-practices/errors.md
@@ -0,0 +1 @@
+Talk about catching errors, dealing with 500s, 404s, etc.
\ No newline at end of file
diff --git a/docs/best-practices/formatting.md b/docs/best-practices/formatting.md
new file mode 100644
index 0000000..e69de29
diff --git a/docs/best-practices/index.md b/docs/best-practices/index.md
new file mode 100644
index 0000000..e69de29
diff --git a/docs/best-practices/log-files.md b/docs/best-practices/log-files.md
new file mode 100644
index 0000000..1ce1fa3
--- /dev/null
+++ b/docs/best-practices/log-files.md
@@ -0,0 +1,3 @@
+Logging to a file
+Logrotate
+etc...
\ No newline at end of file
diff --git a/docs/best-practices/log-levels.md b/docs/best-practices/log-levels.md
new file mode 100644
index 0000000..e69de29
diff --git a/docs/best-practices/logging-class.md b/docs/best-practices/logging-class.md
new file mode 100644
index 0000000..e69de29
diff --git a/docs/best-practices/performance.md b/docs/best-practices/performance.md
new file mode 100644
index 0000000..e69de29
diff --git a/docs/best-practices/profiling.md b/docs/best-practices/profiling.md
new file mode 100644
index 0000000..c27d3e1
--- /dev/null
+++ b/docs/best-practices/profiling.md
@@ -0,0 +1 @@
+Talk about logging as a profiling tool https://www.npmjs.com/package/winston#profiling.
\ No newline at end of file
diff --git a/docs/best-practices/security.md b/docs/best-practices/security.md
new file mode 100644
index 0000000..3aeaa68
--- /dev/null
+++ b/docs/best-practices/security.md
@@ -0,0 +1 @@
+best practices regarding security
\ No newline at end of file
diff --git a/docs/best-practices/shipping.md b/docs/best-practices/shipping.md
new file mode 100644
index 0000000..c528fee
--- /dev/null
+++ b/docs/best-practices/shipping.md
@@ -0,0 +1 @@
+Agent vs Package
\ No newline at end of file
diff --git a/docs/best-practices/stdout-vs-stderr.md b/docs/best-practices/stdout-vs-stderr.md
new file mode 100644
index 0000000..881a720
--- /dev/null
+++ b/docs/best-practices/stdout-vs-stderr.md
@@ -0,0 +1 @@
+Explain the difference.
\ No newline at end of file
diff --git a/docs/best-practices/structuring-logs.md b/docs/best-practices/structuring-logs.md
new file mode 100644
index 0000000..e69de29
diff --git a/docs/best-practices/transports.md b/docs/best-practices/transports.md
new file mode 100644
index 0000000..e19d3a3
--- /dev/null
+++ b/docs/best-practices/transports.md
@@ -0,0 +1 @@
+HTTP vs Syslog
\ No newline at end of file
diff --git a/docs/best-practices/what-to-log.md b/docs/best-practices/what-to-log.md
new file mode 100644
index 0000000..e69de29
diff --git a/docs/browser/index.md b/docs/browser/index.md
new file mode 100644
index 0000000..11be62b
--- /dev/null
+++ b/docs/browser/index.md
@@ -0,0 +1 @@
+Browser...
\ No newline at end of file
diff --git a/docs/configuration/augmentation.md b/docs/configuration/augmentation.md
new file mode 100644
index 0000000..ffe2afa
--- /dev/null
+++ b/docs/configuration/augmentation.md
@@ -0,0 +1,21 @@
+# Automatic Log Augmentation
+
+Timber for Node will automatically augment all log lines with rich structured data. This will turn ordinary log lines like:
+
+```
+Sent 200 in 45.ms
+```
+
+into this:
+
+```
+Sent 200 in 45.2ms @metadata {"dt": "2017-02-02T01:33:21.154345Z", "level": "info", "context": {"http": {"method": "GET", "host": "timber.io", "path": "/path", "request_id": "abcd1234"}}, "event": {"http_response": {"status": 200, "time_ms": 45.2}}}
+```
+
+But when using Timber for Node in a development environment, having all that extra noise in your console can make it difficult to read your logs. For this reason, Timber only appends metadata when the `NODE_ENV` is set to `production`. If you want to override this setting, you can use the `append_metadata` configuration option.
+
+## How to use it
+
+```js
+timber.config.append_metadata = true
+```
\ No newline at end of file
diff --git a/docs/configuration/index.md b/docs/configuration/index.md
new file mode 100644
index 0000000..45c8fb0
--- /dev/null
+++ b/docs/configuration/index.md
@@ -0,0 +1,6 @@
+# Configuration
+
+[Timber for Node](https://github.com/timberio/timber-ruby) ships with a variety of configuration options. Below are a few of the popular ones. For a comprehensive list, see the [timber.config documentation](https://timberio.github.io/timber-node/variable/index.html#static-variable-config).
+
+1. [**Disable automatic log augmentation**](augmentation)
+2. [**Logging to multiple streams**](multiple-streams)
diff --git a/docs/configuration/multiple-streams.md b/docs/configuration/multiple-streams.md
new file mode 100644
index 0000000..da3a316
--- /dev/null
+++ b/docs/configuration/multiple-streams.md
@@ -0,0 +1,21 @@
+# Logging To Multiple Streams
+
+If you followed the [standard install instructions](../installation), your application will send all logs from `stdout` and `stderr` to Timber. If you prefer to send your logs to multiple destinations Timber has built-in support for this. Using the `attach` function, you can attach multiple writable streams to `stout` and `stderr`.
+
+**Note:** The `attach()` function is a replacement for `install()`. When manually attaching streams, you no longer need to use `install()`.
+
+
+## How to use it
+
+### Example: Logging to Timber & a file
+
+```js
+const fs = require('fs')
+const timber = require('timber')
+
+const http_stream = new timber.transports.HTTPS('{{my-timber-api-key}}')
+const file_stream = fs.createWriteStream('./app_logs', { flags: 'a' })
+
+timber.attach([http_stream, file_stream], process.stdout)
+timber.attach([http_stream, file_stream], process.stderr)
+```
diff --git a/docs/examples/express-winston.md b/docs/examples/express-winston.md
new file mode 100644
index 0000000..c7b8f41
--- /dev/null
+++ b/docs/examples/express-winston.md
@@ -0,0 +1,3 @@
+Using express + winston
+
+Link to GitHub repo.
\ No newline at end of file
diff --git a/docs/examples/index.md b/docs/examples/index.md
new file mode 100644
index 0000000..dd5a0c0
--- /dev/null
+++ b/docs/examples/index.md
@@ -0,0 +1 @@
+Example repositories for various setups.
\ No newline at end of file
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..b8253c1
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,8 @@
+---
+items_prepend:
+ - usage
+ - best-practices
+---
+# Timber Node
+
+Everything you need to know about getting started with logging in Node.
diff --git a/docs/installation/http.md b/docs/installation/http.md
new file mode 100644
index 0000000..4b54dc2
--- /dev/null
+++ b/docs/installation/http.md
@@ -0,0 +1,42 @@
+# Node HTTP Installation
+
+1. In your `shell`, *run*: prefer to integrate with your platform instead?
+
+ ```shell
+ npm install --save timber
+ ```
+
+2. In your entry file, *add*:
+
+ ```js
+ const timber = require('timber');
+
+ const transport = new timber.transports.HTTPS('{{my-timber-api-key}}');
+ timber.install(transport);
+ ```
+
+3. Optionally install middleware:
+
+ - Using [Express](https://github.com/expressjs/express)? ([learn more](../integrations/express)):
+
+ ```js
+ app.use(timber.middlewares.express())
+ ```
+
+4. Optionally integrate with your logger:
+
+ - Using [winston](https://github.com/winstonjs/winston)? ([learn more](../integrations/winston))
+
+ ```js
+ winston.remove(winston.transports.Console);
+ winston.add(winston.transports.Console, { formatter: timber.formatters.Winston });
+ ```
+
+ - Using [bunyan](https://github.com/trentm/node-bunyan)? ([learn more](../integrations/bunyan))
+
+ ```js
+ const log = bunyan.createLogger({
+ name: 'Logger',
+ stream: new timber.transports.Bunyan()
+ });
+ ```
diff --git a/docs/installation/index.md b/docs/installation/index.md
new file mode 100644
index 0000000..6464f03
--- /dev/null
+++ b/docs/installation/index.md
@@ -0,0 +1,8 @@
+# Node Installation
+
+*Note: We highly recommended [following the instructions within the Timber app](https://app.timber.io), it provides an easy step-by-step guide.*
+
+Depending on your platform you'll want write logs to STDOUT, a file, or deliver them over HTTP to the Timber service. If you're unaware which method to use, checkout our [HTTP, STDOUT, or log files doc](/guides/http-stdout-or-log-files/).
+
+1. [**HTTP** - Recommended. Deliver logs directly from your app.](http)
+2. [**STDOUT** - Advanced. Required external delivery.](stdout)
diff --git a/docs/installation/stdout.md b/docs/installation/stdout.md
new file mode 100644
index 0000000..71cf50e
--- /dev/null
+++ b/docs/installation/stdout.md
@@ -0,0 +1,41 @@
+# Node STDOUT Installation
+
+1. In your `shell`, *run*: prefer to integrate with your platform instead?
+
+ ```shell
+ npm install --save timber
+ ```
+
+2. In your entry file, *add*:
+
+ ```js
+ const timber = require('timber');
+
+ timber.config.append_metadata = true
+ ```
+
+3. Optionally install middleware:
+
+ - Using [Express](https://github.com/expressjs/express)? ([learn more](../integrations/express)):
+
+ ```js
+ app.use(timber.middlewares.express())
+ ```
+
+4. Optionally integrate with your logger:
+
+ - Using [winston](https://github.com/winstonjs/winston)? ([learn more](../integrations/winston))
+
+ ```js
+ winston.remove(winston.transports.Console);
+ winston.add(winston.transports.Console, { formatter: timber.formatters.Winston });
+ ```
+
+ - Using [bunyan](https://github.com/trentm/node-bunyan)? ([learn more](../integrations/bunyan))
+
+ ```js
+ const log = bunyan.createLogger({
+ name: 'Logger',
+ stream: timber.transports.Bunyan
+ });
+ ```
diff --git a/docs/integrations/express.md b/docs/integrations/express.md
new file mode 100644
index 0000000..a15e40c
--- /dev/null
+++ b/docs/integrations/express.md
@@ -0,0 +1,62 @@
+The [Timber for Node](https://github.com/timberio/timber-node) [Express](http://expressjs.com) integration automatically outputs [augmented](/concepts/structuring-through-augmentation/) log lines for all HTTP events.
+
+|You'll Get|
+|:------|
+|+[HTTP request event](/concepts/log-event-json-schema/events/http-request)|
+|+[HTTP response event](/concepts/log-event-json-schema/events/http-response)|
+
+
+## What you can do
+
+1. [**Trace HTTP requests**](/app/console-log-viewer/trace-http-requests)
+2. [**Inspect HTTP requests & their parameters**](/app/console-log-viewer/inspect-http-requests)
+3. [**Inspect Express logs and view their associated metadata**](/app/console-log-viewer/view-a-logs-metadata-context)
+4. [**Search on Express structured data**](/app/console-log-viewer/searching)
+5. [**Alert on Express structured data**](/app/alerts)
+6. [**Graph & visualize Express structured data**](/app/graphs)
+
+
+## Installation
+
+```js
+const express = require('express')
+const timber = require('timber')
+
+const transport = new timber.transports.HTTPS('your-timber-api-key');
+timber.install(transport);
+
+const app = express()
+
+app.use(timber.middlewares.express())
+
+app.get('/', function (req, res) {
+ res.send('hello, world!')
+})
+
+// Output when loading index route:
+// => Started GET "/" @metadata {"level": "error", "context": {...}}
+// => Outgoing HTTP response 200 in 2ms @metadata {"level": "error", ... }
+```
+
+## Configuration
+
+You can pass a configuration object as an argument to the middleware if you want to use a custom configuration. The available options are:
+
+- `capture_request_body` (`boolean`): Enables capturing of the http request body data (`false` by default)
+- `combine_http_events` (`boolean`): If enabled, the HTTPRequest and HTTPResponse events will be combined in a single log message (`false` by defaut)
+- `logger` (`object`): Pass a reference of your logger if you want the express logs sent to multiple destinations (read the below section for more information)
+
+## Using with a custom logger
+
+If you're using winston or bunyan for logging, it's possible to route the express event logs through your preferred logger. This is not required if you're only sending your logs to Timber, but may be desired if you want the express event logs sent to multiple transports streams. To enable this, pass a reference of your logger to the middleware:
+
+```js
+// If you're using winston:
+const winston = require('winston')
+app.use(timber.middlewares.express({ logger: winston }))
+
+// If you're using bunyan:
+const bunyan = require('bunyan')
+const logger = bunyan.createLogger({ name: 'Custom Logger' })
+app.use(timber.middlewares.express({ logger: winston }))
+```
diff --git a/docs/integrations/index.md b/docs/integrations/index.md
new file mode 100644
index 0000000..e69de29
diff --git a/docs/integrations/lambda.md b/docs/integrations/lambda.md
new file mode 100644
index 0000000..e69de29
diff --git a/docs/integrations/system.md b/docs/integrations/system.md
new file mode 100644
index 0000000..bd215aa
--- /dev/null
+++ b/docs/integrations/system.md
@@ -0,0 +1,16 @@
+The System / Server integration captures system level context upon initialization, augmenting your logs with structured data like `hostname`, `ip`, `pid`, and more.
+
+|You'll Get|
+|:------|
+|+[System context](/concepts/log-event-json-schema/context/system)|
+
+
+## What you can do
+
+1. [**Search your logs with this data**](/app/console-log-viewer/searching) - `system.hostname:server123.myhost.com`
+2. [**Access this data by viewing a log's metadata & context**](/app/console-log-viewer/view-a-logs-metadata-context)
+
+
+## Installation
+
+This integration is installed automatically upon initialization. There is nothing you need to do.
diff --git a/docs/loggers/bunyan.md b/docs/loggers/bunyan.md
new file mode 100644
index 0000000..8454444
--- /dev/null
+++ b/docs/loggers/bunyan.md
@@ -0,0 +1,22 @@
+The [Timber for Node](https://github.com/timberio/timber-node) [Bunyan](https://github.com/trentm/node-bunyan) integration works with the Bunyan logger to ensure structured data is properly captured, providing for seamless integration between the bunyan logger and Timber.
+
+## Installation
+
+This integration is setup when you install Timber. Please follow the instructions for [installing Timber](../installation) to use this integration.
+
+## Example
+
+```javascript
+const bunyan = require('bunyan')
+const timber = require('timber')
+
+const transport = new timber.transports.HTTPS('your-api-key')
+timber.install(transport)
+
+const log = bunyan.createLogger({ name: 'Timber Logger' })
+
+log.info('Sample log message')
+
+// Output:
+// => Sample log message @metadata {"level": "info", ... }
+```
diff --git a/docs/loggers/console.md b/docs/loggers/console.md
new file mode 100644
index 0000000..4ed1fb7
--- /dev/null
+++ b/docs/loggers/console.md
@@ -0,0 +1,12 @@
+Timber for Node ships with an integration for the standard JavaScript `console` functions. This integration allows you to either output standard logs or append logs with custom metadata or events using the builtin `console.log` functions. See [usage](../usage) for more details.
+
+
+## Warning
+You might be wondering by now that why can't we simply use console.log() for logging, afterall its built in. While console.log() can be good for immediate debugging it shouldn't be used a logger at the application level. Few of the reasons are:
+
+* You can't switch off the logs. Once a log statement is encountered, it will always be printed.
+* You can't assign levels to logging. For example you might want certain kinds of logs only in development and not in production.
+
+## Installation
+
+This integration is automatically setup when you install Timber. Please follow the instructions for [installing Timber](../installation) to use the console integration.
diff --git a/docs/loggers/index.md b/docs/loggers/index.md
new file mode 100644
index 0000000..44a6cf5
--- /dev/null
+++ b/docs/loggers/index.md
@@ -0,0 +1,10 @@
+http://www.jyotman.xyz/post/logging-in-node.js-done-right: Setting up proper logging in Node.js applications can be bit overwhelming at first due to the plethora of modules available through NPM. But its all about diving and testing a few modules and then getting comfortable with the ones you like. Some of the popular modules for logging in Node.js are
+
+Morgan
+Debug
+Winston
+Log
+Bunyan
+Pino
+
+Luckily, you can use timber-node with all of these popular loggers automatically.
\ No newline at end of file
diff --git a/docs/loggers/log.md b/docs/loggers/log.md
new file mode 100644
index 0000000..86c2200
--- /dev/null
+++ b/docs/loggers/log.md
@@ -0,0 +1 @@
+https://www.npmjs.com/package/log
\ No newline at end of file
diff --git a/docs/loggers/morgan.md b/docs/loggers/morgan.md
new file mode 100644
index 0000000..e69de29
diff --git a/docs/loggers/pino.md b/docs/loggers/pino.md
new file mode 100644
index 0000000..e69de29
diff --git a/docs/loggers/winston.md b/docs/loggers/winston.md
new file mode 100644
index 0000000..596b913
--- /dev/null
+++ b/docs/loggers/winston.md
@@ -0,0 +1,22 @@
+The [Timber for Node](https://github.com/timberio/timber-node) [Winston](https://github.com/winstonjs/winston) integration works with the Winston logger to ensure structured data is properly captured, providing for seamless integration between the Winston logger and Timber.
+
+## Installation
+
+```javascript
+var winston = require('winston');
+var timber = require('timber');
+
+var logger = new (winston.Logger)({
+ transports: [
+ // you can put any other transports here
+ new timber.transports.Winston('your-api-key', options)
+ ]
+});
+
+```
+
+## Example
+
+For more details examples demonstrating Winston with Timber, you can check out the following repositories:
+
+1. [Winston + Express](https://github.com/timberio/examples/tree/master/node/express-winston)
diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md
new file mode 100644
index 0000000..2692df9
--- /dev/null
+++ b/docs/troubleshooting.md
@@ -0,0 +1,15 @@
+If you ever run into an issue while using Timber for Node, you can use the built-in debug logger to help identify the issue. When enabling the debug logger, Timber will write verbose debug logs to any stream you supply.
+
+
+## How to use it
+
+The most common way to use the debug logger is with a file stream, this can be done like this:
+
+```js
+const timber = require('timber')
+const fs = require('fs')
+
+timber.config.debug_logger = fs.createWriteStream('./debug.log', {flags: 'a'})
+```
+
+You can supply the `debug_logger` to any writeable stream. It's not recommended to set the `debug_logger` to `stdout` or `stderr` since Timber attaches to those streams by default.
\ No newline at end of file
diff --git a/docs/usage/basic-logging.md b/docs/usage/basic-logging.md
new file mode 100644
index 0000000..74d58a8
--- /dev/null
+++ b/docs/usage/basic-logging.md
@@ -0,0 +1,25 @@
+# Basic Logging
+
+Timber integrates directly into stdout, so there's no special syntax required. Once you've installed Timber, you can continue using your logger as you normally would.
+
+
+## How to use it
+
+```js
+// If you're using the standard js console logger:
+console.info("Info message")
+console.warn("Warn message")
+console.error("Error message")
+
+// If you're using winston:
+winston.info("Info message")
+winston.warn("Warn message")
+winston.error("Error message")
+
+// If you're using bunyan:
+logger.info("Info message")
+logger.warn("Warn message")
+logger.error("Error message")
+```
+
+We encourage standard / traditional log messages for non-meaningful events. And because Timber [_augments_](/concepts/structuring-through-augmentation) your logs with metadata, you don't have to worry about making every log structured!
diff --git a/docs/usage/custom-events.md b/docs/usage/custom-events.md
new file mode 100644
index 0000000..f76b519
--- /dev/null
+++ b/docs/usage/custom-events.md
@@ -0,0 +1,56 @@
+# Custom Events
+
+
+Custom events allow you to extend beyond events already defined in [`timber.events`](https://timberio.github.io/timber-node/class/src/event.js~Event.html). If you aren't sure what an event is, please read the ["Metdata, Context, and Events" doc](/concepts/metadata-context-and-events).
+
+
+## How to use it
+
+```js
+// Using console.log:
+console.warn("Payment rejected", {
+ event: {
+ payment_rejected: { customer_id: "abcd1234", amount: 100, reason: "Card expired" }
+ }
+});
+
+// Using winston:
+winston.warn("Payment rejected", {
+ event: {
+ payment_rejected: { customer_id: "abcd1234", amount: 100, reason: "Card expired" }
+ }
+});
+
+// Using bunyan:
+logger.warn({
+ event: {
+ payment_rejected: { customer_id: "abcd1234", amount: 100, reason: "Card expired" }
+ }
+}, "Payment rejected");
+```
+
+1. [Search it](/app/console-log-viewer/searching) with queries like: `type:payment_rejected` or `payment_rejected.amount:>100`
+2. [Alert on it](/app/alerts) with threshold based alerts
+3. [Graph & visualize it](/app/graphs)
+4. [View this event's data and context](/app/console-log-viewer/view-a-logs-metadata-context)
+
+
+## How it works
+
+When this event is received by the Timber service we'll define a namespaced schema based on the event name. In this case, the namespace would be `payment_rejected`. The data structure of your log will look like:
+
+```json
+{
+ "message": "Payment rejected",
+ "level": "warn",
+ "event": {
+ "custom": {
+ "payment_rejected": {
+ "customer_id": "abcd1234",
+ "amount": 100,
+ "reason": "Card expired"
+ }
+ }
+ }
+}
+```
diff --git a/docs/usage/index.md b/docs/usage/index.md
new file mode 100644
index 0000000..3bf322c
--- /dev/null
+++ b/docs/usage/index.md
@@ -0,0 +1,5 @@
+Beyond your traditional logging statements, Timber offers a variety of ways to improve the quality of your Ruby logs. We recommend reviewing these popular guides:
+
+1. [**Basic logging**](basic-logging)
+2. [**Logging custom events (structured data)**](custom-events)
+3. [**Library documentation**](https://github.com/timberio/timber-node)
diff --git a/package.json b/package.json
index 9ac243b..7551c1d 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
"maintainers": [
"Ben Johnson ",
"David Antaramian ",
- "Garet McKinley ",
+ "Jason Maurer ",
"Zach Sherman "
],
"author": {
diff --git a/src/config.js b/src/config.js
index 0176836..e265cbd 100644
--- a/src/config.js
+++ b/src/config.js
@@ -3,8 +3,8 @@ import finder from 'find-package-json'
const filename = (require.main && require.main.filename) || __dirname
const projectPath = path.dirname(filename)
-const packageJson = finder(projectPath).next().value;
-const userConfig = packageJson && packageJson.timber;
+const packageJson = finder(projectPath).next().value
+const userConfig = packageJson && packageJson.timber
/**
* The configuration options here are use throughout the timber library.
diff --git a/src/log_entry.js b/src/log_entry.js
index 459c931..eba034f 100644
--- a/src/log_entry.js
+++ b/src/log_entry.js
@@ -14,7 +14,7 @@ class LogEntry {
* @param {String} message - the log message before transforming
* @param {Object} [context] - context to be attached to message
*/
- constructor(message, context = {}) {
+ constructor(message, context = {}, level) {
// Throw an error if no message is provided
if (!message) throw new Error(errors.log.noMessage)
@@ -32,6 +32,7 @@ class LogEntry {
$schema: JSON_SCHEMA_URL,
dt: new Date(),
message,
+ level,
...context,
}
}
diff --git a/src/transports/https.js b/src/transports/https.js
index 8e0b513..24c0c8c 100644
--- a/src/transports/https.js
+++ b/src/transports/https.js
@@ -68,7 +68,7 @@ class HTTPS extends Writable {
* data off of the buffer. Defining it means we do not need to define _write.
*/
_writev(chunks, next) {
- debug(`Sending ${chunks.length} log to stream`)
+ debug(`Sending ${chunks.length} logs to stream`)
const messages = chunks.map(chunk => chunk.chunk)
const body = JSON.stringify(messages)
const options = {
diff --git a/src/transports/index.js b/src/transports/index.js
index 2c54387..f0e6c85 100644
--- a/src/transports/index.js
+++ b/src/transports/index.js
@@ -1,4 +1,5 @@
import HTTPS from './https'
+import Winston from './winston'
import Bunyan from './bunyan'
-module.exports = { HTTPS, Bunyan }
+module.exports = { HTTPS, Bunyan, Winston }
diff --git a/src/transports/winston.js b/src/transports/winston.js
new file mode 100644
index 0000000..c55110d
--- /dev/null
+++ b/src/transports/winston.js
@@ -0,0 +1,28 @@
+import HTTPS from './https'
+import LogEntry from '../log_entry'
+import debug from '../utils/debug'
+
+// Simple Winston transport that extends the HTTPS transport
+// Look into https://github.com/winstonjs/winston-transport
+class WinstonTransport extends HTTPS {
+ constructor (key, options) {
+ super(key, options);
+ this.name = 'Timber'
+ this.applyBackPressure = options && options.applyBackPressure
+ }
+
+ log (level, message, meta, callback) {
+ const data = { level, message, meta }
+ const log = new LogEntry(message, meta, level)
+ const written = this.write(log.data)
+
+ if (!written && this.applyBackPressure) {
+ transport.once('drain', () => transport.write(log.data))
+ callback();
+ } else {
+ callback();
+ }
+ }
+}
+
+export default WinstonTransport
diff --git a/src/utils/attach.js b/src/utils/attach.js
index 0c9c3ba..5896c07 100644
--- a/src/utils/attach.js
+++ b/src/utils/attach.js
@@ -26,9 +26,18 @@ const attach = (transports, toStream, { applyBackPressure = false } = {}) => {
debug(`attaching ${transports.length} transports to stream`)
+ // Override the target stream's write method to route through the transports
+ // before calling it with the associated arguments
toStream.write = (message, encoding, fd) => {
+ // Check if this is a Timber log entry or a message string
const log = message instanceof LogEntry ? message : new LogEntry(message)
+ // Don't cause an infinite loop with debug lines
+ if (message.indexOf('[timber-debug]') !== -1) {
+ return originalWrite.apply(toStream, [log.data.message])
+ }
+
+ // Write the message to every supplied transport
for (let i = 0; i < transports.length; i++) {
const transport = transports[i]
@@ -45,6 +54,7 @@ const attach = (transports, toStream, { applyBackPressure = false } = {}) => {
// When writing the log to the original stream,
// strip the metadata if we're not in production
+ // this keeps logs cleaner during development
originalWrite.apply(toStream, [
config.append_metadata || process.env.NODE_ENV === 'production'
? log.data.message
diff --git a/src/utils/debug.js b/src/utils/debug.js
index 1ffded9..393632f 100644
--- a/src/utils/debug.js
+++ b/src/utils/debug.js
@@ -20,7 +20,7 @@ const timestamp = () => new Date().toISOString()
* Convenience function for logging debug messages
* to the configured debug_logger
*
- * This works much like the builtin console.log function,
+ * This works much like the built in console.log function,
* accepting any amount of mixed arguments and concatenating
* them into a single string to be sent to the debug_logger stream
*
@@ -29,7 +29,7 @@ const timestamp = () => new Date().toISOString()
*/
const debug = (...args) => {
if (debug_logger()) {
- debug_logger().write(`[${timestamp()}]: ${util.format.apply(null, args)}\n`)
+ debug_logger().write(`[${timestamp()}][timber-debug]: ${util.format.apply(null, args)}\n`)
}
}