Giter VIP home page Giter VIP logo

timbergeist's Introduction

Timbergeist: A flexible typescript logging framework

Features

๐Ÿชถ Lightweight (1 runtime dependency)
๐Ÿ— Universal: Works in Browsers and Node.js
๐Ÿ‘ฎโ€๏ธ Fully typed even with custom Metadata
๐Ÿ—ƒ Structured logging - JSON-first with built in pretty print transforms
๐Ÿฆธ Plugable transports and transformers
๐Ÿค“ Stack trace and pretty errors
๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ฆ Child-logging hierarchies with proper feed-through

Design Rationale

Child Loggers and Log Propagation

Log Object Format

In Timbergeist logs are represented by a collection of javascript objects. There is no concept of a format strings or log id etc. Timbergeist is built to be flexible enough that these features can be built on top in a straight forward way.

Once serialised, the object structure could look something like this:

{
    "0": { "foo": 0, "bar": { "cee": 5 }},
    "1": "Hello logs!",
    "_meta": {
        "__tgLogFormatVersion": 1,
        "logLevelId": 3,
        "logLevelName": "INFO",
        ...
    }
}

Usage

Quickstart

import { Logger } from "@soundboks/timbergeist"

const RootLogger = new Logger()

RootLogger.info("Hello World")

Custom Transports with different logs

In this example we submit JSON logs to a HTTP endpoint and still pretty print logs to the console. We also make sure to submit all log levels via HTTP, but only print level 3 or higher to the console to avoid clutter.

import { ConsoleSink, Logger, PrettyPrinterTransport } from "@soundboks/timbergeist";

const LOG_LEVEL_INFO = 3;
const LOG_LEVEL_DEBUG = 2;

// our "hidden" logger which is actually responsible for printing
const _RootLogger = new Logger(
	{
		minLevel: process.env["NODE_ENV"] === "production" ? LOG_LEVEL_INFO : LOG_LEVEL_DEBUG,
	},
	[
		new PrettyPrinterTransport(ConsoleSink, {
			prettyLogTemplate: "{{hh}}:{{MM}}:{{ss}}:{{ms}} {{logLevelName}} {{name}} ",
		}),
	]
);

// our exported Root Logger, which has a lower minLevel than our hidden logger
export const RootLogger = _RootLogger.getSubLogger({
	minLevel: 0,
});

RootLogger.attachTransport({
	transport(logArgs, meta) {
        const message = {
            ...logArgs,
            _meta: meta,
        }

        // In a real application you should use a batching mechanism of some sort
        fetch("https://api.foobar.com/logs/intake", {
            Body: JSON.stringify(message)
        })
    }
});

Reconstructing string logs from JSON log objects

import { ConsoleSink, PrettyPrinterTransport } from "@soundboks/tslog"

const printer = new PrettyPrinterTransport(ConsoleSink, {
    prettyLogTemplate: "{{hh}}:{{MM}}:{{ss}}:{{ms}} {{logLevelName}} {{name}} ",
});

const log = MY_LOGS[0] // one log object in timbergeist format
const collectedArgs: unknown[] = []
for (let i = 0; Object.keys(log).includes(i.toString()); i++) {
    collectedArgs.push(log[i])
}

printer.transport(collectedArgs, log._meta)

Differences from Tslog

  • Masking as a feature has been removed entirely

Acknowledgements

Timbergeist started out as a internal fork of Tslog.

timbergeist's People

Contributors

nyrox avatar dabs avatar

Watchers

 avatar Rasmus Letterkrantz avatar

timbergeist's Issues

Bug: Automatic source location is broken in some circumstances

The way we search through stack traces when logging produces some weird results sometimes. Notably when running ts-node 10.9.2 / node 18, on my machine it produces /Users/nyrox/dev/soundboks/forkbeard/node_modules/@soundboks/timbergeist/dist/cjs/Logger.js:91. This sucks for 2 reasons:

    1. That source location is inside Timbergeist, not in my code
    1. It is a really long path, which pollutes my terminal

Action items:

  • Find the source of the path mis-location
  • Set up test suites for different runtimes to prevent regressions
  • Figure out if we can un-absolutize the paths, i.e. this path when transformed to be relative to my working directory should be ../../node_modules/@soundboks/timbergeist/dist/cjs/Logger.js:91. Note the ../../, which might make this a bit harder to do cleanly.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.