Skip to content
This repository has been archived by the owner on Jun 11, 2019. It is now read-only.

splincodewd/client-logger

Repository files navigation

ClientLogger

Lightweight and configurable JavaScript logger (written on TypeScript)

Build Status npm version npm version next dependencies Status Coverage Status npm-stat

Installation

npm i @splincode/client-logger --save-dev

Motivation

This logger is a handy tool that can be useful in the design and development of the enterprise application level. Easy setting of logging levels and convenient work with groups. Among other things, you can use meta programming (decorators).

Implementation on Angular here...

Usage

You could easily use this Logger in the browser. You only need to install the package and import it in your scripts before assembly. To see how to use the Logger please follow the link or follow that's link.

You can also run the examples on webpack:

import { ClientLogger } from '@splincode/client-logger';

const logger = new ClientLogger();

Table of contents

Logging

Example: basic methods

import { ClientLogger } from '@splincode/client-logger';

const logger = new ClientLogger();

logger.trace('trace is worked', 1, { a: 1 });
logger.debug('debug is worked', 2, console);
logger.info('info is worked', 3, Object);
logger.warn('warn is worked', 4, String);
logger.error('error is worked', 5, (2.55).toFixed());
  • Default level: All

  • Show time

  • Disable trace on console (filter):
import { ClientLogger } from '@splincode/client-logger';

const logger = new ClientLogger();

for (let i = 0; i < 20; i++) {
    logger.trace('trace is worked', i);
}

Example: groups

  • Logger groups with auto closed (usage callback):
import { ClientLogger } from '@splincode/client-logger';

const logger = new ClientLogger();

logger.groupCollapsed('EXAMPLE 2: show stack', () => {
    logger.trace('trace is worked', 1, { a: 1 });
    logger.debug('debug is worked', 2, console);
    logger.info('info is worked', 3, Object);
    logger.warn('warn is worked', 4, String);
    logger.error('error is worked', 5, (2.55).toFixed());
});

logger.group('Show trace in opened group', ({ trace }) => {
    for (let i = 0; i < 20; i++) {
        trace('trace is worked', i);
    }
});

logger.groupCollapsed('Show trace in collapsed group', ({ trace }) => {
    for (let i = 0; i < 20; i++) {
        trace('trace is worked', i);
    }
});

Example: nested groups

  • Logger nested groups (with pipe):
import { ClientLogger } from '@splincode/client-logger';

const logger = new ClientLogger();

logger
    .groupCollapsed('GROUP TEST')
    .pipe(({ trace, debug, info, warn, error }) => {
        trace('trace is worked');
        debug('debug is worked');
        info('info is worked');
        warn('warn is worked');
        error('error is worked');
    })
    .close();

logger
    .group('A')
    .pipe(
        ({ trace }) => trace('trace is worked'),
        ({ debug }) => debug('debug is worked'),
        ({ info }) => info('info is worked'),
        ({ warn }) => warn('warn is worked'),
        ({ error }) => error('error is worked')
    )
    .groupCollapsed('B')
    .pipe(
        ({ trace }) => trace('trace is worked'),
        ({ debug }) => debug('debug is worked'),
        ({ info }) => info('info is worked'),
        ({ warn }) => warn('warn is worked'),
        ({ error }) => error('error is worked')
    )
    .group('C')
    .pipe(
        ({ trace }) => trace('trace is worked'),
        ({ debug }) => debug('debug is worked'),
        ({ info }) => info('info is worked'),
        ({ warn }) => warn('warn is worked'),
        ({ error }) => error('error is worked')
    )
    .closeAll(); // closed all opened group

Example: set minimal logging level

Basic parameterization

import { ClientLogger, LoggerLevel } from '@splincode/client-logger';

const logger = new ClientLogger();

logger.trace.group('A opened', ({ trace }) => trace('trace group is worked'));
logger.debug.group('B opened', ({ debug }) => debug('debug group is worked'));
logger.info.group('C opened', ({ info }) => info('info group is worked'));
logger.warn.group('D opened', ({ warn }) =>  warn('warn group is worked'));
logger.error.group('E opened', ({ error }) => error('error group is worked'));

const level = LoggerLevel.INFO;
logger.log('Set new logger level', LoggerLevel[level]);
logger.level = level;

logger.trace.groupCollapsed('A collapsed', ({ trace }) => trace('trace group is worked'));
logger.debug.groupCollapsed('B collapsed', ({ debug }) => debug('debug group is worked'));
logger.info.groupCollapsed('C collapsed', ({ info }) => info('info group is worked'));
logger.warn.groupCollapsed('D collapsed', ({ warn }) => warn('warn group is worked'));
logger.error.groupCollapsed('E collapsed', ({ error }) => error('error group is worked'));

  • Logger level groups (pretty usage API):
import { ClientLogger, LoggerLevel } from '@splincode/client-logger';

const logger = new ClientLogger();

const level = LoggerLevel.INFO;
logger.log('Set new logger level', LoggerLevel[level]);
logger.level = level;

logger.trace.group('A')
    .pipe(({ trace }) => trace('trace is worked from A'))
    .pipe(({ debug }) => debug('debug is worked from A'))
    .pipe(({ info }) => info('info is worked from A'))
    .pipe(({ warn }) => warn('warn is worked from A'))
    .pipe(({ error }) => error('error is worked from A'))
    .close()

    .debug.group('B')
    .pipe(({ trace }) => trace('trace is worked from B'))
    .pipe(({ debug }) => debug('debug is worked from B'))
    .pipe(({ info }) => info('info is worked from B'))
    .pipe(({ warn }) => warn('warn is worked from B'))
    .pipe(({ error }) => error('error is worked from B'))
    .close()

    .info.group('C')
    .pipe(({ trace }) => trace('trace is worked from C'))
    .pipe(({ debug }) => debug('debug is worked from C'))
    .pipe(({ info }) => info('info is worked from C'))
    .pipe(({ warn }) => warn('warn is worked from C'))
    .pipe(({ error }) => error('error is worked from C'))
    .close()

    .warn.group('D')
    .pipe(({ trace }) => trace('trace is worked from D'))
    .pipe(({ debug }) => debug('debug is worked from D'))
    .pipe(({ info }) => info('info is worked from D'))
    .pipe(({ warn }) => warn('warn is worked from D'))
    .pipe(({ error }) => error('error is worked from D'))
    .close()

    .error.group('E')
    .pipe(({ trace }) => trace('trace is worked from E'))
    .pipe(({ debug }) => debug('debug is worked from E'))
    .pipe(({ info }) => info('info is worked from E'))
    .pipe(({ warn }) => warn('warn is worked from E'))
    .pipe(({ error }) => error('error is worked from E'))
    .close();

Example: set style line

import { ClientLogger } from '@splincode/client-logger';

const logger = new ClientLogger();

logger
    .css({ textTransform: 'uppercase', fontWeight: 'bold' })
    .debug('window current ', window);

logger
    .css('color: red; text-decoration: underline; font-weight: bold')
    .info('It is awesome logger');

logger.warn('logger.css(...) does not define a global format!');
logger.info('For global configuration, use the constructor parameters');

Example: set global style line

import { ClientLogger, FormatLine } from '@splincode/client-logger';

const logger = new ClientLogger({
    lineStyle: {
        style: 'color: red; text-decoration: underline; font-weight: bold; font-size: 15px',
        format: FormatLine.STRING
    }
});

logger
    .css('font-weight: normal; text-decoration: none;', FormatLine.INT)
    .info(3.14); // 3

logger
    .css('font-weight: normal;', FormatLine.FLOAT)
    .info(3.14); // 3.14

logger.warn('global format with style!');

Example: CSS classes

import { ClientLogger } from '@splincode/client-logger';

const logger = new ClientLogger({
    cssClassMap: {
        'bold': 'font-weight: bold',
        'line-through': 'text-decoration: line-through',
        'code-sandbox': `
            color: #666;
            background: #f4f4f4;
            border-left: 3px solid #f36d33;
            font-family: monospace;
            font-size: 15px;
        `
    }
});

logger.cssClass('bold line-through')
    .log('JavaScript sucks', 'JavaScript is the best');

logger.cssClass('code-sandbox').log(
    '\n   @Component({ .. })' +
    '\n   export class AppComponent { .. }    \n\n'
);

logger.cssClass('bold line-through')
    .debug('JavaScript sucks', 'JavaScript is the best');
        

Example: pretty json

import { ClientLogger } from '@splincode/client-logger';
const logger = new ClientLogger();

fetch("http://data.io").then((greatBigJSON) => {

    // default browser print json
    logger.debug("Classic output json", greatBigJSON);
    
    // for pretty json usage logger.log method
    logger.log(...logger.stringify(greatBigJSON));

});

import { ClientLogger } from '@splincode/client-logger';
const logger = new ClientLogger();

fetch("http://data.io").then((greatBigJSON) => {
    
    logger
        .group('Classic output json:')
        .pipe(({ debug }) => debug('Classic output json: ', greatBigJSON))
        .close()
        .group('Pretty output json:')
        .pipe(({ log, stringify }) => log(...stringify(greatBigJSON)))
        .close();
    
});

Example: clipboard

import { ClientLogger, LoggerLevel } from '@splincode/client-logger';

const logger = new ClientLogger();
const JsonValue = { a: 1, b: [1, 2, 3] };

logger.group('copy JSON', ({ log, stringify, clipboard }) => {
    log(...stringify(clipboard.copy(JsonValue)));
    log('The object you have on the clipboard ...');
});

Example: full configurations

import { ClientLogger, LoggerLevel } from '@splincode/client-logger';
import { MyConsole } from 'node_modules/custom-logger';
// ..

const logger = new ClientLogger({

    // Drop-in replacement for console, if needed
    consoleInstance: <Console> new MyConsole(),
    
    // Minimal execute signature
    minLevel: LoggerLevel.INFO,

    // Custom color
    configColor: {
        [LoggerLevel.TRACE]: 'Grey',
        [LoggerLevel.DEBUG]: 'Blue',
        [LoggerLevel.INFO]: 'Green',
        [LoggerLevel.WARN]: 'Orange',
        [LoggerLevel.ERROR]: 'Red',
    },

    // Custom label
    configLabel: {
        [LoggerLevel.TRACE]: 'trace: ',
        [LoggerLevel.DEBUG]: 'debug: ',
        [LoggerLevel.INFO]: 'info: ',
        [LoggerLevel.WARN]: 'warn: ',
        [LoggerLevel.ERROR]: 'error: ',
    }

});

logger.trace('trace is worked', 1, { a: 1 }); // not execute
logger.debug('debug is worked', 2, console); // not execute
logger.info('info is worked', 3, Object);
logger.warn('warn is worked', 4, String);
logger.error('error is worked', 5, (2.55).toFixed());

Development

Install the dependencies:

npm install

Run the dev server

npm start

Contributing

Your commit messages have to be in this format:

type(category): description [flags]

Where type is one of the following:

  • breaking
  • build
  • ci
  • chore
  • docs
  • feat
  • fix
  • other
  • perf
  • refactor
  • revert
  • style
  • test

Run Tests

All logger tests are written with mocha, chai.

npm test

Todo

  • Override console
  • Logger method (trace, debug, info, warning, error)
  • Logger group + groupCollapsible (pipes)
  • Logger pretty write object
  • Set style by css
  • Logger level groups (trace, debug, info, warn, error)
  • Clipboard data
  • Plugin system architecture (mixins)
  • Set global style
  • Added css classes
  • Format output console
  • Dependency Injection for Angular
  • Switch enable/disable default console output
  • Profiling (memory usage, sizeof, time execute)
  • Timers (decorator)
  • Pre process output
  • Cross-browser fixing

About

Author: Maxim Ivanov