{"id":15105154,"url":"https://github.com/emberjs/log-manager","last_synced_at":"2025-09-27T03:30:28.806Z","repository":{"id":15709786,"uuid":"18447793","full_name":"emberjs/log-manager","owner":"emberjs","description":"Hierarchical Logging + multiple appenders -- Basis for Ember.js logging","archived":true,"fork":false,"pushed_at":"2015-06-20T12:36:36.000Z","size":166,"stargazers_count":12,"open_issues_count":1,"forks_count":4,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-10-29T14:50:51.684Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emberjs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-04-04T18:10:16.000Z","updated_at":"2023-09-12T07:58:31.000Z","dependencies_parsed_at":"2022-09-01T05:12:37.528Z","dependency_job_id":null,"html_url":"https://github.com/emberjs/log-manager","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emberjs%2Flog-manager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emberjs%2Flog-manager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emberjs%2Flog-manager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emberjs%2Flog-manager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emberjs","download_url":"https://codeload.github.com/emberjs/log-manager/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234267255,"owners_count":18805381,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-25T20:21:23.561Z","updated_at":"2025-09-27T03:30:23.497Z","avatar_url":"https://github.com/emberjs.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Log Manager\n\nLogging library with a focus on hierarchy, performance, and multiple appenders.  Borrows most of the concepts from java's [log4j](http://logging.apache.org/log4j/2.x/).\n\n\n### Appenders\n\nAn appender translates a log into a console entry, file entry, ajax post... etc.  You can have multiple appenders, and appenders can be assigned to specific loggers.\n\nThe appenders follow the hierarchical model (an appender to a parent will apply to its children).\n\n#### Adding an appender\n\nWhen adding an appender, specify the name, and the appender instance.\n\n```javascript\n\nvar logManager = new LogManager();\n\nlogManager.addAppenderTo('router', new ConsoleAppender());\nlogManager.addAppenderTo('router.transitions', new AjaxAppender()).\n\n\nlogManager.loggerFor('router'); // will use the console appender\nlogManager.loggerFor('router.transitions'); // will use the console appender and the ajax appender\n\n```\n\n#### Built-in Appenders\n\n##### Console Appender\n\nLogs to the console.  Uses different methods based on the level.\n\n`log.error` uses `console.error`\n`log.warn` uses `console.warn`\n`log.debug` uses `console.debug`\n`log.info` use `console.info`\n\nMore built-in appenders should come soon.\n\n\n### Logging format\n\n```javasript\nvar logManager = new LogManager();\n\nlogManager.addDefaultAppender(new ConsoleAppender());\nvar logger = logManager.loggerFor('router');\n\nlogger.info('Hello Teddy'); // console.info('Hello Teddy');\nvar person = { toString: 'Teddy' };\nlogger.info('Hello @%', [person]); // console.info('Hello Teddy');\nlogger.info(function() {\n  return 'Hello Teddy';\n}); // console.info('Hello Teddy');\n```\n\n### Logging levels\n\nPossible levels: info, debug, warn, error;\n\nYou can set default levels and levels per logger.\n\nSet the levels to an array (ex: `['info', 'warn']`).\n\nTo set the default levels use:\n\n```javascript\nvar logManager = new LogManager();\nlogManager.defaultLevels(['warn', 'error']);\nlogManager.addDefaultAppender(new ConsoleAppender());\n\n//... somewhere in your code\n\nvar logger = logManager.loggerFor('ember-data');\n\nlogger.info('Finding record with id = 1'); // noop\n\nlogger.warn('Record does not have an id'); // console.warn('Record does not have an id')\n\nlogger = logManager.loggerFor('ember-data.adapters');\n\nlogger.error('Record not found'); // console.error('Record not found');\n\nlogManager.levelsFor('ember-data.adapters', []);\n\nlogger.error('Record not found'); // noop\n\n\n```\n\n### Performance\n\nA lot of focus for this logger is performance, especially when logging levels are disabled.  The idea is mainly that if logging is disabled, it should be as expensive as stripping the log methods during build time.\n\nSince the logger is requested before hand, logging levels are pre-computed, and all level methods that should not be logging will be set to empty functions.\nThis makes logging almost free in cases where you don't need it.\n\nFor example:\n\n```javascript\nvar logger = logManager.loggerFor('prison');\n\n// If warn level is disabled for 'prison' logging, the log manager will set `logger.warn = function(){}`\n\n// This method is almost free\nlogger.warn('This person is dangerous');\n\n// This method even avoids calling `toString` on `person`\nlogger.warn('Person named %@ is dangerous', person);\n\n// This method is almost free as the function is never called\nlogger.warn(function() {\n  return people.filterBy('isDangerous', true).map(function(name) {\n    return name + \" is dangerous \\n\";\n  });\n});\n```\n\nSo the only thing you need to worry about when in production and logging is disabled is the extra bytes added by logging methods, and not the lookup costs.\n\n\n### Developing and testing\n\nThe project uses [Broccoli](https://github.com/joliss/broccoli) as a build tool, but wraps all commands with grunt.\n\nInstallation:\n\n```bash\nnpm install -g grunt-cli\n\nnpm install\n```\n\nThe commands are:\n\n- `grunt build` to build the dist files\n- `grunt server` to run the test server at `http://localhost:4200`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femberjs%2Flog-manager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femberjs%2Flog-manager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femberjs%2Flog-manager/lists"}