Angular After Dark: Creating a custom log driver with Lumberjack

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello welcome to angela of the dark it's very dark outside and i'm lars last spring and it's been a while since last time but the reason is i'm fighting streamlabs to give me back my money for a license that's pretty much unusable to me so i'm trying to get a better deal with stream yard instead so right now i'm stuck at 720p and i can't stream to twitch and youtube at the same time so i'm using youtube so that it stores my recordings so yeah today we're going to be looking at continuing some work we did in another episode we're using the lumberjack library and we were let's see we were replacing the logger or the logging mechanism or lag of the same in the two of heroes app and the official tutorial lab from angle i o so that's what we're going to look into today and to help with that we actually have a new feature coming up in lumberjack hey sirken uh santosh yadav has been working very hard to add our second schematic to lumberjack this one is for a custom lock driver and a lock driver is where you hook up lumberjack to whatever output of your logs you want for example we have the http driver and the console driver those come bundled with lumberjack you can activate them and configure them but if you have a custom backend you might want to implement your own log driver and in this case we want the logs to appear in the ui in the front end so that's what we're going to be doing using a lock driver and i will admit that it's not very easy to add a lock driver we do have some documentation on it in the readme file but there's a lot of files to create so it's much nicer to be using a schematic so let's look into that and test out this new feature by santosh let's see i need to figure out how much and should zoom in probably like so just to make sure you can see it and even in oh a very poor hd 720 resolution um i'm trying to figure out how to get full hd again yeah so this is our repo it's the tour of heroes app it's an angular app and last time we were working on this we were adding let's see so in our app module we added lumberjack module for root we added the b man to the scope of the log messages and so so we created a custom formatter we also included two drivers the console driver with default options and the http driver with some options so that logs will be sent to this testing backend that's public not something i created so it's like a paste bin for http request or something like that so now we would actually like to add our own log driver here um and i think it should be called the messages driver module groups this is how we're going to call it um scaffolding out the messages driver for our registration so this is the result we want um hey nacho oh i have no idea what time it is in uruguay um we're working on some some nice features for our ng worker libraries we're working on officially adding angular 12 support for lumberjack 2 and looks like it's going to be going well um but that means we're also including node.js 14 because that's supported officially by angular 12 as the first version but also angular 12 is ditching support for node.js 10. um so we're just making sure that lumberjack can run with angular 12 and it seems that it can indeed do so so we're releasing a patch and we're also working on a bug for our ng worker angular versions action there was some time when there was a separate angular official builder for ng packager and i think it was in version 11.0 where that was actually removed uh and because it was replaced with just a single angular builder uh but with a different name you can have several names for for builders in a single package so the energy packager is now a builder is now a target in the build angular builder by the angular team okay sir can nice to see you you have a nice night's sleep and uh nacho says it's early and he's been doing work yeah nacho joined this dot labs or this dot media whatever they're called so i hope you're doing some interesting stuff okay but for this driver yeah let's see we so we have lumberjack setup and we want to be able to do this to basically output it to the ui there's a list in the ui that can display log messages and we broke that the last time because we replaced their logging implementation with lumberjack but we we were missing the log our we were missing the connection to the messages component so that's what we want to add now we can also just recap see that we added this hero logger service and here we have a method for each [Music] possible log and most of them were actually parameterized loggers and i i just started using lumberjack myself in a project network and it actually seems like parameterized loggers is is used a lot so we should probably work on a nicer api for that for now this is how we can do it yeah so there is this messages component and it takes let's see it has this messages service and in its template it is looping through messageservice.messages so let's look the messages service has just an array of strings that's the messages and you can call it with this add message which is also a string and you can clear the whole thing by calling a clear method there's probably a button for that somewhere here yeah there's a button to clear it okay so we want to hook up lumberjack to this messages component to do that we need to add our own lock driver let me close all of this and the nice thing now is i have i have replaced this lumberjack with a build artifact from our ci pipeline just to test out this new version so here it will say 202 which is the latest version but actually it has this new schematic the log driver schematic you can see your seat here in the collection json that there's the ng ad it's the one you want to run after adding a lumberjack um so it will set up the basic configuration for you and now the new feature is this lockdriver schematic uh so and the source code of course is in here so to run that we will do ng generate and then the name of our package ngworker numproject and then the name of this schematic so that will be logdriver and also has an alias driver so you could also do it like so and now we need to pass it some parameters and i think the only one that's required is a name so we could say messages and let's see what happens when we do that okay let's review here so it created a bunch of files in the messages folder that already existed so it actually added some let's see two folders with a bunch of files the configuration folder has a lot of injection tokens and modules and test suites for those it's mostly just boilerplate so basically you don't really have to worry about all of this this is where you want to implement your driver this one file so it's nice to have a schematic to set up that whole boilerplate for you um so let's let's look into this log driver okay so we have a class was generated it's called the messages driver and it has some generics to accept a payload a payload is a custom property and that we can add to any log object passed to lumberjack so that we can ship it to the back end for example any additional properties we want to add to to whatever is locked and a driver needs to have a driver identifier which should be a unique string so let's just call it the same as the class and don't do it like so because it at runtime will be minified by the angle compiler so the name will not be messages driver so use an actual string for that um you don't have to worry about what this does this is actually a placeholder for a future feature but just know that it needs to be unique so we will have a lumberjack lockdriver config object injected into a property and this is required to have a public property called config of this type um to a lock driver so nice thing that the schematic set all of this up for us and now we can worry about handling these six different uh levels of logs we have warning trace info error debug and critical logs so let's just first i want to commit this um generate messages block driver fiber no driver and now we need to hook it up to this messages service i don't let's see where's the messages service oh for some reason it's not in the messages folder which is kind of strange but let's let's leave it there and it's called the message service so let me inject that into this driver we will have a private message message service like so imported it from a relative route no not that one this one yeah ah that doesn't look good you're relative round message like so and that will resolve correctly okay let me just enable my not this one one sort these import statements okay that looks nice so now we have our message service so we need to add that to each of the [Music] the levels of logs critical and so on so let's start with critical this message service and has this add method and we need to pass it a string and we can see that what we have here the formatted log is actually a string representation of the log object so lumberjack has already done the work for us so we can just pass this formatted log and we don't have to use the other property of this parameter where and the parameter that we're being passed by the way is um a lumberjack lock driver lock with an optional payload okay hey bill you're a bit late you want me to bump up the fund and yeah let me do that it's already pretty big um sorry it's because i don't have full hd right now i will try to fix that at some point but the licenses are pretty expensive okay so yeah this is actually this should be it so now we handle the critical logs so we basically need to do the same for all the other ones and of course we could just add one method to do this but whatever it's not too bad so very simple implementation just to hook up this log driver our messages driver to our message service yeah very good um adds formatted logs to the message service okay so that's the implementation implement messages log driver and now we need to register it so we'll go out to our app module and this is what we wanted to be able to do so let's see if we can do that now yeah we've got it from here messages configuration messages driver module and this messages driver module which was generated for us this for root method that we need to call and now we are also have the common options for log drivers and it's this levels array so we could say we only want lumberjack level dot critical passed uh to this lock driver for example if we do this logs of other severity levels or log levels will be filtered out so they won't be passed by lumberjack um if we don't pass this option it will depend on the route level configuration which we have up here we don't have levels specified so it's following the default settings from lumberjack which is let's see uh i think in development mode every log level is passed to all log drivers in angular production mode trace and debug levels are not passed to log drivers if you want that want everything in production as well you should do it like so lumberjack level verbose this will enable all locks at all levels both in production mode and development mode but yeah the idea is you're not going to need debug and trace in production so let's just use the default configuration okay this should be it so now we will register messages logdriver and the code should be done so now it will be exciting to see if we can output those logs to the messages component oh no ngcc the worst thing in the world it's too late for that way too late for ngcc okay so well one good thing is that ngcc is kind of coming to an end the angular linker is the replacement for that and um oh um yeah that's a different discussion now we need to figure out how we're we have a problem here yeah yeah okay so we actually have an error in the generated code so we need to fix this in the schematic i think but let's see if we can fix it manually first in this code base so in our driver root module okay so it's looking for a variable called the custom driver config but it's actually called messages driver config and okay yeah so i ox i also added a second dependency which is this messages server service so now i need to pass that in this messages driver factory so let's see and this one is called here so we need another dependency message service so in this dependencies array and then we accept it as another parameter here to the factory function for the provider message service and we can then pass it into the constructor of our messages driver so this factory is merging it's copying over the properties of the root configuration and merging it into a new separate configuration for this driver specifically so that we can have different options on the driver level if we pass them to this for root method so this will enable us to have separate options here as we were reviewing before okay let's see if can compile with that yeah that worked okay i need to add a a comment to our pull request we're almost finishing this feature so it's nice to just see that if it will work so this one will be let's see i want to uh how where is the where's the amend option strange oh i have the mouse hovering over it yeah okay i didn't look at the parenthesis for some reason okay commit all comment yeah okay so bill is asking how to use different levels or for what different cases do you use one over the other um well that's up to you you have six different levels to use and you can decide what they mean for your project but for let's see so the net ecosystem has a similar as number of levels see they have critical debug error information trace and warning so they basically have the same as lumberjack except for this non one and this is actually in i think this one and another page on the the microsoft docs explains about logging levels so you can you can look into that if you want some guidance on when to use what for example here it says that critical level is logs that describe an unrecoverable application or system crash or a catastrophic failure that requires immediate attention so that would be and any sort of exception that shouldn't happen something you didn't take into account in your code or that will stop the angular application or whatever or i don't know your last connection and you're unable to regain that connection to some service or whatever debug levels logs that are used for interactive investigation during development and that's why it's disabled in production these logs should primarily contain information useful for debugging and have no long-term value the error level locks that highlight when the current flow of execution is stopped due to a failure this should indicate a failure in the current activity not an application-wide failure so critical will basically break the application or whatever you're doing and an error will be more mo more local error and i would normally say that these are the expected exceptions so for example i mean maybe we know that sometimes the the backend or some some api is unavailable but it doesn't break the experience of the the user experience of of the whole the whole app so that's an expected error or and we are able to recover from that by maybe retrying a few times or later or or something like that the information log is the information log level is logs that track the general flow of the application these logs should have long term value and trace is logs that contain the most detailed messages these messages may kind of contain sensitive application data these messages are disabled by default and should never be enabled in a production environment so that's the dot net let's see if it's in dotnet core yeah it's the same so i'll just put in the link here and the chat and i think there's another documentation page somewhere [Music] i just don't have it open right now but it kind of discusses these logging and these levels as well but yeah that's some guidance but it's up to you you have these six levels you can use them how however you want and similar to net here the debug and trace levels are not enabled in production by default but you can you can enable them you can override the settings to whatever you like okay so now we might have an application running it's this two of heroes app and yay look at that we have a trace log fetched heroes in the messages so apparently our driver is working let's clear the messages go to nachos page and we have another another log message here fetch hero with id12 let's go back let's look at second and now it fetched all the heroes on the page we saw before and now fetch uh sir can with the hero id of 13. so yeah this is actually dashboard fetch the heroes the heroes page also fetch the heroes what if we added one might not work oh let's say phil added the hero with id21 okay let's look at bill fetch the hero with id21 okay so bill is short for william so let's change that name and we updated hero with id21 now it says william instead of bill nice so our custom lock driver is working the schematic was almost working it was just one variable name that didn't match so i'll add that to our pull request so it was nice to see it in practice and yeah the whole idea about lumberjack or one of its it's the things that makes it interesting is as soon as we have these logger services fine we won't have to change this code or the code calling this locker service to add another lock driver so for example to add another back end and right now we have this htp driver it will we will pass it an endpoint url and it will ship it will send http request with the log objects and some metadata and yeah you can find that interface in the documentation so it's just for symbol backend you have to accept a request a post request for this url and the objects it's it'll be an object per request a log object with some metadata so we have this one it comes with lumberjack we have the console driver so that we will we should also see it yeah let's try that should also see it in the browser console so yeah we're seeing the same things here in the browser console we have trace and it says the same message the formatted log output and the undefined it is because this log doesn't have a payload but it could have a payload some logs will have payload with some data that you provided for it and other than that we're just seeing our retry strategy for the back end failing but yeah we see the logs here in the browser we see it in the messages and if we had a proper backend it would also be sending the same log objects to the backend so that is actually now we have three three log drivers activated the messages driver the browser driver the htp driver but we're still logging through the same api this hero logger service or directly through a lumberjack service if you want a more low-level imperative api this is a declarative api so this is pretty nice we can add we can add log drivers we can configure the log drivers differently and we only have to touch the app module it will affect the whole application all the logging so we won't have to change our logger services or wherever it's called in the code so here it's in the hero service it's called it's calling this logger um whenever we for example deleted a hero it will lock that so that's that's pretty interesting i think and kind of shows the power of lumberjack so as soon as we have this logging added we don't have to touch this code again simply to reconfigure our back ends or whatever or even add another lock driver so besides these two there are two command community driven lock drivers one for google firestore google cloud firestore and one for azure application insights and yeah you can find them on npm by searching for ad ng worker there they are hosted in our npm organization and we one of them is also in our github organization called ng worker so but if you're not using any of these two you will have to add your own log driver and this is where this schematic is helpful it will generate all these files for you that you need including tests and setting up the modules and configuration in the best practices way so it will prevent you from accidentally misusing for example if we just imported the module but not before use the for root method we would actually get an error at runtime and we do and it says do not import messages driver module directly use messages driver module 4 root so it has some features added for robust being robust and has tests for all that the only thing it doesn't add currently is it doesn't set it up for allowing other options than the levels and the identifier so if we wanted some custom options here say prefix we would need to look at the http driver for example in the lumberjack repo to figure out how to do that but we might add an option for the schematic later to set it up for additional log driver specific options here for now you can um yeah we can add a driver and we can implement whatever we need in this case it was logging to this message service but it might be send an http request to your whatever your backend is or call some javascript library to log to whatever sentry or log rocket or anything so this should give you an idea about how to do that so that was it for today angle after dark and now we saw how to add a custom lock driver using lumberjack and um we're done with this two of heroes application we replaced the to-do's for implementing actual logging and we even saw how after adding this logger service we could configure or add more lock drivers we'd have to without having to touch the most of the application code we only have to touch the app module again so that is that is really really something i think and i hope you can see the value in this and with this new schematic that for log drivers you'll be able to add your own backend until there's a community uh plugin for that of course if you're using some popular log provider like log rocket or century or whatever uh feel free to start a repo for the community we have i can actually show you we have um kind of some things to help you help you with that lumberjack inside of the energy worker github organization we also have the lumberjack custom driver repo it's a template repo on github so somewhere here there should be like that generate button maybe i can't see it because i'm zoomed in here where is it where did it go usually there's oh it's probably because i'm not signed in here let me find a sign in tab and i'm not sharing my screen so maybe i should do that as well okay so we're in the ng worker organization on github and we found the lumberjack custom driver template repo so if you want to start a log driver plugin that anyone can use click this button use this template and then it will set you up with a repo with everything you need and for example that's how this lumberjack application insights driver repo was started so it's not the lumberjack or ng worker team doing that that's a community member out to a group so he's maintaining this lumberjack application inside driver for azure so and this is all based on on our uh our template repo for log drivers so it will set you up with a ci workflow and template for pull request and basically everything you you need to to get going and it will even set up the whole repo with projects for your library test utilities in an angular cli mono repo with all of this so that's one of the things we can do if you um if you want to add an another plug-in for lumberjack a lock driver plug-in for some lock provider we don't have in a community plug-in for yet you can use this template repo the other thing we can do is we can host you here in our github organization and you will still have full control of this repo and we can also post your package using the official ng worker scope on on mpm so for example if we search for ng worker we will see that we also have the ng worker lumberjack application inside driver and this one is maintained by auto group and we have the lumberjack firestore driver by marcin miliwicz so uh this is to help you with discoverability uh as a lumberjack plugin so get in touch if you want to create one for some some log provider and it's very similar to what we just saw with our custom lock driver here it's basically all of this and then wrapping it and revving it in an angular library a package for npm so so usually it's just about importing some some servers or using some javascript api and hook it hooking it into these six methods that's the gist of it that that's almost all you need unless you want to add some some more options for configuration such as an api key or something like that if you need that you would have to be able to pass it here in in the object similar to what we have with the http driver so so look into that implementation and lumberjack repo because that's exactly what it's there for it's there for being a very simple http log driver and to be a reference driver for these more advanced features like adding options and some metadata and here we have a retry strategy for the http requests so if you need something similar look into the implementation for that yeah so that's all i have to say about log drivers and lumberjack we're almost done with this schematic so maybe sometime next week we can release lumberjack 2.1 and we're also finishing up a patch for lumberjack it will probably probably be 203 there's nothing i don't think there's anything new in it it's just making sure that we have support for angular 12 which is now in release candidate zero and that's about the time where we go and verify that lumberjack works with this new version of angular so yeah that's all for today and i'll see you next time on angela after dark bye
Info
Channel: Lars Gyrup Brink Nielsen
Views: 54
Rating: undefined out of 5
Keywords: angular, lumberjack, logging
Id: CYw7HF22GO8
Channel Id: undefined
Length: 43min 22sec (2602 seconds)
Published: Tue Apr 27 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.