npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

timber

v3.1.3

Published

Timber.io node client.

Downloads

370

Readme

🌲 Timber - Great Node Logging Made Easy

CircleCI Coverage Status npm version ISC License

Node logging has problems. The average node project has libraries logging to the console, internal logs using winston or bunyan, and frameworks logging in their own format. The end result is usually this:

192.442.345.32 - - [Mon, 09 Oct 2017 23:23:37 GMT] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"
Log message from console.warn
{"level":"debug","message":"Log message from winston"}

Timber solves this by normalizing and augmenting your logs with structured data, regardless of the source. This not only normalizes your logs, but captures additional useful metadata:

GET / HTTP/1.1 @metadata {"dt": "2017-10-08T23:23:37.234Z", "level": "info", "context": {"http": {"remote_addr": "192.442.345.32"}}, "event": {"http_request": {"method": "GET", "path": "/", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"}}}
Log message from console.warn @metadata {"dt": "2017-10-08T23:23:37.234Z", "level": "warn"}
Log message from winston @metadata {"dt": "2017-10-08T23:23:37.234Z", "level": "debug"}

Ah! Consistent, easy to use logs. To get started:

  1. Installation - Simple setup
  2. Usage - Clean API. Works with console, winston, and bunyan.
  3. Integrations - Automatic context and metadata for your existing logs
  4. The Timber Console - Beautiful, fast, and designed for developers
  5. Get things done with your logs 💪

Installation

Signup at timber.io and follow the in-app instructions.

For those interested in manual instructions, see the timber.io installation docs.

Usage

No special API, Timber works directly with your logger of choice:

// console
console.log("My log message")
console.info("My log message")
console.warn("My log message")
console.error("My log message")

// winston
winston.info("My log message")
winston.warn("My log message")
// ...

// bunyan
logger.info("My log message")
logger.warn("My log message")
// ...

Log structured data without sacrificing readability:

// console
console.warn("Payment rejected", {
  event: {
    payment_rejected: { customer_id: "abcd1234", amount: 100, reason: "Card expired" }
  }
});

// winston
winston.warn("Payment rejected", {
  event: {
    payment_rejected: { customer_id: "abcd1234", amount: 100, reason: "Card expired" }
  }
});

// bunyan
logger.warn({
  event: {
    payment_rejected: { customer_id: "abcd1234", amount: 100, reason: "Card expired" }
  }
}, "Payment rejected");

Context for node is coming soon! Because node does not have a concept of local storage, we're working to implement continuation local storage. This will enable shared join data across your logs, allowing you to relate them.

Star / watch this repo to be notified when this goes live!

Configuration

If you're using express, you can use the timber middleware to automatically log all http request/response events

const express = require('express')
const timber = require('timber')

// first we create a writeable stream that your logs will get sent to
const transport = new timber.transports.HTTPS('your-timber-api-key');

// attach the stream to stdout
timber.install(transport);

// create our express app
const app = express()

// attach the timber middleware
app.use(timber.middlewares.express())

app.get('/', function (req, res) {
  res.send('hello, world!')
})

// Output:
// => Started GET "/" @metadata {"level": "error", "context": {...}}
// => Outgoing HTTP response 200 in 2ms @metadata {"level": "error", "context": {...}}

The express middleware accepts a single argument for configuration options. To learn more about the available options, visit the express integration docs


If you're using winston, you can use the winston transport to send all of winston's logs to timber.io

const winston = require('winston')
const timber = require('timber')

const transport = new timber.transports.HTTPS('your-api-key')
timber.install(transport)

winston.remove(winston.transports.Console)
winston.add(winston.transports.Console, {
  formatter: timber.formatters.Winston
})

winston.log('info', 'Sample log message')

// Output:
// => Sample log message @metadata {"level": "info", ... }

When you pass a metadata object to winston, timber will automatically augment your log line with it:

winston.log('info', 'Log message with metadata', { user: 'username' })

// Output:
// => Log message with metadata @metadata {"level": "info", meta: { user: 'username' }, ... }

You can augment your log with a custom event by providing an event key at the root of your metadata object:

winston.log('info', 'Log message with event', { event: custom_event_name: { ... } })

// Output:
// => Log message with event @metadata {"level": "info", event: { custom_event_name: { ... } }, ... }

Adding custom context is just as easily done by adding the context key to the root of your metadata object:

winston.log('info', 'Log message with event', { context: { ... } })

// Output:
// => Log message with event @metadata {"level": "info", context: { ... }, ... }

If you're using the timber express middleware, you'll most likely want to configure it to use winston as the logger. This can be done by setting the logger config attribute to winston:

timber.config.logger = winston

If you're using bunyan, you can use the bunyan transport to send all of bunyan's logs to timber.io

const bunyan = require('bunyan')
const timber = require('timber')

const winston = require('winston')
const timber = require('timber')

const transport = new timber.transports.HTTPS('your-api-key')
timber.install(transport)

const log = bunyan.createLogger({ name: 'Timber Logger' })

log.info('Sample log message')

// Output:
// => Sample log message @metadata {"level": "info", ... }

If you want to augment your log with custom metadata, simply add an object as the first argument:

log.info({ user: 'username' }, 'Log message with metadata')

// Output:
// => Log message with metadata @metadata {"level": "info", meta: { user: 'username' }}, ... }

You can augment your log with a custom event by providing an event key at the root of your metadata object:

log.info({ event: { custom_event_name: { ... } } }, 'Log message with event')

// Output:
// => Log message with event @metadata {"level": "info", event: { custom_event_name: { ... } }, ... }

Adding custom context is just as easily done by adding the context key to the root of your metadata object:

log.info({ context: { ... } }, 'Log message with event')

// Output:
// => Log message with event @metadata {"level": "info", context: { ... }, ... }

If you're using the timber express middleware, you'll most likely want to configure it to use bunyan as the logger. This can be done by setting the logger config attribute to the bunyan logger you created:

timber.config.logger = log

By default, Timber makes attaching to stdout and stderr very easy through the convenient timber.install(transport) function. However, it's possible to attach the transport to any writeable stream using the timber.attach() function!

const transport = timber.transports.HTTPS('timber-api-key')

// This is what the install() command is doing:
timber.attach([transport], process.stdout)
timber.attach([transport], process.stderr)
// => This sends all logs from stdout directly to Timber

// You can attach multiple unique transport streams to each stream:
const file_transport = fs.createWriteStream("./output.log", {flags: "a"})
timber.attach([transport, file_transport], process.stdout)
// => This sends all logs from stdout to Timber, stdout, and a custom log file

Integrations

Timber integrates with popular frameworks and libraries to capture context and metadata you couldn't otherwise. This automatically augments logs produced by these libraries, making them easier to search and use. Below is a list of libraries we support:

...more coming soon! Make a request by opening an issue

Get things done with your logs

Logging features designed to help developers get more done:

  1. Powerful searching. - Find what you need faster.
  2. Live tail users. - Easily solve customer issues.
  3. Viw logs per HTTP request. - See the full story without the noise.
  4. Inspect HTTP request parameters. - Quickly reproduce issues.
  5. Threshold based alerting. - Know when things break.
  6. ...and more! Checkout our the Timber application docs

The Timber Console

Timber Console

Learn more about our app.

Your Moment of Zen

The Timber Console

Timber Console

Learn more about our app.

Your Moment of Zen