Pino JS - Logging in JavaScript / Node.js applications

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we're going to learn about PJs which is a JavaScript package used for logging and this package is often used in applications that use backend nodejs Frameworks such as Express and fastify we'll see a little bit of that later in the video we're going to learn about the main features of PJs including how you can send your logs to a remote aggregation service such as better stack where you can then search and analyze those logs quite efficiently and build things like dashboards and charts and PJ has all of the core features that you would expect in a production ready logging package for example log levels and transports that allow you to send your logs to different locations and formatters that allow you to customize the output format of the logs that are generated we're going to see examples of all of those so let's dive in and get started now let's start by having a quick look at the penjs GitHub page you can see it's got 12,400 Stars so this is a very popular logging package in JavaScript and as the about section says it's a super fast allnatural Json logger so the output by default from your Pino logs are going to be Json and that's very useful because that's a structured format that allows you to then go in and extract particular pieces of data from the logs what I'm going to do in this video to start with is open up vs code and I have an empty index.js file here what we're going to do is initialize a node.js project and we're then going to install PJs so let's open a terminal here and I'm just using the built-in vs code terminal here to initialize a project we can use the npm init command and that is then going to create the package.json file as you can see on the left hand side and when we click through to that we get some basic information about the project I'm going to clear the terminal and we can then run npm install and the name of the package that we're going to use is Pino so let's install that and that's then going to install that into this project and it's going to generate the node modules folder that you see here and you can see in the node modules folder we have a variety of packages including penino and all of its dependencies so Pino itself has dependencies and you can see these listed out in the node modules folder so we'll work with PJs in this video Let's close the package.json file and actually before I do that you can see that Peno has been added to the dependencies of this particular nodejs project so let's close that and we're going to work in index.js so let's start by creating a logger and we're going to Output some logs into the standard output into the terminal basically in order to find out how to do that let's go to the documentation and we're going to go to one of these Pages here the API section and this one here is the function that's used to create a logger so let's look at that just now we have a function called Pino and this takes some options and a destination and it returns a logger instance so let's start by using this function and creating the logger we need to import the module so we're going to do that using the require statement and the name of the package is Pino once we've got that imported we can create a logger instance so let's create a logger variable here and we can call this penino function and that's going to give us back that logger instance once we have the logger instance we can call methods on that logger for example logger doino and we can pass a message into that for example hello from Peno and that's going to then output that to the terminal and we have different methods on the logger instance it's not just info we have different levels here and this is the log levels I mentioned in the intro so when different events occur in your application you're going to give different levels of severity to these incidents so as well as logger doino let's have a more critical example and let's say we have an error in the application we can also use the logger do error method and let's output a message here saying a critical error has occurred so now that we're calling a couple of these methods on the logger instance let's run this index.js file we can do that by using the node index.js command and we can see the output of these logs just below here so in the output we're getting some Json data and we have keys for the log level for example that's set to 30 for logger doino and 50 for logger do error we have the Tim stamp when this output was generated we have the process ID of the process that generated this log we also have the host name of the machine that generated the logs and also the message this is the message that was passed into the function so for example logger doino we passed hello from Peno and that's what's output into this message key now we're seeing this on the terminal when we run the index.js file and that's because by default Pino is going to send your logs to standard output and that means that they appear here in the terminal of course we can configure different locations different places to ship your logs to and we're going to do that later in the video and this is done by using the concept of a transport in pjs we'll see that later on now we can make the output of these logs nicer by looking at another package for example here is one called Peno pretty and this is a prettifier for your Peno logs and if we scroll down to the read me here to the description of this package what this is going to do is it's going to detect if an incoming line looks like it could be a line from an ND Json logger and then it's going to apply extra formatting by considering things like the log level and the Tim stamp so let's get an example of how that looks like now to start with of course we need to install the package so let's go down here and copy this command here npm install and we've got the - G flag here we don't really need that we're just going to install it locally for this particular project so npm install Peno pretty and you could also save that to development dependencies if you would like using the dasd flag we're not going to do that we've installed it locally into the project and then what we can do if we go back to the GitHub page under the usage section here we can pipe the output of running our application to this penal pretty module now what I'm going to do is go back to the terminal and I'm going to run a command here so let's run the node index.js command and that's going to remind us of what the logs look like before and I'm going to make the terminal bigger here what we can also do is pipe the output and use npx and then p- pretty and that's going to pipe them through to that new module that we've just installed and here is an example of the output after it's been piped through the Peno pretty module so we have a nicer looking time stamp that tells us the current time and that's a little bit better than this Unix timestamp we also have different log levels here the info and the error levels and we have different colors being applied to each of those levels and we still get the message and you can see the coloration applied to that message as well so this is a bit nicer to look at from a human perspective but of course we also have the option to use these structured logs and that's going to be helpful when we send the logs or when we ship them to a remote service so let's now move on we're going to look at creating a custom log level and you can see we've we've used two log levels here we have the info and the error levels let's start by going to the documentation and we can see all of the default levels that come with PJs and we have these in decreasing order of severity so this one is the most severe problem or the most severe level that can occur in your application and that's the Fatal level we also have error warn info debug and Trace and for most applications I think these levels will serve most of your purposes but you might want to create a custom log level let's very quickly see how to do that if we go back to VSS code what we can do when we create the logger instance by calling the Peno function is pass a JavaScript object that's going to configure this loger with some options and one of these options is the custom levels option and we can set that to another JavaScript object and the key that we give here is the name of the level that we want to add to the default levels that come with penjs so let's say that we wanted to add a level called catastrophe and we give that a value that indicates the numerical value of this particular log level so we have log logger do error here and we can see that that's of level 50 if we go to a level of 70 that's a more severe example it's a higher log level and therefore catastrophe is regarded as more critical than the logger do error level once we've added the custom level we can actually then call a function on the logger object with the key that we've given to this object so to see an example of that let's call logger do catastrophe and we can pass a message into that and let's say catastrophic error so that's a new function that's been added to the logger object and we've added it through this custom levels configuration that we're passing in when we create the logger so I've cleared the console and I'm going to make the terminal bigger let's rerun the application and I'm going to pipe the output to the Peno pretty module and we can see what we get back here and we're getting the message catastrophic error but this time we have a custom user level so that's not showing up with any colors or anything like that if we take away the the piping and just call index.js we can see the output and this time you can see the level has that number of 70 that we configured for this catastrophe custom level so it's very easy to add custom levels if you need them on top of what's given by default what we can also do when we create the penino logger is we can pass a default log level we can do this by adding another key to this object that we're using to configure the penino logger and that's the level key and we can set that to one of the levels and that's going to be the default level for our logger any output that's below that level is not going to be shown up in the output so for example if we set this to the war level our logger do info output here that's not actually going to be shown on the terminal and that's because the info log level has a numerical value of 30 as we can see in the terminal we are setting the default to the war level which has a value of 40 so only worn outputs and above are going to be shown in the terminal so let's save this and we're going to rerun this and instead of seeing all three of these outputs we're now going to see only two of them we see the logger do error and logger do catastrophe outputs but the logger doino is now no longer shown and that's because we're setting the default level to warn now I'm going to set that back to what actually is the default value here and that's info and we're now going to move on with the video and see how we can set this through an environment variable which is a very common practice for your log levels what we can do here in the level key is we can actually look at the process. infv which is going to give us access to environment variables and the process is a module built into nodejs once we get to that we can look for a particular key and I'm going to set a key called Pino log level here and if that exists it's going to set it to whatever that value is but we also maybe need to handle the case where that is not set we can do that by using an or expression in JavaScript and we can set a default value if this turns out to be undefined so let's set the default value if we don't have that environment variable to the info log level now what I'm going to do is I'm going to make the terminal a bit bigger here and we're going to try and run this and what I'm going to do now I'm on Windows here on pow shell I'm going to set an environment variable this will be different on a Mac OS or a Unix operating system but on pow shell what I can do is set the EnV Pino log level to warn so we're setting the default log level to one when I now run node index.js what's going to happen is we're not going to see the info output again for the same reasons as earlier in the video but if we change this environment variable and set it to info again we should now see after we execute that that we get all fre outputs so we can now set things through the environment and that's a common practice for log levels and it aders with the 12 Factor methodology for configuring your applications now if you're on a Unix system then what you can do is you can set the environment variable when you are actually executing the script so you can set penal log level equals Warn and then run index.js and of course you need the node command in order to do that but what you're doing before you actually execute the script is you're setting the log level and what you can also do on Unix is you can set the Pino log level for the duration of the terminal session by using the export command so let's now move on we're going to look at formatters now I'm going to go to the documentation for PJs a formatter is an object that contains functions for formatting the shape of your log lines and these functions should return adjacent fiable object and they allow for full customization of your resulting log lines now in order to customize this we can add a formatters key to the configuration object that we're passing to the Pino function here so let's add a new key called formatters and we're going to set this to a JavaScript object and let's say that we want to change the output for the level now if you remember the level was output as a numeric numerical value for example 30 for the info level and 50 for the error level for the level key in order to customize that we can provide a function here and that's going to take the label for that level and what we're going to do is we're going to return a new JavaScript object remember this has to be Json fiable and this object can allow us to set another value that we want to see for the level key in the output so what we're going to do is set the level to the label that we have and we're going to make that an uppercase string by calling the two uppercase method and we can then save that and what we're going to do is we're going to run node index.js and you can see the different formats now for the level key and the output we have the uppercase log levels label now instead of using that numerical value and that works as well with our custom level the catastrophe level we can see the output there and that might be a better way for you to represent your output it's up to you but you can use these formatters in order to change the output format of your logs so we're learning how to configure the Pino object in order to get the output that we want but this is at the moment just using the default keys and values that we get when we send a logger doino or error and so on each of these methods outputs the same set of keys but often in your logs you want to enrich those logs with useful information about particular events that are happening in your application so how do we add some custom context to the logs let's see how to do that now what I'm going to do to start with is remove the logger do catastrophe example and we can remove that custom level that we have as well we no longer need that and I'm going to Target this logger do error call that we have as well as the message we can actually pass as a first parameter an object of key value pairs that are going to be added to the log output so let's Show an example of that we're going to add a JavaScript object as the first argument here and let's say that we have a user who's making a particular call to a backend service and we want to Output the user's username here and let's just call them John do for demonstration purposes so we're adding a custom JavaScript object as the first argument to our logger method if we save the file and go back to the terminal and run node index.js you can see for the error output we are now getting this additional key value in the output so what we need to do if we want to customize the Json that's returned from our logger methods is simply add a JavaScript object containing the information we need as a first argument to these logger methods and we can also pipe this output to the penal pretty module and we're going to see that the output from that contains the custom keys and values just underneath the original message so it's very easy to add this custom information and we can add as many key value pairs as we want to this JavaScript object and as long as it's Json serializable it's going to appear in the output of the logs you can see this other key and value that we've added here let's now see another example we're going to look at how to create a child logger and what that entails in PJs let's remove the second value here but let's assume that we always wanted to Output the username into the log files just to track which users were making the different requests and Performing different actions in our application so we now have a logger doino call and a loger do error call and to both of those we're passing a username of John do now if we execute this it's going to work fine and we're going to see that username appear in both of these log outputs but let's imagine we have a lot of logs and we have the same keys and values that we want to Output all the time we can create what's called a child logger in order to consolidate that into a child object of the default logger and to do that let's have a look at the documentation for PJs on child loggers you can see a link to that in the description of the video what you can do is you can call the logger do child method and you can pass this JavaScript script object of all of the keys and values you want to use when you are working with an instance of that child logger so let's go back to VSS code and create one of those just now so just above these two functions I'm going to create some variables here let's create a variable called username and we'll set that to John do and as I've said here you might get this property from the request. user object in your Express Handler function for example but for now let's just hard code that in the application and then underneath that we're going to create a a new logger here called username logger and that's going to be an instance of the logger that we created here by calling the Pino function we're going to use that and call the child method on that and here is where we pass the custom keys and values that we need to that child logger so what I'm going to pass here is the username and we're going to set that equal to the username that we have on the line above now the benefit of doing this is it means that we can use this username logger here instead of the default logger so let's replace that with the username loger ER and we can then remove these JavaScript objects here so I'm going to remove these and we can then just pass in the message and by default the username will be output on both of those calls so let's test this out I'm going to clear the terminal and rerun the command and when we look at the output here we can see we still get the username and the output but we haven't needed to pass that object into these login calls these methods and that's because we're now using the child logger that has that set by default so if you have a logger in your application and you need to pass the same keys and values multiple times you might want to create that child logger and that makes the code a lot more maintainable it makes it a lot easier to write that code and if you need to change things you can do it in one place and that's where you define the child logger let's now move on to another example and we're going to show how to log errors in our application so in order to do that what I'm going to do at the very top of this file is Define a JavaScript function and that's a function called divide that's going to take two arguments A and B and it's simply going to return a divided by B so a very simple divide function it's redundant in JavaScript because we have a division operator but let's try and work with this and we're going to show some errors that may occur as you use this function now at the bottom I'm going to comment out this code that we just wrote and I'm going to write some new code here and let's say we wanted to log out the division of two numbers here so logger do info and I'm going to use a JavaScript template string here and let's say we get the result which is going to be equal to the divide function and we're passing two numbers into that function let's pass in five and zero so when we pass those in it's going to take those two numbers and it's going to divide five by zero and that's going to create a problem in the application so let's clear this out and run node index.js if we look at the message that's outputed we get a result of infinity so the problem here of course is that we're dividing by zero and we're getting an output here in JavaScript of infinity now what we're going to do in order to make this divide function a little bit better is we're going to check if B is equal to zero and if that's the case we're not going to perform this division actually what we're going to do is we're going to throw a new error and we're going to pass a message into that error saying that we cannot divide by zero so now there is a possibility that this function is going to return or rather throw an error so let's go back down and we're going to surround this in a try catch statement so what we're going to do we're going to try and get the result by calling divide so let's create a variable here called result and we're going to call divide and pass those two arguments in and then we can catch that exception so we're going to catch the error and what we're going to do if we get that error is we can create another logging statement here so logger do error and what we're going to do in order to actually pass the error through to the logging output is we're going to pass the error as a first argument to logger do error and as well as the error we're going to pass a message as always we're going to see that an error occurred during the division so now we're calling divide here in a tri block and if we get get that error what's going to happen is we're going to go to the catch block and we're going to use our logger and output that error so just by passing the error as a first argument we should hopefully see that in the output let's make the terminal bigger and we're going to run node index.js and this time we can see some different output and it's quite hard to read that so what I'm going to do is pipe that through to the penal pretty module and you can then see hopefully a better representation of that error that we have and we have a key called error and you can see the entire object here including a stack trace and within that we have the message cannot divide by zero and that is coming from the error that we have here that's the message we passed when we had that FR new error statement so that's all available in the output here all we need to do if we need to log the error objects is pass that error to our logger methods and that's going to appear in the Json output so we've now covered log levels we've now covered formatters and creating child loggers in the application we've covered how to pass context into our logging methods and we've also seen how to pass errors into our methods as well we're now going to move on to a New Concept and that's transports in PJs transports allow us to determine where the logs are going to be sent to Now by default what we've been doing so far is just outputting the logs to the terminal so the logs by default will be sent to standard output but it's very common to want to send your logs to files or to remote Services over the network let's now look at penal transports what we're going to do is go to the documentation and you can see that transports can be used to both transmit and also to transform your log output and one of the things to note here is that it's recommended that any log transformation or transmission is performed either in a separate thread or in a separate process and from Peno version 7 and upwards these transports can Now operate inside a worker thread and this helps your performance you can imagine if we have an API for example and you want to do some logging you don't want to have a transport that's logging to a file or over the network these operations might take some time and that might delay the response that you're sending to your clients you don't want that so you can actually do this work in a worker thread or in a different process and that's going to speed things up and allow you to respond to requests much quicker now what is a transport under the hood it's a module that defines or rather exports a default function that returns a writable stream in nodejs and this is useful to know if you're going to write your own transports but for example there is a built-in transport for sending the logs to a file and we have npm packages available if you want to send them to remote services such as better stack now I'll leave a link to this page below the video we're going to go to the API section and I'm going to scroll down here to the pen. transport function and I'm going to go to this function what this does is it creates a stream that Roots the logs to a worker thread that wraps around a Peno trans Port what we can do is call pin. transport and we provide a Target to that as well as some options and you can see a couple of examples below here we call pen. transport and we're providing multiple targets for example one target is the Pino pretty module and another one is the built-in Peno / file Target and when we specify Peno / file we have the options with a destination key and that destination is where the logs are going to be written to we're going to see an example of that now so let's go back to VSS code and I'm going to minimize this terminal and scroll to the top just above where we create the logger instance what we're going to do now is create a transport so let's create a variable here called transport and we're going to call Peno do transport and provide the object here that's going to Define these transports so we need a Target so we're going to use the built-in p/ file Target and what we also need is the options for this target we need to specify the destination and that's going to be a file where the output logs are going to be sent to and what I want to do here is specify a directory within my local directory and that's going to be called logs and we can then send the logs let's just say to a file called output. log and as you can see in the left hand side we don't currently have a directory called logs so we can also pass a makeer argument to this options and we can set that to true and that's going to create the directory if it doesn't already exist so this is a transport object and that's going to out put the logs to a file we now need to tell the penal logger object about this so let's copy the name of the variable and this is the second argument to the logger this entire first argument here is the options that configure the logger and that's a JavaScript object we're now going to add a second argument and that's going to be the transport and remember when we're using the pin. transport it's going to run the logging in a separate thread so let's now test this out and I'm going to make the terminal bigger here and we're going to run node index.js and and you can see when that runs we no longer have the output on the standard output on the terminal instead we now have a logs directory and we have a file here called output. log if we click through to that we get the Json for that log output for the error message so now our logs are being sent to a file and we can specify different transports for example if I go back to this definition here rather than penal file we can set the target to penal pretty and Peno pretty will understand if we set the destination to a file that it's going to Output to to that file and we can also pass because we're not sending that to the terminal we can pass colorize as false here and that's going to remove the color from that output let's try this again and we're going to run index.js and if we go back to our output. log file you can see we have a different format where the logs have been piped through the Peno pretty module and we can see in this case the error more clearly so it depends what you're looking for if you're looking for structured logging you might want the Json but for human readable logging you might want to use the penal pretty module mod now we can also log to multiple locations so far we've logged to standard output or to a file but what if we wanted to log to both let's see how we can do that now if we go back to the p. transport call we can provide a key called targets here and that's going to be an array in JavaScript and each object within that array will Define a specific Target that we want to use as a transport so we have the penal pretty module here that's outputting to our output. log file we might want to add a second transport that's going to Output to the terminal so again we want the target here to be penino pretty and let's set the options here in order to set the destination to standard output in order to set that to standard output we can use the process module in nodejs that has a standard out property and then we can use the file descriptor in order to send the logs to that file descriptor now before we run this I want to highlight something in the Pino documentation and that's for the formatters object that we defined earlier in the video what what we did earlier was customize the level as you can see below here and you can see this note here that the log level cannot be customized when you use multiple transports and that's what we're doing in vs code we have a transport object but we're defining multiple targets now in order for this to work we need to remove this formatters block of code here so let's remove that and we are now just going to pass a level in when we're customizing the Peno logger and we can pass the transport as a second argument let's now save this file and we're going to make the terminal bigger here when we run node index.js we now get the output appearing in the terminal but it's also going to be sent to our output file here so output. log also contains that output so now we have multiple transports the logs are being shipped to multiple locations and we can control that by defining this pen. transport object that contains multiple targets now we have a few more things to show in this video Let's now see how we might want to redact sensitive data from our log files now it's vitally important that you don't output sensitive data into logs you need to assume always that these logs can be read by anybody they might be read by malicious actors so you might want to redact certain data from your log output let's now see how to do that using PJs what I'm going to do here is I'm going to Define an object just below the logger instance so let's remove the code for dividing here we don't need that anymore and I'm going to remove this code at the bottom just to clean things up a little bit and we can also remove the divide function so what we're left with here is the pen. transport call and also our logger itself now what I'm going to do is Define an object and this is a JavaScript object that just contains some details the object is called employee and employees have an ID a name age email password and address now some of this information you might want to have in your logs for example you might want to log out the name of a user or their ID but on the other hand you probably don't want to Output the email you definitely don't want to Output the password and you don't want to Output the address either so what I'm going to do is add below that a call to logger doino and we're going to pass that employee object in as well as a message and let's give this a message of employee record and we can then save that and clear the terminal if we then run node index.js we get the output here that contains all of the keys and values all of the fields in that employee record now I've moved the terminal to the right hand side so that we can see this a little bit better as we build this example what we're going to do is try and redact the email the password and the address from this employee record so what we can do in order to do that is we can pass another key to the Pino options and this key is a key called redact and we can set this to an array of values that we want to hide from the output so for example I want to hide the email the password and the address from the log output if we add that array of values for the redact key we can save this file and we can then run the example on the right hand side and we're going to see a different output this time we have the employee record and you can see the values here for the ID and the age but the sensitive Fields with the email the password and the address they all contain this redacted string instead of the raw value and that's important as it can stop us logging that sensitive information to the terminal or to our log destinations and we can also change the redact key here to a JavaScript object so I'm going to change that to an object just now and the keys that we have here for example the paths are going to be set to that array that we defined before but as well as just redacting them we can actually remove them from the output if we want to save some space in our log files or stop sending as much information over the network instead of the raw value of redacted we can provide a key here called remove and set that to true and then when we run this again on the right hand side this time we don't get the redacted values we only get the raw values for the ID and the age so this shows how we can redact sensitive data from our log output what I'm going to do now is install fastify which is a backend framework for nodejs and we're going to see how we can use Pino with that framework we're going to see this very quickly and then we'll move on to the last part of the video so let's have a look at the fastify documentation you can see it's a package that has 29,000 Stars so we're talking about a very popular web framework for nodejs let's start by installing that so if we go down to the readme and click install we can install it into to our directory here with the mpm install command so mpm install fastify I pasted that in there we're going to run that and then we can create a new file in this application I'm going to call this app.js and this is going to contain the code to create a very basic web server now it turns out that fastify actually uses PJs by default and in order to get that working you can create the fastify object by importing it so require fastify and then once you create that object you instantiate it and provide a JavaScript object of configuration and in order to activate PJs we just simply pass logger true to that object once we've done that we can define an API route in the application we can do that with the fastify doget function for example so this is the API route and that's going to take a call back function when it gets a request which will take the request as the first argument and the reply as the second argument and we can log out some data here by using request. log that gives us access to the Pino instance and then we can use the normal methods that we saw before on that Pino logger for example error fatal info and Trace so let's log out an info call here and we're going to pass the request in that's going to Output the details from the request and then we can pass a message here of request to the server and then we can send a very simple response with the reply. send function and let's say that this API endpoint is just going to return a very simple piece of data so let's return a JavaScript object with the key of hello and the value of world we can then create the server Itself by using the fastify do listen function and to that we can pass a port so let's listen on Port 3000 so that's our listen function if we now run this application with node app.js you can see we're already getting some log output here and what I'm going to do is go to the browser and we're going to send a request to Local Host 3000 and we're going to check if we get this log output here so let's go to the browser and send that request and we get back the data that we specified from that Handler function and that's the hello world piece of Json data here and what we get back if we look at the terminal is some logging and you can see the message in this output here it doesn't look particularly good with all of this text on the right hand side but you can see request to server is the message and that matches what we passed in here to request. loginfo so if we have a request in our fastify Handler function we can access the logger through the request. log property and by default fastify as I said earlier it's using PS as its logging package so everything we've learned in this video about how to customize Peno loggers this will apply when you're using fastify as your framework and also if you're using something like Express or nestjs you can also configure those to use Peno as the loging framework and what we're going to do now to finish the video is we're going to show how we can define a transport that's going to send our logs to a centralized location on the web using better stack and this is many benefits it allows us to consolidate our logs in a central location it allows us to build indexes over those logs and then allows us to search very rapidly to find the data that we need and also to build dashboards and charts and analytics around the log data that's coming in so in order to do this let's cross over to the better stack platform we have the log service here and what we're going to do is we're going to create a source now we can hover over the info icon and as it says sources represent Services you want to collect logs from so we have a service let's say here in our application this very simple index.js file containing a Peno logger we want to send those logs to a source and that source is going to be on better stack so let's create the source and we'll give it a name of p- demo we also need to select a platform I'm going to select the JavaScript nodejs platform and then we're going to create that Source now once that source is created what you'll get back is a token here you can click this to copy that and then we can go back to the index.js file and we're going to paste or rather we're going to create a variable with that token stored in it so just at the top here I'm going to create a variable called token and we'll set that equal to that value now in a real application you want to extract that and store it somewhere secure for example as an environment variable but for now let's just store it as a raw value and then we're going to reference that in a second now let's cross over to the documentation for using JavaScript and nodejs with better stack better stack provides clients for JavaScript in nodejs and it provides these clients for multiple JavaScript logging Frameworks the one we're using of course is Pino and we have a transport that we can use for Peno but there are other Frameworks that you can see here as well so let's click the Pino transport and we'll be taken to the page here and I'll leave a link to this in the video description and the first step here is to install the log tail Peno npm package page this will allow us to send the logs via a transport to the better stack log platform so let's copy the mpm install command and the terminal is currently on the right hand side so let's paste that command in once that's installed what we're going to do is add another transport to this list of transports that we have here in the targets key so let's scroll down and we're going to define a new JavaScript object for the third transport in this list we're going to set the target equal to that package that we've just installed so it's at@ log tail /po and then we can set the options here and what we're going to do is pass as before a JavaScript object we're going to set a key of source token and we're going to make that equal to the Token that we created here on line three so let's paste that token in and that token is basically going to allow us to send those API requests with the logs to the better stack log platform and allow us to ship the logs to that location for further searching and Analysis so let's save this and I'm going to scroll down and what we're actually logging at the moment is this employee we're using a logger doino statement I'm going to add a couple of extra statements here let's bring back the logger do error statement and we can add one final statement and we'll use the logger do1 method to warn that we have a deprecated package now this time when we run index.js we're expecting to see the output on standard out and also in that log file because those are the two transports that we had before but we're also going to see that the logs are shipped to the better stack log platform so let's save this file and we're going to clear the terminal and run the index.js file and we're getting that output and that has finished running that script let's now go back to the browser and we're going to go to this page here where we created The Source earlier on if we click the live tail of this Source hopefully we're going to get those messages and we do and the logs that we see here these correspond to the logs from these functions that we called and we have the messages appearing in the better stack tail here now we can click these to see more information for example if we want to look at this employee record log we get the details from that log that now appear on the better stack log management platform for example the age of the employee is here and we get all those default details from the Pino loging such as the host name the level and the message now the cool thing here is that if we go back to the central page here we can actually search these logs for example if we wanted to get all error logs we can specify a search of log equals error and then that will filter down the logs and only give us back the ones where the log level is equal to error and you can search on a variety of different fields here for example if we wanted to look for a message that contains a particular value we could search for the message and then we can use the contains operator and if we look back to the functions here we're going to take the logger doino call that said employee record so let's look for any messages that can contain the word employee we're going to get back the record where the message contains the word employee so it's very easy to search your logs on better stack and all the fields are sent to the platform using that transport these will be indexed on the back end and that allows you to search through your logs very efficiently and very quickly to get the results you need and of course you can go further and build dashboards and charts and get some further insights into your log data and that's all for this video we've seen how to use use PS as a logging package in JavaScript and we've seen all of the core features that that provides from log levels to transports to formatters and so on if you're interested in further videos for example pairing PJs with Express or Nest JS let us know in the comments and if you're interested in other JavaScript logging packages such as Winston and you'd like to see videos on those please also let us know in the comments thanks again for watching and if you're interested in more videos like this please subscribe to the better stack YouTube channel and we'll see you in the next video
Info
Channel: Better Stack
Views: 6,637
Rating: undefined out of 5
Keywords:
Id: fluDEkA1h6w
Channel Id: undefined
Length: 41min 30sec (2490 seconds)
Published: Tue Nov 28 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.