Detalhes do pacote

storyboard

guigrpa12.6kMIT3.3.2

End-to-end, hierarchical, real-time, colorful logs and stories

log, logging, websockets, console

readme (leia-me)

Storyboard Build Status Coverage Status npm version

Storyboard DevTools

A library, plus a Chrome DevTools extension.

Blog post: http://guigrpa.github.io/2016/07/18/untangling-spaghetti-logs/

These docs are for Storyboard v3. Docs for v2 are also available, but you're encouraged to upgrade!

Why? :sparkles:

  • Hierarchical stories: put logs in context (stories), and group them in higher-order stories; they can be a life-saver with concurrent user actions and async events.
  • End-to-end stories: see all client and server tasks triggered by a user action (a click on the Login button, maybe) in a single place.
  • Storyboard DevTools Chrome extension: view client and server logs with a clean and detail-rich interface, including advanced features such as remote monitoring (for mobile devices and non-Chrome browsers) and relative timestamps.
  • Storyboard CLI: wrap any application with it (no changes required) to monitor it remotely with the Storyboard DevTools.
  • Real-time push of server logs to the Storyboard DevTools extension via WebSockets, with opt-in client-server clock synchronization. Even more: control the level of detail you get from various parts of your server remotely, without relaunching.
  • Secure server logs: remote access is opt-in, and can be authenticated.
  • Attach anything to your logs for further investigation.
  • Plug-in architecture. Available plugins include Console (& Parallel Console), WebSocket Server & Client, File, (PostgreSQL) Database, and Browser Extension, but you can write your own too!
  • Lightweight. Plugins are now (v3) available separately, so you only need to bring in the dependencies you actually use.
  • Rich filter options: give logs source and severity attributes and apply fine-grained filtering, with white and black lists.
  • Colorful: use color to convey meaning and importance. Storyboard extends the popular chalk library so that it can also be used on the browser.
  • Enjoy the simple-yet-powerful API.
  • Flow-compatible (with zero config).

Installation

For the simplest possible Storyboard installation (for more options, check out the Listeners section below):

$ npm install --save storyboard storyboard-preset-console

If you only want the (less powerful) CLI tool, see this section.

To install the Storyboard DevTools Chrome extension, get it from the Chrome Web Store. Optional, but highly recommended! After installing it, open the Storyboard pane in the Chrome DevTools and point your browser to a Storyboard-equipped page (see below for how to use the library).

CLI tool

Hopefully the next sections will convince you of the benefits of adding Storyboard to your project. If you don't want to modify your existing application but still want to use the Storyboard DevTools or other Storyboard features, you can use the sb CLI tool:

$ npm install -g storyboard-cli
$ sb --server ls

2016-07-15T17:26:33.974Z           storyboard INFO  ┌── ROOT STORY [CREATED]
2016-07-15T17:26:33.975Z           storyboard INFO  Log filter: *:DEBUG
2016-07-15T17:26:34.151Z           storyboard INFO  Logs available via web on port 8090
2016-07-15T17:26:34.154Z                 main INFO  CHANGELOG.md
2016-07-15T17:26:34.155Z                 main INFO  LICENSE
2016-07-15T17:26:34.155Z                 main INFO  README.md
2016-07-15T17:26:34.155Z                 main INFO  ROADMAP.md
2016-07-15T17:26:34.155Z                 main INFO  chromeExtension
2016-07-15T17:26:34.155Z                 main INFO  coverage
...

You can pipe stdin and stdout in the standard way:

$ sb ls | head -n 3

2016-07-15T14:41:47.573Z           storyboard INFO  ┌── ROOT STORY [CREATED]
2016-07-15T14:41:47.574Z           storyboard INFO  Log filter: *:DEBUG
2016-07-15T14:41:47.601Z                 main INFO  CHANGELOG.md

$ ls | sb -- head -n 3

2016-07-15T14:41:52.174Z           storyboard INFO  ┌── ROOT STORY [CREATED]
2016-07-15T14:41:52.176Z           storyboard INFO  Log filter: *:DEBUG
2016-07-15T14:41:52.201Z                 main INFO  CHANGELOG.md
2016-07-15T14:41:52.201Z                 main INFO  LICENSE
2016-07-15T14:41:52.201Z                 main INFO  README.md
2016-07-15T14:41:52.202Z                 main INFO  
2016-07-15T14:41:52.203Z           storyboard INFO  └── ROOT STORY [CLOSED]

Note the use of the -- separator: options before the separator are passed to the sb tool; after the separator, they are passed to the called application.

Here are the CLI tool configuration options:

$ sb --help

  Usage: sb [options] <command> [args...]

  Options:

    -h, --help         output usage information
    -V, --version      output the version number
    --no-console       Disable console output
    --stderr           Enable stderr for errors
    --no-colors        Disable color output
    -f, --file <path>  Save logs to file
    -s, --server       Launch web server for logs
    -p, --port <port>  Port for web server

Storyboard library usage

Basic usage

import { mainStory } from 'storyboard';
import 'storyboard-preset-console';

mainStory.info('Hello world!');

We're using the storyboard-preset-console preset for convenience, which is equivalent to:

import { mainStory, addListener } from 'storyboard';
import consoleListener from 'storyboard-listener-console';
addListener(consoleListener);

mainStory.info('Hello world!');

See more details on plugins in Listeners below.

Severity levels

mainStory.trace('Teeny-weeny detail: x = 3, y = 4');
mainStory.debug('Called login()');
mainStory.info('User "admin" authenticated successfully');
mainStory.warn('Sad we can\'t show colors in GFM');
mainStory.error('User "admin" could not be authenticated', { attach: err });
mainStory.fatal('Ooops! Crashed! Mayday!', { attach: fatalError });
// ...
// 2016-03-09T16:18:19.659Z           main WARN  Sad we can't show colors in GFM
// 2016-03-09T16:18:19.672Z           main ERROR User "admin" could not be authenticated
// 2016-03-09T16:18:19.672Z           main ERROR   name: 'Error'
// 2016-03-09T16:18:19.672Z           main ERROR   message: 'AUTHENTICATION_ERROR'
// 2016-03-09T16:18:19.672Z           main ERROR   stack: Error: AUTHENTICATION_ERROR
// 2016-03-09T16:18:19.672Z           main ERROR   stack:     at repl:3:11
// ...

Maybe you noticed that the trace call produces no output by default. See Log filtering to fine-tune your filters.

Sources

Namespace your logs for readability, as well as to allow finer-grained filtering later on.

mainStory.info('http', 'GET /api/item/25');
mainStory.info('db', 'Fetching item 25...');
// 2016-03-09T16:29:51.943Z           http INFO  GET /api/item/25
// 2016-03-09T16:31:52.231Z             db INFO  Fetching item 25...

Colors

Use colors to emphasize/de-emphasize parts of your logs:

import { mainStory, chalk } from 'storyboard';
mainStory.info('http', `GET ${chalk.green.bold('/api/item/26')}`);
mainStory.info('db', `Fetching item ${chalk.green.bold('26')}...`);
// 2016-03-09T16:29:51.943Z           http INFO  GET /api/item/26
// 2016-03-09T16:31:52.231Z             db INFO  Fetching item 26...

As seen above, we recommend using the popular chalk library by Sindre Sorhus. Chalk is automatically extended by Storyboard for use in the browser. If you prefer another ANSI-color library, make sure it's universal and doesn't disable itself automatically in the browser.

Attachments

Attach anything to your logs that might provide additional context: an object, an array, an exception, a simple value... Don't worry about circular references, long buffers, or undefined! Use the attach option to display it as a tree, or attachInline for a more compact, JSON.stringify-ed version.

You can also use the attachLevel option to control the (severity) level of the detailed object logs (by default: the same level of the main logged line). Pro tip: use the trace level for long attachments (hidden by default), so that they don't pollute your console but are still accessible via the Storyboard DevTools extension.

mainStory.info('test', 'A simple object', { attachInline: obj1 });
// 2016-03-09T16:51:16.436Z           test INFO  A simple object -- {"foo":2,"bar":3}
mainStory.info('test', 'An object with a circular reference', {
  attach: obj2,
  attachLevel: 'debug',
});
// 2016-03-09T16:52:48.882Z           test INFO  An object with a circular reference
// 2016-03-09T16:52:48.882Z           test DEBUG   foo: 2
// 2016-03-09T16:52:48.882Z           test DEBUG   bar: 3
// 2016-03-09T16:52:48.882Z           test DEBUG   circularRef: [CIRCULAR]
mainStory.info('test', 'This message is logged', {
  attach: butThisHugeObjectIsNot,
  attachLevel: 'trace',
});
// 2017-02-17T16:03:23.124Z           test INFO  This message is logged
// [attachment is hidden; inspect it in the Storyboard DevTools]

Note: attach and attachInline have no effect on the way attachments are shown in the Storyboard DevTools.

Log filtering

Inspired by the popular debug library, Storyboard allows you to filter logs according to source, specifying white and black lists and using wildcards. Beyond that, you can specify the minimum severity level you are interested in, depending on the source:

  • *:DEBUG (default) or * will include logs from all sources, as long as they have severity debug or higher.
  • *:* will include absolutely all logs.
  • foo or foo:DEBUG will include logs from foo but exclude all other sources.
  • -test, *:* will include all logs, except those from source test.
  • foo, bar:INFO, -test, *:WARN will include logs from foo (DEBUG or higher), bar (INFO or higher), and all other sources (WARN or higher), but exclude source test.
  • ba*:*, -basket will include all logs from bar, baz, etc. but exclude source basket.

In Node, you can configure log filtering via the STORYBOARD environment variable (have a look at cross-env for a cross-platform setup):

# OS X / Linux
$ STORYBOARD=*:* node myScript

# Windows
$ set "STORYBOARD=*:*" && node myScript

In the browser, use localStorage:

localStorage.STORYBOARD = '*:*'

Alternatively, you can configure the log filters programatically:

import { config } from 'storyboard';
config({ filter: '*:*' });

And even more convenient: configure filters remotely and without reloading by using the Storyboard DevTools.

Children stories

Create child stories by calling child() on the parent story and passing an options argument. Don't forget to close() the child story when you're done with it! More on child stories here.

const story = mainStory.child({
  src: 'lib',
  title: 'Little Red Riding Hood',
  level: 'DEBUG',
});
story.info('Once upon a time...');
story.warn('...a wolf appeared!...');
story.info('...and they lived happily ever after.');
story.close();
// 2016-03-19T14:10:14.080Z        lib DEBUG ┌── Little Red Riding Hood [CREATED]
// 2016-03-19T14:10:14.083Z       main INFO  Once upon a time...
// 2016-03-19T14:10:14.085Z       main WARN  ...a wolf appeared!...
// 2016-03-19T14:10:14.087Z       main INFO  ...and they lived happily ever after.
// 2016-03-19T14:10:14.088Z        lib DEBUG └── Little Red Riding Hood [CLOSED]

Pro tip: Child stories have INFO level by default, and can be completely hidden by log filtering. However, when a log with level WARN or higher is added to a hidden story, the story and all of its ancestors will become visible. You will not miss any errors, nor the actions that led to them!

Listeners (plugins)

Logs emitted by stories are relayed by the Storyboard Hub to all attached listeners. A Hub exists at the core of every Storyboard instance. Here is an example of a typical configuration, with server and client-side Hubs (other use cases have proved possible in production):

Typical configuration

Several listeners are readily available as separate packages:

  • Console (storyboard-listener-console): formats logs and sends them to the console (also in the browser).

  • Parallel Console (storyboard-listener-console-parallel): shows parallel, top-level stories in the console, with support for resizing.

  • WebSocket Server (storyboard-listener-ws-server): encapsulates logs and pushes them to WebSocket clients. Used jointly with the WebSocket Client and Browser Extension, it allows remote access to server stories.

  • WebSocket Client (storyboard-listener-ws-client): downloads logs from the WebSocket Server, and optionally uploads client logs to the server for remote monitoring.

  • Browser Extension (storyboard-listener-browser-extension): relays logs to the Storyboard DevTools.

  • File (storyboard-listener-file): saves logs to file.

  • PostgreSQL Database (storyboard-listener-db-postgres): saves logs to a PostgreSQL database, including attachments, story hierarchy, etc.

Check out the full listener configuration options.

More listeners can be added by the user (see the API), e.g. to support different databases, integrate with other services, etc. Get inspired by winston's and bunyan's plugins.

Remote access to server stories

Standalone log server

The simplest way to add remote access to a Node application's logs is to enable the WebSocket Server listener:

// Server
import { addListener } from 'storyboard';
import wsServerListener from 'storyboard-listener-ws-server';
addListener(wsServerListener);

You now have a standalone HTTP server at port 8090 (by default) and can use the Storyboard DevTools to see your logs.

Integrated log server

You can also integrate the log server functionality with your own application server. This may be desirable if you want to use a single port, or if you want to see end-to-end stories. In this case, your client application should enable the WebSocket Client and Browser Extension listeners:

// Client
import { addListener } from 'storyboard';
import wsClientListener from 'storyboard-listener-ws-client';
import browserExtListener from 'storyboard-listener-browser-extension';
addListener(wsClientListener);
addListener(browserExtListener);

At the server side, initialize the WebSocket Server listener with either your http Server instance, or your socket.io Server instance, depending on your case:

// If your application doesn't use WebSockets:
import express from 'express';
import http from 'http';
const httpServer = http.createServer(express());
httpServer.listen(3000);
addListener(wsServerListener, { httpServer });

// If your application uses socket.io WebSockets without socket auth:
import socketio from 'socket.io';
const socketServer = socketio(httpServer);
addListener(wsServerListener, { socketServer });

// If your application uses sockets with auth, namespace them
// so that they don't clash with the log server's:
// At the server...
const io = socketServer.of('/myApp');
io.use(myAuthMiddleware);
io.on('connection', myConnectFunction);
// ...and at the client:
const socket = socketio.connect('/myApp')

Now when you open your client-side application, you can see both server and client logs in the Storyboard DevTools.

User authentication

You can add prevent unauthorized access to your logs via a listener option:

addListener(wsServerListener, {
  authenticate: ({ login, password }) => isAuthorized(login, password),
});

Remote access to client stories

In some cases, you may want to remotely monitor client logs, e.g. if you are building a mobile web app, or you want to see the logs generated in non-Chrome browsers for which there is (currently) no browser extension.

For these cases, you can configure your WebSocket Client listener so that it uploads its logs to the server, which can then provide remote access to them:

import { addListener } from 'storyboard';
import wsClientListener from 'storyboard-listener-ws-client';
addListener(wsClientListener, { uploadClientStories: true });

Client logs will not pollute the server's own log, and will appear as a separate remote client story in the Storyboard DevTools, along with a short description of the remote platform:

Remote monitoring

End-to-end stories

The icing on the cake is linking server- and client-side stories to get a complete picture of what is triggered by a user action (see video at the top of this page).

Storyboard provides a simple yet flexible way to achieve this: stories can have multiple parents, which are specified upon creation. This feature is leveraged by the Storyboard DevTools: when it receives a new story from the server with multiple parents, it checks whether any of the parents is a client-side story. If so, it prioritizes this parent for display purposes, since it is expected to provide more context.

For this to work, the client's storyId must be transmitted to the server somehow. This example uses the URL query string for simplicity, but feel free to use whatever technique you want (the body of a POST request, your own WebSocket messaging scheme, etc.):

// Client:
const onClick = async () => {
  const story = mainStory.child({
    src: 'itemList',
    title: 'User click on Refresh',
  });
  try {
    story.info('itemList', 'Fetching items...');
    const response = await fetch(`/items?storyId=${story.storyId}`);
    const items = await response.json();
    story.info('itemList', `Fetched ${items.length} items`);
  } finally {
    story.close();
  }
};

// Server (using Express):
import express from 'express';
const app = express();
app.get('/items', (req, res) => {
  const { storyId } = req.query;
  const story = mainStory.child({
    src: 'http',
    title: `HTTP request ${req.url}`,
    extraParents: storyId != null ? [storyId] : undefined,
  });
  story.info('http', 'Processing request...');
  // ...
  res.json(items);
  story.close();
});

Want to see the end-to-end story? Use the Storyboard DevTools extension.

Note: end-to-end stories work better when server and client system clocks are not too different. Servers are typically NTP-synchronized, as are most modern PCs with Internet access. If this is not the case, enable Storyboard's time synchronization function (available since v2.0.0):

import { addListener } from 'storyboard';
import wsClientListener from 'storyboard-listener-ws-client';
addListener(wsClientListener, { clockSync: true });

Storyboard DevTools

Storyboard DevTools

Enable the link to the browser extension in your application:

import { addListener } from 'storyboard';
import browserExtListener from 'storyboard-listener-browser-extension';
addListener(browserExtListener);

After installing the Chrome extension, open the Chrome DevTools, select the Storyboard pane and point your browser at either:

  • Your standard application URL, to see both server and client logs
  • Port 8090 (configurable) of your server, to see server logs only (+ uploaded client logs)

Some highlighted features:

  • Modify the server's filter configuration without restarting it.
  • Show stories chronologically (flat) or hierarchically (tree): hover on the story title for the button to appear.
  • Collapse/expand stories: click on the caret. Even when stories are collapsed, detect that they contain an error or warning thanks to a special icon.
  • Open attachments and exceptions: click on the folder icon.
  • Choose among 3 timestamp formats: UTC, local or relative to now: click on any timestamp.
  • Set reference timestamps: right-click or control-click on any timestamp.
  • Use quick find (case-insensitive) to highlight what you're looking for.
  • Squash identical, consecutive messages into a convenient summary line.
  • Configure when and how Storyboard forgets old logs and stories.
  • Customize colors to your heart's content!

You can check out your new extension navigating to: https://storyboard-examples-ifkpkpoyhz.now.sh/ (might be a bit slow at first; free hosting!)

Storyboard DevTools is built with React, Redux and Redux-Saga.

Changelog :scroll:

License (MIT) :books:

Copyright (c) Guillermo Grau Panea 2016-now

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

changelog (log de mudanças)

3.3.2 (2021-2-7)

3.3.1 (2021-2-7)

3.3.0 (2021-2-7)

  • Library: add short IDs to distinguish between parallel stories (displayed in console).

3.2.1 (2019-12-28)

3.2.0 (2019-12-28)

  • Library: add chalk to all stories.

3.1.4 (2018-8-14)

  • Bump some deps to fix vulnerabilities detected by GitHub.

3.1.3 (2017-8-16)

3.1.2 (2017-3-17)

  • Bugfix: fix a situation in which the Parallel Console would scroll and mix up all parallel stories.

3.1.1 (March 1, 2017)

  • Library:
    • Bugfix: make Parallel Console compatible with zero-height terminals (e.g. in Travis CI builds).
  • Common:
    • Bugfix: recover colors in log levels and sources, both in the Chrome Extension and in the browser-side Console Listener.

3.1.0 (February 27, 2017)

  • New Parallel Console listener: shows parallel, top-level stories in the console, with support for resizing. It should work correctly in the following terminals:

    • OS X: Terminal.app (default terminal), iTerm, Hyper
    • Windows: cmd (default terminal), Console 2, Hyper

3.0.0 (February 18, 2017)

Breaking change

  • All Storyboard listeners/plugins are now available as separate packages. Following the steps of Babel and others, Storyboard no longer comes with everything but the kitchen sink built in. In other words, you need to add your listeners to your package.json, for example:

    "dependencies": {
      "storyboard": "^3.0.0",
      "storyboard-listener-console": "^3.0.0",
      "storyboard-listener-ws-server": "^3.0.0",
      "storyboard-listener-ws-client": "^3.0.0",
      "storyboard-listener-browser-extension": "^3.0.0",
    }

    ...but in exchange you won't be dragging in express, socket.io, socket.io-client when you're only interested in the console, or pg when you have no database in sight.

    Enabling listeners is pretty much the same as in Storyboard v2, only loaded from the separate package:

    import { mainStory, addListener } from 'storyboard';
    import consoleListener from 'storyboard-listener-console';
    addListener(consoleListener, options);
    
    mainStory.info('Hi there!');

    For convenience, a console preset is provided (make sure you add both storyboard-preset-console and storyboard to your package.json file):

    import 'storyboard-preset-console';
    import { mainStory } from 'storyboard';
    
    mainStory.info('Hi there!');

    Nerdy note: Storyboard is now a monorepo, i.e. separate packages, all under one roof, glued together with yarn a tool called oao.

Other changes

  • Browser extension:
    • [M] The user can now set reference timestamps via ctrl-click or right-click on a timestamp. When set, all other timestamps are displayed as relative to the reference.
    • [m] Add usage hints (popping up when first the app is first used, as well as when the user clicks on the dedicated button)

2.3.2 (February 17, 2017)

  • Management release (no changes).

2.3.1 (December 14, 2016)

  • Library:
    • Avoid cumbersome deprecation warning from Node when enabling the file listener.

2.3.0 (November 23, 2016)

  • Internal:
    • [M] Completed migration from CS to JS. I hope I didn't break anything, despite the large test suite! Note on the decreased test coverage figure: the new figure (~82%) is more accurate, since it now includes files that were previously not pulled in (or instrumented) by the tests, notably action creators in the browser extension. Test coverage for the library is around 98%, same as before the migration.
  • Browser extension:
    • Bugfix fix a case in which forgetHysteresis and maxRecords settings could not be modified due to incoming messages resetting these parameters.

2.2.0 (October 19, 2016)

  • Library:
    • [M] Flow API: if you use Flow in your project, you will be able to typecheck against Storyboard's API. No configuration is required.
    • [m] Add onChangeFilter hook to allow saving the backend filter config after being modified through the browser extension.

2.1.2 (September 20, 2016)

  • Library:
    • Bugfix: move socket.io-client to dependencies (was inadvertently moved to devDependencies)

2.1.1 (September 9, 2016)

  • Browser extension:
    • Fix a bug derived from the change in CSS property webkit-user-select in the latest Chrome release.

2.1.0 (August 16, 2016)

  • Browser extension:
    • [M] Allow customising the application's colours, including presets.
    • [m] Settings: add revert to defaults option.

2.0.2 (July 26, 2016)

  • Library:

    • [m] Add withConsoleListener.js convenience initialiser, for the most common case in which we just want to attach a console listener:

      import { mainStory } from 'storyboard/lib/withConsoleListener';
      
      mainStory.info('That was fast!');

2.0.1 (July 18, 2016)

  • Minor documentation changes.

2.0.0 (July 18, 2016)

Breaking changes

  • No listeners are installed by default. The default behaviour in v1 was to automatically install some listeners, depending on whether Storyboard ran on the server or the client and the development/production mode. This was very convenient out of the box, but made it harder to customize the configuration in certain setups. If you need the old default behaviour, use this (note that for conditionally bundling listeners we recommend sticking to require for the time being):

      import { addListener } from 'storyboard';
    
      // Server
      import consoleListener from 'storyboard/lib/listeners/console';
      addListener(consoleListener);
    
      // Client
      if (process.env.NODE_ENV !== 'production') {
          addListener(require('storyboard/lib/listeners/console').default);
          addListener(require('storyboard/lib/listeners/browserExtension').default);
          addListener(require('storyboard/lib/listeners/wsClient').default);
      }
  • Listeners have been migrated to ES6. Notice above the different way to use them, depending on whether you import them (ES6 module) or require them (CommonJS):

      // ES6 module
      import fileListener from 'storyboard/lib/listeners/file';
      addListener(fileListener);
    
      // CommonJS module
      const fileListener = require('storyboard/lib/listeners/file').default;
      addListener(fileListener);
  • The Console listener no longer uses stderr on Node, to avoid out-of-order logs (see this link for some background); it now uses stdout for all log levels. If you want the old behaviour, configure it with useStderr: true. On the browser, console.error() is used as before.

Other changes

  • Add a command-line interface (CLI) tool to use Storyboard on unmodified applications/modules (i.e. without requiring the use of the library). This tool wraps the application and allows redirecting the logs to a file, the console and/or the web (using the WebSocket Server listener). In principle, this makes any application compatible with the Storyboard DevTools. More details here.
  • Library:
    • [M] Implement a refined listener architecture, affecting in particular the client side. These changes should be transparent to the user. The WsClient listener no longer interfaces directly with the browser extension, but rather relays its messages via the hub. The BrowserExtension listener has been merged with the interfaceExtension helper, since no other module can have access to this interface any more. This architecture is more flexible and will allow other uses of the library, e.g. using the WsClient listener in a non-browser application to obtain logs from another process and offload database access or file storage.
    • [M] WebSocket Server and Client can now estimate their clock differences, so that timestamps correspond to (approximately) the client's system clock. This functionality is disabled by default, but can be opted in by setting clockSync: true in the WebSocket Client configuration.
    • [M] Add Postgres database listener: stores logs to a PostgreSQL database, including attachments.
    • [M] Add file listener: stores all logs to a file, with or without ANSI color escapes (disabled by default).
    • [M] Better attachment serialization. undefined values will no longer disappear from your attachments when they traverse the WebSocket interface between the WsServer and WsClient plugins.
    • [m] Improve graceful exits, tearing down all listeners if possible. Previously, we only closed the main story.
  • Browser extension:
    • [m] Settings: show version.
    • Bugfix: Settings: Fix hysteresis tooltip.
  • Internal:
    • Ongoing migration from CoffeeScript to JS.

1.4.0 (June 29, 2016)

  • Browser extension:
    • [M] Improve behaviour when server restarts (always download the server's new records)
    • [m] Click on the warning icon in a story title to expand the story.

1.3.1 (June 29, 2016)

  • [m] Show buffers nicely within attachments.
  • Bugfix: Correct serialization of exceptions.
  • Bugfix: Fix an issue in the browser extension where an incorrect attachment would be open when clicked upon after a server reset.

1.3.0 (June 9, 2016)

  • Browser extension:
    • [m] Use Giu components for the UI
    • [m] Add some validation on the settings
    • [m] Simplify cxReducer state
    • [m] Fix panel charset (required for Redux devtools)
  • Lib:
    • [M] Attach objects in their original shape (not simplified), after removal of possible circular refs
    • [m] Add stdinLogger tool (result from issue #11): use it to log via Storyboard the output of any command, e.g. ls | node stdinLogger.js
    • [m] Fix incorrect filter config when user enters a blank string

1.2.0 (Apr. 19, 2016)

  • Browser extension:
    • [M] Allow the user to configure the filters used by the server and local client
    • [M] Add warning icon to collapsed stories containing warnings/errors
    • [m] Allow the user to filter out client root stories from other clients
  • Lib:
    • [m] Internal: the Storyboard entry point now just re-exports the noPlugins API, enabling listeners as in the previous version (hence, non-breaking change)

1.1.1 (Apr. 12, 2016)

  • Lib:
    • [M] Fix a regression concerning the client side of the server logs (standalone) app: plugins were not included in the minified/production version

1.1.0 (Apr. 12, 2016)

  • Lib:
    • [M] Add remote log monitoring: logs can be uploaded by the WS Client listener, e.g. from mobile devices or non-Chrome browsers, and monitored from a remote Storyboard DevTools somewhere else.
    • [M] Split WS Client listener in two:
      • WS Client listener (dedicated just to WebSockets)
      • Browser Extension listener (relays client-side logs to the browser extension)
    • [M] Include a no-plugins version of Storyboard (at storyboard/lib/noPlugins), which might become default in future major releases. Using this version prevents socket.io from getting into your bundle, if you don't need it.
  • Browser extension:
    • [M] For servers requiring no auth for logs: Automatically retrieve server backlog upon startup
    • [m] Bumped React to v15.0.1

1.0.0 (Apr. 5, 2016)

  • Enforce semver
  • Lib:
    • [m] Publish chalk as part of the top-level API: storyboard.chalk. This is for convenience, as well as to prevent duplicate instances of chalk in certain setups (should not happen anyway if you use npm@3 and include chalk@^1.0.0).

0.1.3 (Mar. 30, 2016)

  • Browser extension:
    • [M] Add shorthand representation for "identical, consecutive logs"
    • [m] Allow user configuration of the maximum number of logs/stories to be remembered
    • Thorough testing of storyReducer
    • Add tests for all other reducers

0.1.2 (Mar. 28, 2016)

  • Lib:
    • Add unit tests for most modules
  • Browser extension:
    • [M] Add the capability to forget logs and closed stories
    • Add very limited unit tests (concerning the storyReducer)
  • Tooling:
    • Use nyc instead of istanbul for coverage testing (simplifies merging coverage reports)

0.1.1 (Mar. 19, 2016)

Not a breaking change, but still noteworthy: Stories now have a level attribute and are subject to filtering, the same way as logs. The default story level is INFO. Depending on your filter configuration, you may start filtering out some stories.

  • Lib:
    • Stories:
      • [M] Add level attribute to stories (same as for logs)
      • [M] Filter out stories completely according to source and level, even if they contain logs that would have been visible (up to INFO level). Logs at WARN or above turn their ancestor stories visible again.
    • Console Listener:
      • [m] Show story levels
      • [m] Hide story ID
      • [m] Hide time in attachment lines (just as in the browser extension)
      • [m] Highlight action lines
    • WS Client Listener:
      • [m] Stop dumping internal Storyboard messages to the console
  • Browser extension:
    • [m] Swap severity and source columns for coherence with console output
    • [m] Show story levels
    • [m] Tweak style of some components

0.1.0 (Mar. 15, 2016)

  • First public release