|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383 |
- [![npm version](https://img.shields.io/npm/v/bunyan.svg?style=flat)](https://www.npmjs.com/package/bunyan)
- [![Build Status](https://travis-ci.org/trentm/node-bunyan.svg?branch=master)](https://travis-ci.org/trentm/node-bunyan)
-
- Bunyan is **a simple and fast JSON logging library** for node.js services:
-
- ```js
- var bunyan = require('bunyan');
- var log = bunyan.createLogger({name: "myapp"});
- log.info("hi");
- ```
-
- and **a `bunyan` CLI tool** for nicely viewing those logs:
-
- ![bunyan CLI screenshot](https://raw.github.com/trentm/node-bunyan/master/tools/screenshot1.png)
-
- Manifesto: Server logs should be structured. JSON's a good format. Let's do
- that. A log record is one line of `JSON.stringify`'d output. Let's also
- specify some common names for the requisite and common fields for a log
- record (see below).
-
-
- ## Table of Contents
-
- <!-- toc -->
-
- - [Current Status](#current-status)
- - [Installation](#installation)
- - [Features](#features)
- - [Introduction](#introduction)
- * [Constructor API](#constructor-api)
- * [Log Method API](#log-method-api)
- * [CLI Usage](#cli-usage)
- * [Streams Introduction](#streams-introduction)
- * [log.child](#logchild)
- * [Serializers](#serializers)
- + [Requirements for serializers functions](#requirements-for-serializers-functions)
- + [Standard Serializers](#standard-serializers)
- * [src](#src)
- - [Levels](#levels)
- * [Level suggestions](#level-suggestions)
- - [Log Record Fields](#log-record-fields)
- * [Core fields](#core-fields)
- * [Recommended/Best Practice Fields](#recommendedbest-practice-fields)
- * [Other fields to consider](#other-fields-to-consider)
- - [Streams](#streams)
- * [Adding a Stream](#adding-a-stream)
- * [stream errors](#stream-errors)
- * [stream type: `stream`](#stream-type-stream)
- * [stream type: `file`](#stream-type-file)
- * [stream type: `rotating-file`](#stream-type-rotating-file)
- * [stream type: `raw`](#stream-type-raw)
- * [`raw` + RingBuffer Stream](#raw--ringbuffer-stream)
- * [third-party streams](#third-party-streams)
- - [Runtime log snooping via DTrace](#runtime-log-snooping-via-dtrace)
- * [DTrace examples](#dtrace-examples)
- - [Runtime environments](#runtime-environments)
- * [Browserify](#browserify)
- * [Webpack](#webpack)
- - [Versioning](#versioning)
- - [License](#license)
- - [See Also](#see-also)
-
- <!-- tocstop -->
-
- # Current Status
-
- Solid core functionality is there. Joyent is using this for a number of
- production services. Bunyan supports node 0.10 and greater. Follow
- <a href="https://twitter.com/intent/user?screen_name=trentmick" target="_blank">@trentmick</a>
- for updates to Bunyan.
-
- There is an email discussion list
- [bunyan-logging@googlegroups.com](mailto:bunyan-logging@googlegroups.com),
- also [as a forum in the
- browser](https://groups.google.com/forum/?fromgroups#!forum/bunyan-logging).
-
-
- # Installation
-
- ```sh
- npm install bunyan
- ```
-
- **Tip**: The `bunyan` CLI tool is written to be compatible (within reason) with
- all versions of Bunyan logs. Therefore you might want to `npm install -g bunyan`
- to get the bunyan CLI on your PATH, then use local bunyan installs for
- node.js library usage of bunyan in your apps.
-
-
- # Features
-
- - elegant [log method API](#log-method-api)
- - extensible [streams](#streams) system for controlling where log records
- go (to a stream, to a file, [log file rotation](#stream-type-rotating-file),
- etc.)
- - [`bunyan` CLI](#cli-usage) for pretty-printing and filtering of Bunyan logs
- - simple include of log call source location (file, line, function) with
- [`src: true`](#src)
- - 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 a few [runtime environments](#runtime-environments): Node.js,
- [Browserify](http://browserify.org/), [Webpack](https://webpack.github.io/), [NW.js](http://nwjs.io/).
-
-
- # Introduction
-
- Like most logging libraries you create a Logger instance and call methods
- named after the logging levels:
-
- ```js
- // hi.js
- var bunyan = require('bunyan');
- var log = bunyan.createLogger({name: 'myapp'});
- log.info('hi');
- log.warn({lang: 'fr'}, 'au revoir');
- ```
-
- All loggers must provide a "name". This is somewhat akin to the log4j logger
- "name", but Bunyan doesn't do hierarchical logger names.
-
- **Bunyan log records are JSON.** A few fields are added automatically:
- "pid", "hostname", "time" and "v".
-
- ```sh
- $ node hi.js
- {"name":"myapp","hostname":"banana.local","pid":40161,"level":30,"msg":"hi","time":"2013-01-04T18:46:23.851Z","v":0}
- {"name":"myapp","hostname":"banana.local","pid":40161,"level":40,"lang":"fr","msg":"au revoir","time":"2013-01-04T18:46:23.853Z","v":0}
- ```
-
-
- ## Constructor API
-
- ```js
- var bunyan = require('bunyan');
- var log = bunyan.createLogger({
- name: <string>, // Required
- level: <level name or number>, // Optional, see "Levels" section
- stream: <node.js stream>, // Optional, see "Streams" section
- streams: [<bunyan streams>, ...], // Optional, see "Streams" section
- serializers: <serializers mapping>, // Optional, see "Serializers" section
- src: <boolean>, // Optional, see "src" section
-
- // Any other fields are added to all log records as is.
- foo: 'bar',
- ...
- });
- ```
-
-
- ## Log Method API
-
- The example above shows two different ways to call `log.info(...)`. The
- full API is:
-
- ```js
- log.info(); // Returns a boolean: is the "info" level enabled?
- // This is equivalent to `log.isInfoEnabled()` or
- // `log.isEnabledFor(INFO)` in log4j.
-
- log.info('hi'); // Log a simple string message (or number).
- log.info('hi %s', bob, anotherVar); // Uses `util.format` for msg formatting.
-
- log.info({foo: 'bar'}, 'hi');
- // The first field can optionally be a "fields" object, which
- // is merged into the log record.
-
- log.info(err); // Special case to log an `Error` instance to the record.
- // This adds an "err" field with exception details
- // (including the stack) and sets "msg" to the exception
- // message.
- log.info(err, 'more on this: %s', more);
- // ... or you can specify the "msg".
-
- log.info({foo: 'bar', err: err}, 'some msg about this error');
- // To pass in an Error *and* other fields, use the `err`
- // field name for the Error instance.
- ```
-
- Note that this implies **you cannot blindly pass any object as the first
- argument to log it** because that object might include fields that collide with
- Bunyan's [core record fields](#core-fields). In other words,
- `log.info(mywidget)` may not yield what you expect. Instead of a string
- representation of `mywidget` that other logging libraries may give you, Bunyan
- will try to JSON-ify your object. It is a Bunyan best practice to always give a
- field name to included objects, e.g.:
-
- ```js
- log.info({widget: mywidget}, ...)
- ```
-
- This will dove-tail with [Bunyan serializer support](#serializers), discussed
- later.
-
- The same goes for all of Bunyan's log levels: `log.trace`, `log.debug`,
- `log.info`, `log.warn`, `log.error`, and `log.fatal`. See the [levels
- section](#levels) below for details and suggestions.
-
-
- ## CLI Usage
-
- Bunyan log output is a stream of JSON objects. This is great for processing,
- but not for reading directly. A **`bunyan` tool** is provided **for
- pretty-printing bunyan logs** and for **filtering** (e.g.
- `| bunyan -c 'this.foo == "bar"'`). Using our example above:
-
- ```sh
- $ node hi.js | ./node_modules/.bin/bunyan
- [2013-01-04T19:01:18.241Z] INFO: myapp/40208 on banana.local: hi
- [2013-01-04T19:01:18.242Z] WARN: myapp/40208 on banana.local: au revoir (lang=fr)
- ```
-
- See the screenshot above for an example of the default coloring of rendered
- log output. That example also shows the nice formatting automatically done for
- some well-known log record fields (e.g. `req` is formatted like an HTTP request,
- `res` like an HTTP response, `err` like an error stack trace).
-
- One interesting feature is **filtering** of log content, which can be useful
- for digging through large log files or for analysis. We can filter only
- records above a certain level:
-
- ```sh
- $ node hi.js | bunyan -l warn
- [2013-01-04T19:08:37.182Z] WARN: myapp/40353 on banana.local: au revoir (lang=fr)
- ```
-
- Or filter on the JSON fields in the records (e.g. only showing the French
- records in our contrived example):
-
- ```sh
- $ node hi.js | bunyan -c 'this.lang == "fr"'
- [2013-01-04T19:08:26.411Z] WARN: myapp/40342 on banana.local: au revoir (lang=fr)
- ```
-
- See `bunyan --help` for other facilities.
-
-
- ## Streams Introduction
-
- By default, log output is to stdout and at the "info" level. Explicitly that
- looks like:
-
- ```js
- var log = bunyan.createLogger({
- name: 'myapp',
- stream: process.stdout,
- level: 'info'
- });
- ```
-
- That is an abbreviated form for a single stream. **You can define multiple
- streams at different levels**.
-
- ```js
- var log = bunyan.createLogger({
- name: 'myapp',
- streams: [
- {
- level: 'info',
- stream: process.stdout // log INFO and above to stdout
- },
- {
- level: 'error',
- path: '/var/tmp/myapp-error.log' // log ERROR and above to a file
- }
- ]
- });
- ```
-
- More on streams in the [Streams section](#streams) below.
-
- ## log.child
-
- Bunyan has a concept of a child logger to **specialize a logger for a
- sub-component of your application**, i.e. to create a new logger with
- additional bound fields that will be included in its log records. A child
- logger is created with `log.child(...)`.
-
- In the following example, logging on a "Wuzzle" instance's `this.log` will
- be exactly as on the parent logger with the addition of the `widget_type`
- field:
-
- ```js
- var bunyan = require('bunyan');
- var log = bunyan.createLogger({name: 'myapp'});
-
- function Wuzzle(options) {
- this.log = options.log.child({widget_type: 'wuzzle'});
- this.log.info('creating a wuzzle')
- }
- Wuzzle.prototype.woos = function () {
- this.log.warn('This wuzzle is woosey.')
- }
-
- log.info('start');
- var wuzzle = new Wuzzle({log: log});
- wuzzle.woos();
- log.info('done');
- ```
-
- Running that looks like (raw):
-
- ```sh
- $ node myapp.js
- {"name":"myapp","hostname":"myhost","pid":34572,"level":30,"msg":"start","time":"2013-01-04T07:47:25.814Z","v":0}
- {"name":"myapp","hostname":"myhost","pid":34572,"widget_type":"wuzzle","level":30,"msg":"creating a wuzzle","time":"2013-01-04T07:47:25.815Z","v":0}
- {"name":"myapp","hostname":"myhost","pid":34572,"widget_type":"wuzzle","level":40,"msg":"This wuzzle is woosey.","time":"2013-01-04T07:47:25.815Z","v":0}
- {"name":"myapp","hostname":"myhost","pid":34572,"level":30,"msg":"done","time":"2013-01-04T07:47:25.816Z","v":0}
- ```
-
- And with the `bunyan` CLI (using the "short" output mode):
-
- ```sh
- $ node myapp.js | bunyan -o short
- 07:46:42.707Z INFO myapp: start
- 07:46:42.709Z INFO myapp: creating a wuzzle (widget_type=wuzzle)
- 07:46:42.709Z WARN myapp: This wuzzle is woosey. (widget_type=wuzzle)
- 07:46:42.709Z INFO myapp: done
- ```
-
- A more practical example is in the
- [node-restify](https://github.com/mcavage/node-restify) web framework.
- Restify uses Bunyan for its logging. One feature of its integration, is that
- if `server.use(restify.requestLogger())` is used, each restify request handler
- includes a `req.log` logger that is:
-
- ```js
- log.child({req_id: <unique request id>}, true)
- ```
-
- Apps using restify can then use `req.log` and have all such log records
- include the unique request id (as "req\_id"). Handy.
-
-
- ## Serializers
-
- Bunyan has a concept of **"serializer" functions to produce a JSON-able object
- from a JavaScript object**, so you can easily do the following:
-
- ```js
- log.info({req: <request object>}, 'something about handling this request');
- ```
-
- and have the `req` entry in the log record be just a reasonable subset of
- `<request object>` fields (or computed data about those fields).
-
-
- A logger instance can have a `serializers` mapping of log record field name
- ("req" in this example) to a serializer function. When creating the log
- record, Bunyan will call the serializer function for fields of that name.
- An example:
-
- ```js
- function reqSerializer(req) {
- return {
- method: req.method,
- url: req.url,
- headers: req.headers
- };
- }
- var log = bunyan.createLogger({
- name: 'myapp',
- serializers: {
- req: reqSerializer
- }
- });
- ```
-
-
- Typically serializers are added to a logger at creation time via
- `bunyan.createLogger({..., serializers: <serializers>})`. However, serializers
- can be added after creation via `<logger>.addSerializers(...)`, e.g.:
-
- ```js
- var log = bunyan.createLogger({name: 'myapp'});
- log.addSerializers({req: reqSerializer});
- ```
-
- ### Requirements for serializers functions
-
- A serializer function is passed unprotected objects that are passed to the
- `log.info`, `log.debug`, etc. call. This means a poorly written serializer
- function can case side-effects. Logging shouldn't do that. Here are a few
- rules and best practices for serializer functions:
-
- - A serializer function *should never throw*. The bunyan library *does*
- protect somewhat from this: if the serializer throws an error, then
- bunyan will (a) write an ugly message on stderr (along with the traceback),
- and (b) the field in the log record will be replace with a short error message.
- For example:
-
- ```
- bunyan: ERROR: Exception thrown from the "foo" Bunyan serializer. This should never happen. This is a bug in that serializer function.
- TypeError: Cannot read property 'not' of undefined
- at Object.fooSerializer [as foo] (/Users/trentm/tm/node-bunyan/bar.js:8:26)
- at /Users/trentm/tm/node-bunyan/lib/bunyan.js:873:50
- at Array.forEach (native)
- at Logger._applySerializers (/Users/trentm/tm/node-bunyan/lib/bunyan.js:865:35)
- at mkRecord (/Users/trentm/tm/node-bunyan/lib/bunyan.js:978:17)
- at Logger.info (/Users/trentm/tm/node-bunyan/lib/bunyan.js:1044:19)
- at Object.<anonymous> (/Users/trentm/tm/node-bunyan/bar.js:13:5)
- at Module._compile (module.js:409:26)
- at Object.Module._extensions..js (module.js:416:10)
- at Module.load (module.js:343:32)
- {"name":"bar","hostname":"danger0.local","pid":47411,"level":30,"foo":"(Error in Bunyan log \"foo\" serializer broke field. See stderr for details.)","msg":"one","time":"2017-03-08T02:53:51.173Z","v":0}
- ```
-
- - A serializer function *should never mutate the given object*. Doing so will
- change the object in your application.
-
- - A serializer function *should be defensive*. In my experience it is common to
- set a serializer in an app, say for field name "foo", and then accidentally
- have a log line that passes a "foo" that is undefined, or null, or of some
- unexpected type. A good start at defensiveness is to start with this:
-
- ```javascript
- function fooSerializers(foo) {
- // Guard against foo be null/undefined. Check that expected fields
- // are defined.
- if (!foo || !foo.bar)
- return foo;
- var obj = {
- // Create the object to be logged.
- bar: foo.bar
- }
- return obj;
- };
- ```
-
-
- ### Standard Serializers
-
- Bunyan includes a small set of "standard serializers", exported as
- `bunyan.stdSerializers`. Their use is completely optional. Example using
- all of them:
-
- ```js
- var log = bunyan.createLogger({
- name: 'myapp',
- serializers: bunyan.stdSerializers
- });
- ```
-
- or particular ones:
-
- ```js
- var log = bunyan.createLogger({
- name: 'myapp',
- serializers: {err: bunyan.stdSerializers.err}
- });
- ```
-
- Standard serializers are:
-
- | Field | Description |
- | ----- | ----------- |
- | err | Used for serializing JavaScript error objects, including traversing an error's cause chain for error objects with a `.cause()` -- e.g. as from [verror](https://github.com/davepacheco/node-verror). |
- | req | Common fields from a node.js HTTP request object. |
- | res | Common fields from a node.js HTTP response object. |
-
- Note that the `req` and `res` serializers intentionally do not include the
- request/response *body*, as that can be prohibitively large. If helpful, the
- [restify framework's audit logger plugin](https://github.com/restify/node-restify/blob/ac13902ad9716dcb20aaa62295403983075b1841/lib/plugins/audit.js#L38-L87)
- has its own req/res serializers that include more information (optionally
- including the body).
-
-
- ## src
-
- The **source file, line and function of the log call site** can be added to
- log records by using the `src: true` config option:
-
- ```js
- var log = bunyan.createLogger({src: true, ...});
- ```
-
- This adds the call source info with the 'src' field, like this:
-
- ```js
- {
- "name": "src-example",
- "hostname": "banana.local",
- "pid": 123,
- "component": "wuzzle",
- "level": 4,
- "msg": "This wuzzle is woosey.",
- "time": "2012-02-06T04:19:35.605Z",
- "src": {
- "file": "/Users/trentm/tm/node-bunyan/examples/src.js",
- "line": 20,
- "func": "Wuzzle.woos"
- },
- "v": 0
- }
- ```
-
- **WARNING: Determining the call source info is slow. Never use this option
- in production.**
-
-
- # Levels
-
- The log levels in bunyan are as follows. The level descriptions are best
- practice *opinions* of the author.
-
- - "fatal" (60): The service/app is going to stop or become unusable now.
- An operator should definitely look into this soon.
- - "error" (50): Fatal for a particular request, but the service/app continues
- servicing other requests. An operator should look at this soon(ish).
- - "warn" (40): A note on something that should probably be looked at by an
- operator eventually.
- - "info" (30): Detail on regular operation.
- - "debug" (20): Anything else, i.e. too verbose to be included in "info" level.
- - "trace" (10): Logging from external libraries used by your app or *very*
- detailed application logging.
-
- Setting a logger instance (or one of its streams) to a particular level implies
- that all log records *at that level and above* are logged. E.g. a logger set to
- level "info" will log records at level info and above (warn, error, fatal).
-
- While using log level *names* is preferred, the actual level values are integers
- internally (10 for "trace", ..., 60 for "fatal"). Constants are defined for
- the levels: `bunyan.TRACE` ... `bunyan.FATAL`. The lowercase level names are
- aliases supported in the API, e.g. `log.level("info")`. There is one exception:
- DTrace integration uses the level names. The fired DTrace probes are named
- 'bunyan-$levelName'.
-
- Here is the API for querying and changing levels on an existing logger.
- Recall that a logger instance has an array of output "streams":
-
- ```js
- log.level() -> INFO // gets current level (lowest level of all streams)
-
- log.level(INFO) // set all streams to level INFO
- log.level("info") // set all streams to level INFO
-
- log.levels() -> [DEBUG, INFO] // get array of levels of all streams
- log.levels(0) -> DEBUG // get level of stream at index 0
- log.levels("foo") // get level of stream with name "foo"
-
- log.levels(0, INFO) // set level of stream 0 to INFO
- log.levels(0, "info") // can use "info" et al aliases
- log.levels("foo", WARN) // set stream named "foo" to WARN
- ```
-
-
- ## Level suggestions
-
- Trent's biased suggestions for server apps: Use "debug" sparingly. Information
- that will be useful to debug errors *post mortem* should usually be included in
- "info" messages if it's generally relevant or else with the corresponding
- "error" event. Don't rely on spewing mostly irrelevant debug messages all the
- time and sifting through them when an error occurs.
-
- Trent's biased suggestions for node.js libraries: IMHO, libraries should only
- ever log at `trace`-level. Fine control over log output should be up to the
- app using a library. Having a library that spews log output at higher levels
- gets in the way of a clear story in the *app* logs.
-
-
- # Log Record Fields
-
- This section will describe *rules* for the Bunyan log format: field names,
- field meanings, required fields, etc. However, a Bunyan library doesn't
- strictly enforce all these rules while records are being emitted. For example,
- Bunyan will add a `time` field with the correct format to your log records,
- but you can specify your own. It is the caller's responsibility to specify
- the appropriate format.
-
- The reason for the above leniency is because IMO logging a message should
- never break your app. This leads to this rule of logging: **a thrown
- exception from `log.info(...)` or equivalent (other than for calling with the
- incorrect signature) is always a bug in Bunyan.**
-
-
- A typical Bunyan log record looks like this:
-
- ```js
- {"name":"myserver","hostname":"banana.local","pid":123,"req":{"method":"GET","url":"/path?q=1#anchor","headers":{"x-hi":"Mom","connection":"close"}},"level":3,"msg":"start request","time":"2012-02-03T19:02:46.178Z","v":0}
- ```
-
- Pretty-printed:
-
- ```js
- {
- "name": "myserver",
- "hostname": "banana.local",
- "pid": 123,
- "req": {
- "method": "GET",
- "url": "/path?q=1#anchor",
- "headers": {
- "x-hi": "Mom",
- "connection": "close"
- },
- "remoteAddress": "120.0.0.1",
- "remotePort": 51244
- },
- "level": 3,
- "msg": "start request",
- "time": "2012-02-03T19:02:57.534Z",
- "v": 0
- }
- ```
-
- ## Core fields
-
- - `v`: Required. Integer. Added by Bunyan. Cannot be overridden.
- This is the Bunyan log format version (`require('bunyan').LOG_VERSION`).
- The log version is a single integer. `0` is until I release a version
- "1.0.0" of node-bunyan. Thereafter, starting with `1`, this will be
- incremented if there is any backward incompatible change to the log record
- format. Details will be in "CHANGES.md" (the change log).
- - `level`: Required. Integer. Added by Bunyan. Cannot be overridden.
- See the "Levels" section.
- - `name`: Required. String. Provided at Logger creation.
- You must specify a name for your logger when creating it. Typically this
- is the name of the service/app using Bunyan for logging.
- - `hostname`: Required. String. Provided or determined at Logger creation.
- You can specify your hostname at Logger creation or it will be retrieved
- vi `os.hostname()`.
- - `pid`: Required. Integer. Filled in automatically at Logger creation.
- - `time`: Required. String. Added by Bunyan. Can be overridden.
- The date and time of the event in [ISO 8601
- Extended Format](http://en.wikipedia.org/wiki/ISO_8601) format and in UTC,
- as from
- [`Date.toISOString()`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/toISOString).
- - `msg`: Required. String.
- Every `log.debug(...)` et al call must provide a log message.
- - `src`: Optional. Object giving log call source info. This is added
- automatically by Bunyan if the "src: true" config option is given to the
- Logger. Never use in production as this is really slow.
-
-
- Go ahead and add more fields, and nested ones are fine (and recommended) as
- well. This is why we're using JSON. Some suggestions and best practices
- follow (feedback from actual users welcome).
-
-
- ## Recommended/Best Practice Fields
-
- - `err`: Object. A caught JS exception. Log that thing with `log.info(err)`
- to get:
-
- ```js
- ...
- "err": {
- "message": "boom",
- "name": "TypeError",
- "stack": "TypeError: boom\n at Object.<anonymous> ..."
- },
- "msg": "boom",
- ...
- ```
-
- Or use the `bunyan.stdSerializers.err` serializer in your Logger and
- do this `log.error({err: err}, "oops")`. See "examples/err.js".
-
- - `req_id`: String. A request identifier. Including this field in all logging
- tied to handling a particular request to your server is strongly suggested.
- This allows post analysis of logs to easily collate all related logging
- for a request. This really shines when you have a SOA with multiple services
- and you carry a single request ID from the top API down through all APIs
- (as [node-restify](https://github.com/mcavage/node-restify) facilitates
- with its 'Request-Id' header).
-
- - `req`: An HTTP server request. Bunyan provides `bunyan.stdSerializers.req`
- to serialize a request with a suggested set of keys. Example:
-
- ```js
- {
- "method": "GET",
- "url": "/path?q=1#anchor",
- "headers": {
- "x-hi": "Mom",
- "connection": "close"
- },
- "remoteAddress": "120.0.0.1",
- "remotePort": 51244
- }
- ```
-
- - `res`: An HTTP server response. Bunyan provides `bunyan.stdSerializers.res`
- to serialize a response with a suggested set of keys. Example:
-
- ```js
- {
- "statusCode": 200,
- "header": "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: keep-alive\r\nTransfer-Encoding: chunked\r\n\r\n"
- }
- ```
-
- ## Other fields to consider
-
- - `req.username`: Authenticated user (or for a 401, the user attempting to
- auth).
- - Some mechanism to calculate response latency. "restify" users will have
- a "X-Response-Time" header. A `latency` custom field would be fine.
- - `req.body`: If you know that request bodies are small (common in APIs,
- for example), then logging the request body is good.
-
-
- # Streams
-
- A "stream" is Bunyan's name for where it outputs log messages (the equivalent
- to a log4j Appender). Ultimately Bunyan uses a
- [Writable Stream](https://nodejs.org/docs/latest/api/all.html#writable_Stream)
- interface, but there are some additional attributes used to create and
- manage the stream. A Bunyan Logger instance has one or more streams.
- In general streams are specified with the "streams" option:
-
- ```js
- var bunyan = require('bunyan');
- var log = bunyan.createLogger({
- name: "foo",
- streams: [
- {
- stream: process.stderr,
- level: "debug"
- },
- ...
- ]
- });
- ```
-
- For convenience, if there is only one stream, it can specified with the
- "stream" and "level" options (internally converted to a `Logger.streams`).
-
- ```js
- var log = bunyan.createLogger({
- name: "foo",
- stream: process.stderr,
- level: "debug"
- });
- ```
-
- Note that "file" streams do not support this shortcut (partly for historical
- reasons and partly to not make it difficult to add a literal "path" field
- on log records).
-
- If neither "streams" nor "stream" are specified, the default is a stream of
- type "stream" emitting to `process.stdout` at the "info" level.
-
- ## Adding a Stream
-
- After a bunyan instance has been initialized, you may add additional streams by
- calling the `addStream` function.
-
- ```js
- var bunyan = require('bunyan');
- var log = bunyan.createLogger('myLogger');
- log.addStream({
- name: "myNewStream",
- stream: process.stderr,
- level: "debug"
- });
- ```
-
- ## stream errors
-
- A Bunyan logger instance can be made to re-emit "error" events from its
- streams. Bunyan does so by default for [`type === "file"`
- streams](#stream-type-file), so you can do this:
-
- ```js
- var log = bunyan.createLogger({name: 'mylog', streams: [{path: LOG_PATH}]});
- log.on('error', function (err, stream) {
- // Handle stream write or create error here.
- });
- ```
-
- As of bunyan@1.7.0, the `reemitErrorEvents` field can be used when adding a
- stream to control whether "error" events are re-emitted on the Logger. For
- example:
-
- var EventEmitter = require('events').EventEmitter;
- var util = require('util');
-
- function MyFlakyStream() {}
- util.inherits(MyFlakyStream, EventEmitter);
-
- MyFlakyStream.prototype.write = function (rec) {
- this.emit('error', new Error('boom'));
- }
-
- var log = bunyan.createLogger({
- name: 'this-is-flaky',
- streams: [
- {
- type: 'raw',
- stream: new MyFlakyStream(),
- reemitErrorEvents: true
- }
- ]
- });
- log.info('hi there');
-
- The behaviour is as follows:
-
- - `reemitErrorEvents` not specified: `file` streams will re-emit error events
- on the Logger instance.
- - `reemitErrorEvents: true`: error events will be re-emitted on the Logger
- for any stream with a `.on()` function -- which includes file streams,
- process.stdout/stderr, and any object that inherits from EventEmitter.
- - `reemitErrorEvents: false`: error events will not be re-emitted for any
- streams.
-
- Note: "error" events are **not** related to log records at the "error" level
- as produced by `log.error(...)`. See [the node.js docs on error
- events](https://nodejs.org/api/events.html#events_error_events) for details.
-
-
- ## stream type: `stream`
-
- A `type === 'stream'` is a plain ol' node.js [Writable
- Stream](http://nodejs.org/docs/latest/api/all.html#writable_Stream). A
- "stream" (the writable stream) field is required. E.g.: `process.stdout`,
- `process.stderr`.
-
- ```js
- var log = bunyan.createLogger({
- name: 'foo',
- streams: [{
- stream: process.stderr
- // `type: 'stream'` is implied
- }]
- });
- ```
-
- <table>
- <tr>
- <th>Field</th>
- <th>Required?</th>
- <th>Default</th>
- <th>Description</th>
- </tr>
- <tr>
- <td>stream</td>
- <td>Yes</td>
- <td>-</td>
- <td>A "Writable Stream", e.g. a std handle or an open file write stream.</td>
- </tr>
- <tr>
- <td>type</td>
- <td>No</td>
- <td>n/a</td>
- <td>`type == 'stream'` is implied if the `stream` field is given.</td>
- </tr>
- <tr>
- <td>level</td>
- <td>No</td>
- <td>info</td>
- <td>The level to which logging to this stream is enabled. If not
- specified it defaults to "info". If specified this can be one of the
- level strings ("trace", "debug", ...) or constants (`bunyan.TRACE`,
- `bunyan.DEBUG`, ...). This serves as a severity threshold for that stream
- so logs of greater severity will also pass through (i.e. If level="warn",
- error and fatal will also pass through this stream).</td>
- </tr>
- <tr>
- <td>name</td>
- <td>No</td>
- <td>-</td>
- <td>A name for this stream. This may be useful for usage of `log.level(NAME,
- LEVEL)`. See the [Levels section](#levels) for details. A stream "name" isn't
- used for anything else.</td>
- </tr>
- </table>
-
-
- ## stream type: `file`
-
- A `type === 'file'` stream requires a "path" field. Bunyan will open this
- file for appending. E.g.:
-
- ```js
- var log = bunyan.createLogger({
- name: 'foo',
- streams: [{
- path: '/var/log/foo.log',
- // `type: 'file'` is implied
- }]
- });
- ```
-
- <table>
- <tr>
- <th>Field</th>
- <th>Required?</th>
- <th>Default</th>
- <th>Description</th>
- </tr>
- <tr>
- <td>path</td>
- <td>Yes</td>
- <td>-</td>
- <td>A file path to which to log.</td>
- </tr>
- <tr>
- <td>type</td>
- <td>No</td>
- <td>n/a</td>
- <td>`type == 'file'` is implied if the `path` field is given.</td>
- </tr>
- <tr>
- <td>level</td>
- <td>No</td>
- <td>info</td>
- <td>The level to which logging to this stream is enabled. If not
- specified it defaults to "info". If specified this can be one of the
- level strings ("trace", "debug", ...) or constants (`bunyan.TRACE`,
- `bunyan.DEBUG`, ...). This serves as a severity threshold for that
- stream so logs of greater severity will also pass through (i.e. If
- level="warn", error and fatal will also pass through this stream).</td>
- </tr>
- <tr>
- <td>name</td>
- <td>No</td>
- <td>-</td>
- <td>A name for this stream. This may be useful for usage of `log.level(NAME,
- LEVEL)`. See the [Levels section](#levels) for details. A stream "name" isn't
- used for anything else.</td>
- </tr>
- </table>
-
-
- ## stream type: `rotating-file`
-
- **WARNING on node 0.8 usage:** Users of Bunyan's `rotating-file` should (a) be
- using at least bunyan 0.23.1 (with the fix for [this
- issue](https://github.com/trentm/node-bunyan/pull/97)), and (b) should use at
- least node 0.10 (node 0.8 does not support the `unref()` method on
- `setTimeout(...)` needed for the mentioned fix). The symptom is that process
- termination will hang for up to a full rotation period.
-
- **WARNING on [cluster](http://nodejs.org/docs/latest/api/all.html#all_cluster)
- usage:** Using Bunyan's `rotating-file` stream with node.js's "cluster" module
- can result in unexpected file rotation. You must not have multiple processes
- in the cluster logging to the same file path. In other words, you must have
- a separate log file path for the master and each worker in the cluster.
- Alternatively, consider using a system file rotation facility such as
- `logrotate` on Linux or `logadm` on SmartOS/Illumos. See
- [this comment on issue #117](https://github.com/trentm/node-bunyan/issues/117#issuecomment-44804938)
- for details.
-
- A `type === 'rotating-file'` is a file stream that handles file automatic
- rotation.
-
- ```js
- var log = bunyan.createLogger({
- name: 'foo',
- streams: [{
- type: 'rotating-file',
- path: '/var/log/foo.log',
- period: '1d', // daily rotation
- count: 3 // keep 3 back copies
- }]
- });
- ```
-
- This will rotate '/var/log/foo.log' every day (at midnight) to:
-
- ```sh
- /var/log/foo.log.0 # yesterday
- /var/log/foo.log.1 # 1 day ago
- /var/log/foo.log.2 # 2 days ago
- ```
-
- *Currently*, there is no support for providing a template for the rotated
- files, or for rotating when the log reaches a threshold size.
-
- <table>
- <tr>
- <th>Field</th>
- <th>Required?</th>
- <th>Default</th>
- <th>Description</th>
- </tr>
- <tr>
- <td>type</td>
- <td>Yes</td>
- <td>-</td>
- <td>"rotating-file"</td>
- </tr>
- <tr>
- <td>path</td>
- <td>Yes</td>
- <td>-</td>
- <td>A file path to which to log. Rotated files will be "$path.0",
- "$path.1", ...</td>
- </tr>
- <tr>
- <td>period</td>
- <td>No</td>
- <td>1d</td>
- <td>The period at which to rotate. This is a string of the format
- "$number$scope" where "$scope" is one of "ms" (milliseconds -- only useful for
- testing), "h" (hours), "d" (days), "w" (weeks), "m" (months), "y" (years). Or
- one of the following names can be used "hourly" (means 1h), "daily" (1d),
- "weekly" (1w), "monthly" (1m), "yearly" (1y). Rotation is done at the start of
- the scope: top of the hour (h), midnight (d), start of Sunday (w), start of the
- 1st of the month (m), start of Jan 1st (y).</td>
- </tr>
- <tr>
- <td>count</td>
- <td>No</td>
- <td>10</td>
- <td>The number of rotated files to keep.</td>
- </tr>
- <tr>
- <td>level</td>
- <td>No</td>
- <td>info</td>
- <td>The level at which logging to this stream is enabled. If not
- specified it defaults to "info". If specified this can be one of the
- level strings ("trace", "debug", ...) or constants (`bunyan.TRACE`,
- `bunyan.DEBUG`, ...).</td>
- </tr>
- <tr>
- <td>name</td>
- <td>No</td>
- <td>-</td>
- <td>A name for this stream. This may be useful for usage of `log.level(NAME,
- LEVEL)`. See the [Levels section](#levels) for details. A stream "name" isn't
- used for anything else.</td>
- </tr>
- </table>
-
-
- **Note on log rotation**: Often you may be using external log rotation utilities
- like `logrotate` on Linux or `logadm` on SmartOS/Illumos. In those cases, unless
- your are ensuring "copy and truncate" semantics (via `copytruncate` with
- logrotate or `-c` with logadm) then the fd for your 'file' stream will change.
- You can tell bunyan to reopen the file stream with code like this in your
- app:
-
- ```js
- var log = bunyan.createLogger(...);
- ...
- process.on('SIGUSR2', function () {
- log.reopenFileStreams();
- });
- ```
-
- where you'd configure your log rotation to send SIGUSR2 (or some other signal)
- to your process. Any other mechanism to signal your app to run
- `log.reopenFileStreams()` would work as well.
-
-
- ## stream type: `raw`
-
- - `raw`: Similar to a "stream" writable stream, except that the write method
- is given raw log record *Object*s instead of a JSON-stringified string.
- This can be useful for hooking on further processing to all Bunyan logging:
- pushing to an external service, a RingBuffer (see below), etc.
-
-
-
- ## `raw` + RingBuffer Stream
-
- Bunyan comes with a special stream called a RingBuffer which keeps the last N
- records in memory and does *not* write the data anywhere else. One common
- strategy is to log 'info' and higher to a normal log file but log all records
- (including 'trace') to a ringbuffer that you can access via a debugger, or your
- own HTTP interface, or a post-mortem facility like MDB or node-panic.
-
- To use a RingBuffer:
-
- ```js
- /* Create a ring buffer that stores the last 100 records. */
- var bunyan = require('bunyan');
- var ringbuffer = new bunyan.RingBuffer({ limit: 100 });
- var log = bunyan.createLogger({
- name: 'foo',
- streams: [
- {
- level: 'info',
- stream: process.stdout
- },
- {
- level: 'trace',
- type: 'raw', // use 'raw' to get raw log record objects
- stream: ringbuffer
- }
- ]
- });
-
- log.info('hello world');
- console.log(ringbuffer.records);
- ```
-
- This example emits:
-
- ```js
- [ { name: 'foo',
- hostname: '912d2b29',
- pid: 50346,
- level: 30,
- msg: 'hello world',
- time: '2012-06-19T21:34:19.906Z',
- v: 0 } ]
- ```
-
- ## third-party streams
-
- See the [user-maintained list in the Bunyan
- wiki](https://github.com/trentm/node-bunyan/wiki/Awesome-Bunyan).
-
-
- # Runtime log snooping via DTrace
-
- On systems that support DTrace (e.g., illumos derivatives like SmartOS and
- OmniOS, FreeBSD, Mac), Bunyan will create a DTrace provider (`bunyan`) that
- makes available the following probes:
-
- ```sh
- log-trace
- log-debug
- log-info
- log-warn
- log-error
- log-fatal
- ```
-
- Each of these probes has a single argument: the string that would be
- written to the log. Note that when a probe is enabled, it will
- fire whenever the corresponding function is called, even if the level of
- the log message is less than that of any stream.
-
-
- ## DTrace examples
-
- Trace all log messages coming from any Bunyan module on the system.
- (The `-x strsize=4k` is to raise dtrace's default 256 byte buffer size
- because log messages are longer than typical dtrace probes.)
-
- ```sh
- dtrace -x strsize=4k -qn 'bunyan*:::log-*{printf("%d: %s: %s", pid, probefunc, copyinstr(arg0))}'
- ```
-
- Trace all log messages coming from the "wuzzle" component:
-
- ```sh
- dtrace -x strsize=4k -qn 'bunyan*:::log-*/strstr(this->str = copyinstr(arg0), "\"component\":\"wuzzle\"") != NULL/{printf("%s", this->str)}'
- ```
-
- Aggregate debug messages from process 1234, by message:
-
- ```sh
- dtrace -x strsize=4k -n 'bunyan1234:::log-debug{@[copyinstr(arg0)] = count()}'
- ```
-
- Have the bunyan CLI pretty-print the traced logs:
-
- ```sh
- dtrace -x strsize=4k -qn 'bunyan1234:::log-*{printf("%s", copyinstr(arg0))}' | bunyan
- ```
-
- A convenience handle has been made for this:
-
- ```sh
- bunyan -p 1234
- ```
-
- On systems that support the
- [`jstack`](http://dtrace.org/blogs/dap/2012/04/25/profiling-node-js/) action
- via a node.js helper, get a stack backtrace for any debug message that
- includes the string "danger!":
-
- ```sh
- dtrace -x strsize=4k -qn 'log-debug/strstr(copyinstr(arg0), "danger!") != NULL/{printf("\n%s", copyinstr(arg0)); jstack()}'
- ```
-
- Output of the above might be:
-
- ```
- {"name":"foo","hostname":"763bf293-d65c-42d5-872b-4abe25d5c4c7.local","pid":12747,"level":20,"msg":"danger!","time":"2012-10-30T18:28:57.115Z","v":0}
-
- node`0x87e2010
- DTraceProviderBindings.node`usdt_fire_probe+0x32
- DTraceProviderBindings.node`_ZN4node11DTraceProbe5_fireEN2v85LocalINS1_5ValueEEE+0x32d
- DTraceProviderBindings.node`_ZN4node11DTraceProbe4FireERKN2v89ArgumentsE+0x77
- << internal code >>
- (anon) as (anon) at /root/node-bunyan/lib/bunyan.js position 40484
- << adaptor >>
- (anon) as doit at /root/my-prog.js position 360
- (anon) as list.ontimeout at timers.js position 4960
- << adaptor >>
- << internal >>
- << entry >>
- node`_ZN2v88internalL6InvokeEbNS0_6HandleINS0_10JSFunctionEEENS1_INS0_6ObjectEEEiPS5_Pb+0x101
- node`_ZN2v88internal9Execution4CallENS0_6HandleINS0_6ObjectEEES4_iPS4_Pbb+0xcb
- node`_ZN2v88Function4CallENS_6HandleINS_6ObjectEEEiPNS1_INS_5ValueEEE+0xf0
- node`_ZN4node12MakeCallbackEN2v86HandleINS0_6ObjectEEENS1_INS0_8FunctionEEEiPNS1_INS0_5ValueEEE+0x11f
- node`_ZN4node12MakeCallbackEN2v86HandleINS0_6ObjectEEENS1_INS0_6StringEEEiPNS1_INS0_5ValueEEE+0x66
- node`_ZN4node9TimerWrap9OnTimeoutEP10uv_timer_si+0x63
- node`uv__run_timers+0x66
- node`uv__run+0x1b
- node`uv_run+0x17
- node`_ZN4node5StartEiPPc+0x1d0
- node`main+0x1b
- node`_start+0x83
-
- node`0x87e2010
- DTraceProviderBindings.node`usdt_fire_probe+0x32
- DTraceProviderBindings.node`_ZN4node11DTraceProbe5_fireEN2v85LocalINS1_5ValueEEE+0x32d
- DTraceProviderBindings.node`_ZN4node11DTraceProbe4FireERKN2v89ArgumentsE+0x77
- << internal code >>
- (anon) as (anon) at /root/node-bunyan/lib/bunyan.js position 40484
- << adaptor >>
- (anon) as doit at /root/my-prog.js position 360
- (anon) as list.ontimeout at timers.js position 4960
- << adaptor >>
- << internal >>
- << entry >>
- node`_ZN2v88internalL6InvokeEbNS0_6HandleINS0_10JSFunctionEEENS1_INS0_6ObjectEEEiPS5_Pb+0x101
- node`_ZN2v88internal9Execution4CallENS0_6HandleINS0_6ObjectEEES4_iPS4_Pbb+0xcb
- node`_ZN2v88Function4CallENS_6HandleINS_6ObjectEEEiPNS1_INS_5ValueEEE+0xf0
- node`_ZN4node12MakeCallbackEN2v86HandleINS0_6ObjectEEENS1_INS0_8FunctionEEEiPNS1_INS0_5ValueEEE+0x11f
- node`_ZN4node12MakeCallbackEN2v86HandleINS0_6ObjectEEENS1_INS0_6StringEEEiPNS1_INS0_5ValueEEE+0x66
- node`_ZN4node9TimerWrap9OnTimeoutEP10uv_timer_si+0x63
- node`uv__run_timers+0x66
- node`uv__run+0x1b
- node`uv_run+0x17
- node`_ZN4node5StartEiPPc+0x1d0
- node`main+0x1b
- node`_start+0x83
- ```
-
-
- # 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.
- - [Webpack](https://webpack.github.io/): See the [Webpack section](#webpack) 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."
- It is a build tool to run on your node.js script to bundle up your script and
- all its node.js dependencies into a single file that is runnable in the
- browser via:
-
- ```html
- <script src="play.browser.js"></script>
- ```
-
- As of version 1.1.0, node-bunyan supports being run via Browserify. The
- default [stream](#streams) when running in the browser is one that emits
- raw log records to `console.log/info/warn/error`.
-
- Here is a quick example showing you how you can get this working for your
- script.
-
- 1. Get browserify and bunyan installed in your module:
-
- ```sh
- $ npm install browserify bunyan
- ```
-
- 2. An example script using Bunyan, "play.js":
-
- ```js
- var bunyan = require('bunyan');
- var log = bunyan.createLogger({name: 'play', level: 'debug'});
- log.trace('this one does not emit');
- log.debug('hi on debug'); // console.log
- log.info('hi on info'); // console.info
- log.warn('hi on warn'); // console.warn
- log.error('hi on error'); // console.error
- ```
-
- 3. Build this into a bundle to run in the browser, "play.browser.js":
-
- ```sh
- $ ./node_modules/.bin/browserify play.js -o play.browser.js
- ```
-
- 4. Put that into an HTML file, "play.html":
-
- ```html
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <script src="play.browser.js"></script>
- </head>
- <body>
- <div>hi</div>
- </body>
- </html>
- ```
-
- 5. Open that in your browser and open your browser console:
-
- ```sh
- $ open play.html
- ```
-
- Here is what it looks like in Firefox's console: ![Bunyan + Browserify in the
- Firefox console](./docs/img/bunyan.browserify.png)
-
- For some, the raw log records might not be desired. To have a rendered log line
- you'll want to add your own stream, starting with something like this:
-
- ```js
- var bunyan = require('./lib/bunyan');
-
- function MyRawStream() {}
- MyRawStream.prototype.write = function (rec) {
- console.log('[%s] %s: %s',
- rec.time.toISOString(),
- bunyan.nameFromLevel[rec.level],
- rec.msg);
- }
-
- var log = bunyan.createLogger({
- name: 'play',
- streams: [
- {
- level: 'info',
- stream: new MyRawStream(),
- type: 'raw'
- }
- ]
- });
-
- log.info('hi on info');
- ```
-
- ## Webpack
- Webpack can work with the same example Browserify above. To do this, we need to make webpack ignore optional files:
- Create "empty_shim.js":
- ```javascript
- // This is an empty shim for things that should be not be included in webpack
- ```
- Now tell webpack to use this file for
- [optional dependencies](https://webpack.github.io/docs/configuration.html#resolve-alias)
- in your "webpack.config.js":
- ```
- resolve: {
- // These shims are needed for bunyan
- alias: {
- 'dtrace-provider': '/path/to/shim/empty_shim.js',
- fs: '/path/to/shim/empty_shim.js',
- 'safe-json-stringify': '/path/to/shim/empty_shim.js',
- mv: '/path/to/shim/empty_shim.js',
- 'source-map-support': '/path/to/shim/empty_shim.js'
- }
- }
- ```
- Now webpack builds, ignoring these optional dependencies via shimming in an empty JS file!
-
- # Versioning
-
- All versions are `<major>.<minor>.<patch>` which will be incremented for
- breaking backward compat and major reworks, new features without breaking
- change, and bug fixes, respectively. tl;dr: [Semantic
- versioning](http://semver.org/).
-
- # License
-
- [MIT](./LICENSE.txt).
-
- # See Also
-
- See the [user-maintained list of Bunyan-related software in the Bunyan
- wiki](https://github.com/trentm/node-bunyan/wiki/Awesome-Bunyan).
|