Giter VIP home page Giter VIP logo

babel-plugin-metalog's Introduction

Babel Plugin: METALOG!!

Babel that uses labeled statements to pass call-site meta data to a global logging function. also lets you totally remove logging statements from production builds.

free context! free logging! come and get it!

based on the great work by Charles Pick from codemix on babel-plugin-trace.

Status

alpha-as-fuck. like as in 4-5 hours work. but i couldn't find anything else that worked the way it seemed loggers should in the babel / js environment and i'm pretty happy with it so far.

use with caution. like you always should when running some random dude you don't know's code.

Motivation

  1. make call-site meta data (filename, class/function, line number) as well as this binding automatically available to a logging function.

    • logging calls automatically have context information available so you can just log the important stuff and not worry about keeping log statements in sync with file / function / class names or creating different logger instances for different contexts.

    • i.e. no more of this crap:

      // src/index.js
      
      const logger = new Logger(__filename);
      
      logger.debug("i'm at the file level!");
      // => DEBUG [src/index.js] i'm at the file level!
      
      function doSomething() {
        // pain-in-the-ass and has a performance cost even if logging 
        // is disabled: 
        const logger = new Logger(__filename, "doSomething");
        
        logger.debug("i'm doing something!");
        // => DEBUG [src/index.js:doSomething] i'm doing something!
      }
      
      class Dude {
        constructor(name) {
          this.name = name;
        }
        
        doSomethingElse() {
          const logger = new Logger(
            __filename,
            `<Dude name=${ this.name }>`,
            'doSomethingElse'
          );
          
          logger.debug(`I'm doing something else!`);
        }
      }
      
      (new Dude('NRSER')).doSomethingElse();
      // => DEBUG [src/index.js:<Dude name=NRSER>:doSomethingElse] I'm doing something else!
    • just do this:

      // src/index.js
      
      debug: "i'm at the file level!";
      // => DEBUG [src/index.js:3] i'm at the file level!
      
      function doSomething() {
        debug: "i'm doing something!";
        // => DEBUG [src/index.js:doSomething:7] i'm doing something!
      }
      
      class Dude {
        constructor(name) {
          this.name = name;
        }
        
        __logContext() {
          return `<Dude name=${ this.name }>`;
        }
        
        doSomethingElse() {
          debug: `I'm doing something else!`;
        }
      }
      
      (new Dude('NRSER')).doSomethingElse();
      // => DEBUG [src/index.js:<Dude name=NRSER>:doSomethingElse] I'm doing something else!
  2. pay no performance penalty for logging in production by completely removing logging statements during compilation.

    • configure the plugin in .babelrc to remove logging statements when NODE_ENV=production:

      {
        ...
        "plugins": [
          ["metalog", {
            "strip": {
              "production": true
            }
          }],
          ...
        ],
        ...
      }
    • go crazy. log it up. everywhere. and leave them there. won't affect production performance at all.

    • you can of course strip them out of all builds to see the difference with {"strip": true} in the above, and there is a bunch of functionality inherited from babel-plugin-trace that should help you be more fine-grained about it, but i haven't tried it out yet (keep scrolling for details).

  3. use any logging package you like.

    • metalog just replaces error:, warn:, info:, debug: and trace: statements with calls to a global function. define that function and send the data to whatever logger you prefer.

    • compiles

      // src/index.js
      
      debug: "i'm at the file level!";
      
      function doSomething() {
        trace: "i'm doing something!";
      }
    • to

      "use strict";
      
      // src/index.js
      
      METALOG({
        label: "debug",
        filename: "/Users/nrser/dev/gh/nrser/nrser.js/src/blah.js",
        filepath: "/Users/nrser/dev/gh/nrser/nrser.js/src/blah.js",
        content: ["i'm at the file level!"],
        line: 1,
        parentPath: [],
        binding: undefined
      });
      
      function doSomething() {
        METALOG({
          label: "trace",
          filename: "/Users/nrser/dev/gh/nrser/nrser.js/src/blah.js",
          filepath: "/Users/nrser/dev/gh/nrser/nrser.js/src/blah.js",
          content: ["i'm doing something!"],
          line: 4,
          parentPath: ["doSomething"],
          binding: this
        });
      }
    • you just define METALOG() at global scope and handle the data in the javascript runtime however you like. pass it to your favorite logging library and filter logs using levels / hierarchy / patterns / whatever! or handle it yourself!

      a simple implementation (doesn't deal with binding):

      function METALOG({
        values, // boolean, see below
        level, // "error" | "warn" | "info" | "debug" | "trace"
        filename, // string, filename as babel sees it
        filepath, // string, resolved path to file
        content, // Array<any>, the stuff that was logged
        line, // number, line number of the call site
        parentPath, // Array<string>, class / function ancestry
        binding, // `this` in current scope, undefined at file-level
      }) {
        console.log(
          `${ level } [${ filename }:${ parentPath.join(':') }:${ line }]`,
          ...content
        );
      }
    • you can change the global function name (default METALOG) in the .babelrc plugin options:

      {
        ...
        "plugins": [
          ["metalog", {
            "strip": {
              "production": true
            },
            "logFunction": "myMetalogHandler"
          }],
          ...
        ],
        ...
      }

Installation

TODO

i haven't put it up on npm yet, so you need to point npm at this repo or fork/clone it and link it yourself... which you'll probably want to do because it's almost certain to have bugs and issues that you'll need to go muck around in the source to sort out. you also have to add the plugin to .babelrc or wherever you define your babel plugins.

if this sounds confusing this package is probably way too early for your needs. if someone's actually reading this and really wants it published and doc'd open an issue and i'll try and find some time for it.

filtering stuff inherited from babel-plugin-trace

i haven't tried any of this stuff, but i didn't go out of my way to break it either. let me know how it goes!

Enable by filename

Enable logging for any file with login.js in the path.

TRACE_FILE=login.js babel -d ./lib ./src

Enable logging for any file with db/models or components/login in the path.

TRACE_FILE=db/models,components/login babel -d ./lib ./src

Enable for specific functions

Enable logging for any function called login() or logout().

TRACE_CONTEXT=:login,:logout babel -d ./lib ./src

Enable logging for any function in a class called User.

TRACE_CONTEXT=:User: babel -d ./lib ./src

Enable only specific logging levels

Log only warn statements.

TRACE_LEVEL=warn babel -d ./lib ./src

Log trace and warn statements.

TRACE_LEVEL=trace,warn babel -d ./lib ./src

License

MIT

babel-plugin-metalog's People

Contributors

nrser avatar phpnode avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

pillowsoft

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.