So as usual I have some questions about something I am trying to do with Aurelia, in this case the LogManager.
Here is what I want to do…
- setup an appender that goes to the console
- setup an appender that goes to Rollbar
- setup an appender that goes to my custom error api endpoint
Okay, so that is all easy enough to do with a few simple calls:
Use the aurelia.use.developmentLogging() for console, or just use ConsoleAppender()
Use Jujens RollbarAppender for Rollbar.js (Rollbar is awesome btw) (https://www.jujens.eu/category/aurelia.html)
Use a customLogAppender for the error api
Now that all works fine, if you want the logger to call all 3 appenders for the configured setLevel (info, warn, …)
But, ha! You knew there had to be one… I want to have some calls, go to the console and Rollbar, but others go to the console and the customLog.
Here is my reasoning, Rollbar captures browser telemetry over and above the thrown error message that is extremely handy for debugging client issues. But its a paid service, and I would like to keep the hit count down. I want to be able to sent more verbose logging to the app server when needed for caught errors and debugging.
It doesn’t appear that aurelia-logger allows me to do that. Its odd in that there is a ‘name/id’ that is required when you instantiate the logger, but you cannot change what appenders are going to be called. And since its a singleton, you cannot create multiple loggers for the various combinations I want to use at least in all the examples I have been able to find
Or I guess I should say, ‘I’ can’t see how to do that in the current logger. I also don’t understand the use case for current way the name/id is used. Why have multiple names for the same configuration of the logger? It seems more something that should be set in a config at app level versus for each instantiated logger for the same set of appenders. Maybe I am missing something (as usual) on that and someone can set me straight.
So here is an example of my current code.
main.js sets up the appenders…
import { Aurelia, LogManager } from 'aurelia-framework'
.
.
.
if (environment.debug)
{
//defaults to debug and console
aurelia.use.developmentLogging();
}
else
{
LogManager.addAppender(new m.ConsoleAppender());
LogManager.addAppender(new RollbarAppender);
//LogManager.addAppender(new customLogAppender); // not implemented yet
LogManager.setLevel(LogManager.logLevel.error);
}
I have created a service to use in each VM that I want to use the logger:
import { LogManager } from "aurelia-framework";
export var logger = LogManager.getLogger('MyApp');
Then in each VM I use the following import:
import { logger } from 'services/logger';
logger.error("Error: Missing state data", this.state);
What I would like to do is configure in main.ts something like the following (not checked, just thoughts typed out):
if (environment.debug)
{
//defaults to debug and console
aurelia.use.developmentLogging();
}
else
{
LogManager.setName("MyApp");
//Setup Console and Rollbar for Errors
let loggerName = "LogConsoleRollbar";
LogManager.addLogger(loggerName);
LogManager.getLogger(loggerName).addAppender(new m.ConsoleAppender());
LogManager.getLogger(loggerName).addAppender(new RollbarAppender);
LogManager.getLogger(loggerName).setLevel(LogManager.logLevel.error);
//Setup Console and Custom for Info
loggerName = "LogConsoleCustom";
LogManager.addLogger(loggerName);
LogManager.getLogger(loggerName).addAppender(new m.ConsoleAppender());
LogManager.getLogger(loggerName).addAppender(new customLogAppender);
LogManager.getLogger(loggerName).setLevel(LogManager.logLevel.debug);
}
Then to use the logger the service would be something like this:
import { LogManager } from "aurelia-framework";
export var rollbar = LogManager.getLogger('LogConsoleRollbar');
export var customLog = LogManager.getLogger('LogConsoleCustom');
Then in each VM is use the following import:
import { rollbar } from 'services/logger';
and/or
import { customLog } from 'services/logger';
So, am I off base and aurelia-logging can something similar to this? If not should it?
Is this reasonable, a code smell, unique case and can not be generalized, something else?
Open to learning a better way of thinking about this, and other ideas on how to manage this.