Package detail

@studio/log

javascript-studio11.4kMIT2.1.3

A tiny streaming ndJSON logger

log, stream, format, json

readme

Studio Log 2

👻 Log ndjson to an output stream, pretty print the output with emoji ✨

Note! Version 2 has significantly changed compared to the original announcement. Make sure to read the release notes for migration instructions!

Features

  • API designed to produce expressive source code.
  • Uses topics instead of log levels for more fine grained filtering.
  • Uses object streams to avoid serialize -> parse -> serialize when used in a command line application.
  • Disabled by default. If no output stream is specified, no logs are written.

Usage

Log output is disabled by default to ensure logs don't get in the way when writing unit tests. Therefore you want to set this up as the first thing in your main:

// Sending raw ndJSON logs to stdout, e.g. in a server application:
const Stringify = require('@studio/ndjson/stringify');
require('@studio/log')
  .pipe(new Stringify())
  .pipe(process.stdout);

// Sending fancy formatted logs to stdout, e.g. in a command line tool:
const Format = require('@studio/log-format/fancy');
require('@studio/log')
  .pipe(new Format())
  .pipe(process.stdout);

// Sending logs to console.log, e.g. in a browser:
const Format = require('@studio/log-format/console');
require('@studio/log')
  .pipe(new Format())

Next, create a logger instance in a module and start writing logs:

const logger = require('@studio/log');

const log = logger('app');

exports.startService = function (port) {
  log.launch('my service', { port: 433 });
};

In the server example above, this output is produced:

{"ts":1486630378584,"ns":"app","topic":"launch","msg":"my service","data":{"port":433}}

Send your logs to the emojilog CLI for pretty printing:

❯ cat logs.ndjson | emojilog
09:52:58 🚀 app my service port=433

Install

❯ npm i @studio/log

Topics

Instead of log levels, this logger uses a set of topics. Unlike log levels, topics are not ordered by severity.

These topics are available: ok, warn, error, issue, ignore, input, output, send, receive, fetch, finish, launch, terminate, spawn, broadcast, disk, timing, money, numbers and wtf.

Topics and their mapping to emojis are defined in the Studio Log Topics project.

Log format

  • ns: The logger instance namespace.
  • ts: The timestamp as returned by Date.now().
  • topic: The topic name.
  • msg: The message.
  • data: The data.
  • stack: The stack of error object.
  • cause: The cause stack of error.cause object, if available.

API

Creating a logger

  • log = logger(ns[, data]): Creates a new logger with the given namespace. The namespace is added to each log entry as the ns property. If data is provided, it is added to each log entry. Multiple calls with the same ns property return the same logger instance while data is replaced.
  • log.child(ns[, data]): Creates a child logger of a log instance. The namespaces are joined with a blank and data is merged. Multiple calls with the same ns property return the same logger instance while data is replaced.

Log instance API

  • log.{topic}([message][, data][, error]): Create a new log entry with these behaviors:
    • The topic is added as the "topic".
    • If message is present, it's added as the "msg".
    • If data is present, it's added as the "data".
    • If error is present, the stack property of the error is added as the "stack". If no stack is present, the toString representation of the error is used.
    • If error.code is present, it is added to the "data" without modifying the original object.
    • If error.cause is present, the stack property of the cause is added as the "cause". If no stack is present, the toString representation of the cause is used.
    • If error.cause.code is present, a cause object is added to the "data" with { code: cause.code } and without modifying the original object.

Module API

  • logger.pipe(stream): Configure the output stream to write logs to. If not specified, no logs are written. Returns the stream.
  • logger.hasStream(): Whether a stream was set.
  • logger.reset(): Resets the internal state.

Transform streams

Transform streams can be used to alter the data before passing it on. For example, Studio Log X is a Transform stream that can remove confidential data from the log data and Studio Log Format project implements the basic, fancy and console pretty printers.

Format transforms are node transform streams in writableObjectMode. Here is an example implementation, similar to the ndjson stringify transform:

const { Transform } = require('stream');

const ndjson = new Transform({
  writableObjectMode: true,

  transform(entry, enc, callback) {
    const str = JSON.stringify(entry);
    callback(null, `${str}\n`);
  }
});

Related modules

License

MIT

Made with ❤️ on 🌍

changelog

Changes

2.1.3

  • 🐛 3dbde57 Allow stream to be null
  • 🐛 d23708a Improve log error typing
  • 🐛 de9d125 Fix missing base data when logging error only

Released by Maximilian Antoni on 2024-01-31.

2.1.2

  • 🐛 b786cbd Handle weird errors in stack helper
  • 🐛 112e615 Fix test in Safari

Released by Maximilian Antoni on 2024-01-29.

2.1.1

  • 🐛 88a50b7 Include error message in stack if name is missing
  • 8510c8f Run tests with local safari
  • 318c73b Expose stack helper on logger

Released by Maximilian Antoni on 2024-01-29.

2.1.0

  • 🍏 45073bc Always include error name and message in stack
  • 🍏 7b5934f Add typescript
  • 🐛 03e6a5f Remove broken error handler
  • dff39b6 Use new mochify with esbuild and upgrade mocha
  • 2b22838 Add GitHub action
  • 05886d9 Upgrade Studio Changes
  • 770dc13 Upgrade referee-sinon
  • eb54bac Upgrade eslint config and update eslint

Released by Maximilian Antoni on 2024-01-28.

2.0.0

With this release, Studio Log becomes a tiny 3.3KB library. Formatters and the CLI have been moved to separate modules and with the new console format, Studio Log can be used in browsers too.

The most important API change is the removal of the default transform. Updated examples of how to configure the logger can be found in the README.

  • 💥 3750908 BREAKING: Slim down API

    • Change out to pipe and let it return the stream instead of the logger.
    • Remove transform. Use stream pipes instead.
    • Remove mute and muteAll. Use a custom transform instead.
    • Remove filter. Use a custom trnasform instead.
    • Remove default transform. Add a serializing transform like Studio ndjson to the pipeline yourself.
  • 💥 8da64cc BREAKING: Extract format and CLI modules

    • Move topics into @studio/log-topics module
    • Move format into @studio/log-format module
    • Move emojilog into @studio/emojilog module
  • 📚 612f818 Document v2.0 API changes

  • 📚 eca4548 Improve "Transform streams" documentation
  • 📚 6096722 Use new Studio Changes --commits feature
  • 281934c Add test runner for browser support
  • 583ed68 Use Sinon + Referee

1.7.5

  • 🐛 Adjust whitespace after emoji to be consistent

    With Unicode 9 most emoji are rendered with the correct width now. Some still need an extra space though. This changes the spacing to make them look consistent.

1.7.4

  • 🐛 Log all non-error related cause properties

    Previously, only the code property of the cause error was logged. With this change any property that is not name, message or stack is added to the data.cause object.

1.7.3

  • 🐛 Handle error like objects correctly

1.7.2

  • 🐛 Fix --map if chunks have multiple lines

    When passing --map sourcemaps.map to emojilog, the created transform stream expected each chunk to contain a single line. With this change, the sourcemaps lookup also works for multiline chunks.

  • ✨ Use Sinon 5 default sandbox

  • 📚 Fix typo in message docs

1.7.1

  • 🐛 Fix unwiring filters

    Filters must be unwired before re-configuring. This refactoring also removes some duplication in reset.

1.7.0

  • 🍏 Allow to add filters directly to a child namespace

1.6.0

  • 🍏 Add source maps support

    Use --map source.js.map to specify a source maps file.

1.5.1

  • 🐛 Restore Node 4 compatibility
  • 📚 Add cause.js example
  • 📚 Move demo.js into examples dir

1.5.0

  • 🍏 Serialize the error cause as a new JSON property
  • 🍏 Serialize the error code into the data object
  • 🍏 Serialize the error cause.code into the data object
  • 🍏 Support the new cause property in the basic and fancy formatters
  • 📚 Add new feature to docs and improve usage example and API docs
  • 📚 Add cause example to demo

1.4.1

  • ✨ Add install instructions

1.4.0

  • 🍏 Add global log filter stream support

    A global filter stream can be configured which will receive all log entries before they are passed to the transform stream. This can be used to enrich the log data with generic environment information.

  • 🍏 Add support for logger base data

    When creating a logger, a data property can be passed which will be included in the data of each log entry.

  • 🍏 Add support for child loggers

    Child loggers have their namespace joined with their parent by a blank and the data property of the parent and the child logger are merged.

  • 🍏 Add mute() to logger instance

  • 🐛 Do not invoke filters if out stream was removed

1.3.0

  • 🍏 Add log instance filter stream support

    Filters are object streams to modify the log data before passing it to the transform stream. They can be used to x-out confidential information or add generated information to log entries.

  • ✨ Add npm 5 package-lock.json

1.2.0

The ndjson parsing and serialization was refactored into a separate module. This enables error handling for serialization failures.

  • 🍏 Use the Studio ndjson parser transform
  • 🍏 Handle transform error events. If a transform error occurs, an error message is logged instead of throwing up the stack.
  • 🍏 Replace the internal default transform with the more robust implementation from Studio ndjson.
  • ✨ Make log functions no-ops if no output is given. This avoids pointless JSON.stringify invocations and therefore improves performance a tiny bit.

1.1.1

🐛 Fix screenshot image to work outside of GitHub

1.1.0

🍏 Add hasStream() to the API which returns whether an output stream was set.

1.0.5

Fixes and improvements for the fancy format transform.

  • 🐛 Escape all non-printable characters. Print escape sequences, if available, and fall back to hex values. Do not escape emoji‼️
  • 🐛 Escape newlines and tabs in strings (Fixes #3)
  • 🐛 Format empty objects as {} without blanks (Fixes #1)
  • 🐛 Format primitive data values (Fixes #4)

1.0.4

🙈 Support Node 4

1.0.3

✨ Handle non-json prefix in emojilog. Attempt to parse JSON starting from the first occurrence of the { character. Anything before that is forwarded to stdout.

1.0.2

🐛 Make it work with local symlinks

1.0.1

🙈 Disabled by default

1.0.0

✨ Initial release