View on GitHub

ts-base

Boring things for projects

Download this project as a .zip file Download this project as a tar.gz file

Usage

Console APM

Console has a built in console.time() and console.count(). These can be setup with the CONSOLE_APM configuration.

import {expect} from 'chai';
import {
  bootstrap,
  CONSOLE_APM,
} from '../src';

const appName = 'my-app';
bootstrap({
  appName,
  apm: CONSOLE_APM,
});

Annotating methods with decorators

There are method decorators for counters, timers, and gauges to capture metrics around their execution.

Counters

import {
  CountErrors,
  CountInvocations,
  CountSuccess,
} from '../src';

class Example {
    @CountInvocations()
    @CountSuccess()
    @CountErrors()
    method() {
        console.log('Called');
    }
}

Gauges

import {
  GaugeErrors,
  GaugeInvocations,
  GaugeSuccess,
} from '../src';

class Example {
    @GaugeInvocations()
    @GaugeSuccess()
    @GaugeErrors()
    method() {
        console.log('Called');
    }
}

Timers

import {
  Timed,
  TimedAsync,
} from '../src';

class Example {
    @Timed()
    method(): void {
        console.log('Called sync');
    }

    @TimedAsync()
    async methodAsync(): Promise<void> {
        console.log('Called async');
    }

}

Logging

Console Log

This is a wrapper around console but supports all the logging features like interceptors, message templates, and context suppliers.

You can create one pretty simply.

import {ConsoleLog} from '../src';

const log = ConsoleLog.create({name:'my-log'});

log.info('Hello');

You can also register a root logger and configure the default log level when bootstrapping.

import {
    ConsoleLog,
    bootstrap,
    LogLevel,
    LogConfig,
    templateString,
    Providers,
    Log,
    loadEnvWithObj,
    LOG_ENV,
} from '../src';

const appName = 'my-app';

const config = LogConfig.create({
    rootLevel: LogLevel.WARN,
    messageTemplate: templateString('[${ctx.data.fqn}] ${ctx.message}')
});
const root = ConsoleLog.create({
    name:appName,
    config,
});
bootstrap({
    appName,
    log: {
        root,
    }
});

const log = Providers.provide(Log).extend('sub-log');
console.assert(log.logLevelEnabled(LogLevel.WARN), 'WARN should be enabled');
console.assert(log.logLevelEnabled(LogLevel.INFO) === false, 'INFO should not be enabled');

log.info('Hello world'); // no output
log.warn('Goodbye'); // outputs "[my-app.sub-log] Goodbye"
stderr >
> [my-app.sub-log] Goodbye
stdout >
> my-log: Hello

APM Support for Node

Configuring APM in Node

Currently you have 2 main options, either Prometheus or StatsD. Both support counters, gauges, timers, and histograms.

Prometheus

The Prometheus integration is done with prom-client which has a lot of already built in and automated metrics or integrations.

import { bootstrap } from '@btilford/ts-base';
import {createPrometheusFeature, PromOptions} from '../src';
import {Registry} from 'prom-client';

const appName = 'my-app';
const registry = new Registry();

const options: PromOptions = {
    registry,
    help: '',
    tags: {appName, example:'true'}
};
bootstrap({
    appName,
    // Make the prometheus Registry available by calling Providers.provider(Registry)
    register: [[registry, Registry]],
    apm: {
        features: {
            counter: createPrometheusFeature({
                name:'counter',
                prefix:appName,
                options
            }),
            gauge: createPrometheusFeature({
                name:'gauge',
                prefix:appName,
                options
            }),
            timer: createPrometheusFeature({
                name:'timer',
                prefix:appName,
                options
            }),
            histogram: createPrometheusFeature({
                name:'histogram',
                prefix:appName,
                options
            }),
        }
    }
});

StatsD

The StatsD integration uses hot-shots StatsD client which supports extended StatsD features used by Telegraf and Datadog. There are a lot of framework integrations and automated capture you can configure with StatsD.

There is also an Log interceptor that can send events to Datadog.

import { bootstrap } from '@btilford/ts-base';
import {createStatsDFeature, StatsDOptions} from '../src';
import {Registry} from 'prom-client';

const appName = 'my-app';
const options: StatsDOptions = {
    prefix: appName,
    sampleRate: 0.8,
    tags: {appName, example:'true'},
};
bootstrap({
    appName,
    apm: {
        features: {
            counter: createStatsDFeature({
                name:'counter',
                options
            }),
            gauge: createStatsDFeature({
                name:'gauge',
                options
            }),
            timer: createStatsDFeature({
                name:'timer',
                options
            }),
            histogram: createStatsDFeature({
                name:'histogram',
                options
            }),
        }
    }
});