Skip to content

Add $log like functionality to Angular 2 #5458

Closed

Description

@juristr

Directly writing console.log statements throughout the apps codebase is bad as you don't have any possibility to centrally deactivate it.

Are there any plans on integrating a $log like feature in Angular2, or even something a bit more advanced. I've quickly seen diary.js but it seems abandoned.

Activity

  1. robwormald commented on Nov 24, 2015

    @robwormald
    Contributor

    Not bad idea. Diary is a pretty simple lib, and should still work (with a bit of tinkering) - might be worth bringing into the main repo (and adding Dart support?) @IgorMinar ?

  2. jamesmorgan commented on Feb 27, 2016

    @jamesmorgan

    I am surprised I couldn't find a $log equalivant in angular? +1 for adding this feature.

  3. zoechi commented on Feb 28, 2016

    @zoechi
    Contributor

    In Dart it's print() and it can be redefined in zones.

  4. blaster151 commented on Mar 2, 2016

    @blaster151

    I concur, this is needed.

  5. cviccaro commented on Mar 9, 2016

    @cviccaro

    +1 I would like to see this as well. Currently I am trying to create my own LogService.. but am running into a problem wherein the file/line referenced in the console.log is that of the log.service.js file, and not the original file. Until I can solve that problem, I'll just be forced to use the global console everywhere. Anyone have any ideas?

    consoleLog() and formatError() come from A1 (slightly modified for ES6):

    export class LogService {
    
        enabled = true;
    
        constructor() {
            this.enabled = '<%= ENV %>' === 'dev';
            var methods = ['assert', 'debug', 'error', 'info', 'log', 'trace', 'warn'];
            methods.forEach((method) => {
                this[method] = this.consoleLog(method);
            });
        }
    
        assert(message) {
            //
        }
        debug(message, ...args) {
            //
        }
        error(message, ...args) {
            //
        }
        info(message, ...args) {
            //
        }
        log(message, ...args) {
            //
        }
        trace(message, ...args) {
            //
        }
        warn(message, ...args) {
            //
        }
    
        private formatError(arg) {
          if (arg instanceof Error) {
            if (arg.stack) {
              arg = (arg.message && arg.stack.indexOf(arg.message) === -1)
                  ? 'Error: ' + arg.message + '\n' + arg.stack
                  : arg.stack;
            } else if (arg.sourceURL) {
              arg = arg.message + '\n' + arg.sourceURL + ':' + arg.line;
            }
          }
          return arg;
        }
    
        private consoleLog(type) {
            if (this.enabled) {
                let console = window.console || {},
                  logFn = console[type] || console.log || noop,
                  hasApply = false;
    
                let formatError = this.formatError;
                // Note: reading logFn.apply throws an error in IE11 in IE8 document mode.
                // The reason behind this is that console.log has type "object" in IE8...
                try {
                    hasApply = !!logFn.apply;
                } catch (e) {
                    //
                }
    
                if (hasApply) {
                    return function(...args) {
                        var _args = [];
                        args.forEach(function(arg) {
                            _args.push(formatError(arg));
                        });
                        return logFn.apply(console, _args);
                    };
                }
                // we are IE which either doesn't have window.console => this is noop and we do nothing,
                // or we are IE where console.log doesn't have apply so we log at least first 2 args
                return function(arg1, arg2) {
                    logFn(arg1, arg2 === null ? '' : arg2);
                };
            }
            return function() {
                //
            };
        }
    }
    
    
    
  6. sebastianovide commented on Mar 12, 2016

    @sebastianovide

    +1 for $log equivalent

  7. jstuparitz commented on Mar 29, 2016

    @jstuparitz

    +1 for $log

  8. seenimurugan commented on Apr 22, 2016

    @seenimurugan

    +1 for $log equivalent

  9. juristr commented on Apr 26, 2016

    @juristr
    ContributorAuthor

    I didn't look into what diary.js does, yet, but given the reactions from people we should maybe revive it? @robwormald ?

  10. marcalj commented on Jun 29, 2016

    @marcalj

    Use the thumbs up button on first comment please!

  11. simpss commented on Jul 10, 2016

    @simpss

    After finding this request, I walked the internets and found this little library: https://github.com/koroandr/log4ts The docs aren't that good, but the source is easy to understand.

    npm install log4ts --save

    created a small wrapper around it. For some reason ngOnInit didn't fire so the initialization has to be called manually for now. This can surely be improved, I threw it together just to quickly test the library.

    log level config:

    import {LogLevel} from "log4ts/build/LogLevel";
    
    export class AppConf {
        public static get LOG_LEVEL(): LogLevel { return LogLevel.ALL; }
    }
    import {Injectable} from '@angular/core';
    
    import Logger from "log4ts/build/Logger"
    import LoggerConfig from "log4ts/build/LoggerConfig"
    import BasicLayout from "log4ts/build/layouts/BasicLayout";
    import ConsoleAppender from "log4ts/build/appenders/ConsoleAppender";
    import {IAppender} from "log4ts/build/IAppender";
    import {ILayout} from "log4ts/build/ILayout";
    import {LogLevel} from "log4ts/build/LogLevel";
    import {AppConf} from "../../config/app.conf";
    
    @Injectable()
    export class LogService{
    
        public log: Logger;
    
        private appender: IAppender;
        private layout: ILayout;
        private config: LoggerConfig;
    
        constructor() {
    
        }
    
        init(){
            this.layout = new BasicLayout();
            this.appender = new ConsoleAppender();
            this.appender.setLayout(this.layout);
            this.config = new LoggerConfig(this.appender);
            this.config.setLevel(AppConf.LOG_LEVEL);
            this.log = new Logger();
            Logger.setConfig(this.config);
        }
    }

    and usage:

    this.logService.log("Something that interests you");
    this.logService.log.info("Something that interests you");
    this.logService.log.fatal("Something that interests you");
    this.logService.log.error("Something that interests you");
    this.logService.log.debug("Something that interests you");
    this.logService.log.warn("Something that interests you");
    this.logService.log.trace("Something that interests you");
  12. trakhimenok commented on Jul 11, 2016

    @trakhimenok

    @simpss too many dots to call, probably would be better if usage was something like:

    this.logInfo("Something that interests you");
    this.logFatal("Something that interests you");
    this.logError("Something that interests you");
    this.logDebug("Something that interests you");
    this.logWarn("Something that interests you");
    this.logTrace("Something that interests you");
    
  13. gorilla77 commented on Jul 12, 2016

    @gorilla77

    @cviccaro You can use this to get the "correct" line number:

    info = console.info.bind(console);
    info("Log me");
    
  14. cviccaro commented on Jul 13, 2016

    @cviccaro

    @gorilla77 Thanks! I used it like this:

    export class LoggerService {
        get log() {
            return console.log.bind(console);
        }

    It was the only way I found I could get the appropriate line number to show up. I didn't realize what you wanted to do is to return the bound function from the logger service. I was, at first, trying to return an anonymous function like Angular1's logger.

  15. juristr commented on Aug 10, 2016

    @juristr
    ContributorAuthor

    Ben Nadel (@bennadel) just published an article about this topic. Might be interesting for some of you: http://www.bennadel.com/blog/3129-implementing-a-log-inspired-logging-service-in-angular-2-rc-4.htm

  16. 20 remaining items

  17. harikrishnan-u01 commented on Jul 27, 2017

    @harikrishnan-u01

    Is there any fix planned for implementing $log as part of Angular 5 release?

  18. jesujcastillom commented on Aug 2, 2017

    @jesujcastillom

    +1

  19. mtpultz commented on Aug 2, 2017

    @mtpultz

    Can you please stop using +1 and just hit subscribe, and/or add an emote to peoples responses where you agree or disagree. This +1-itis drives everyone crazy with useless notifications while we all patiently wait for features that are marked for implementation at some point based on the issues labels. This is why subscribe and emotes were added. Yes, everyone wants this feature you're not adding any weight to the conversation unless you're providing some sort of insight into implementation. Lets try and make the next notification for this feature be the actual closing of the issue.

  20. Toxicable commented on Aug 3, 2017

    @Toxicable

    The implementation of this issue is currently blocked on the fact that Services are not easily tree shakable see here:
    #17399 (review)
    Feel free to suggest a designed where these issues have been reduce if you want to seee this in core sooner.

  21. Anish895 commented on Dec 22, 2017

    @Anish895

    how to generate .log extension in angular 4 .. Is there any possible way to create and use??

  22. added this to the Backlog milestone on Jan 23, 2018
  23. splincode commented on Jul 26, 2018

    @splincode
    Contributor

    @juristr Is the issue relevant?

  24. ocombe commented on Jul 26, 2018

    @ocombe
    Contributor

    @splincode please stop spamming old issues asking if they are still relevant, I assume that you have good intentions, but it's annoying.

  25. splincode commented on Jul 26, 2018

    @splincode
    Contributor

    @ocombe I just wanted to know whether to close the old tasks, if they are not relevant
    mhevery Recently closed several obsolete tasks, thanks to this

  26. juristr commented on Jul 26, 2018

    @juristr
    ContributorAuthor

    It's somehow relevant but it's an old issue and I think ppl have found other ways (i.e. external libs or custom impl) and moved ahead. I'm closing this as there are way more important features to be implemented 🙂

    For those interested, creating a custom logger could look like this one here:
    https://github.com/angular/angular/blob/master/aio/src/app/shared/logger.service.ts

  27. splincode commented on Jul 26, 2018

    @splincode
    Contributor

    @juristr Thank you for having responded, I am grateful to you!!!

    Also I develop an improved version of the logging for Angular
    https://github.com/splincodewd/client-logger

  28. msalehisedeh commented on Jan 19, 2019

    @msalehisedeh

    looks like this conversation halted back in July and i am a late comer in this conversation. But, checkout @sedeh/smart-console on npm and let me know what you think.
    Live demo is on https://smart-console.stackblitz.io/

  29. angular-automatic-lock-bot commented on Sep 14, 2019

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  30. locked and limited conversation to collaborators on Sep 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: coreIssues related to the framework runtimefeatureLabel used to distinguish feature request from other issuesfreq3: high

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions