 Okay First of all, thank you for coming I'll tell if you worked about myself. My name is Yvail Donchev and I'm a technical community to hacksoft You can find me in any of these social channels and we're going to pull the slides from the talk in LinkedIn after a call I'm working in a Bulgaria software company for end-to-end development and we are based in Bulgaria You can see it north from Greece and South from Shingen And we kind of have a tradition to go to your partner conferences in the lab Eight years excluding the pandemic years and this is my third time making a talk here By the way, I have more sliders than minutes. So bear with me. Let's see how it goes First of all, how many of us have experienced and use Django in their daily work Cool and how many of us have experienced production outage with their current project this month Well, yeah, it's usually like that and it's usually in the times when you're it's not in the working hours It's either during the night or when you drink beer on the beach or when you have conference and Yeah Yeah to a development team. I love you guys. Nothing personal. Just a fresh example. That's how it goes and Well, when this happened Usually the priorities obviously to bring production back online It's not so important what happened and how it happened the first priority is to get production back online And the first step is usually just restart the workers and see how it goes but then it's Monday and We need to actually figure out what happened and why the production went down and we have two friends that can help us and that's the Monitoring and the way usually Monitoring to see how the resources are going or and how the traffic is going and walking for everything else Okay, last question. How many of us are comfortable when seeing the Django in configuration? By the way, the default Django walking configuration sounds pretty much complex per side Now while I was preparing the talk I saw a token junk on us with this meme and yeah, I had to put it here So before we start let's define what exactly is walking. I made a quick experiment and asked just GPT What is logging and it gave me gave me that complex explanation, which is true But it's kind of more abstract I'd love to read and Then I saw in the Python documentation and they say something more clearer and simpler that the logging is a means of Tracking events that happen when some software runs so it's always about tracking events that matters and If you start dink in the logging, that's the first example that you see you have the logging library that comes from the standard Python library And you have a method like warning and you could pass a string and you see outputs in your console And this is a good start, but it's actually a bad example to start with because We'll see why A better example with this We always use the logging library Python and We need to instantiate a lower class. We'll see what that means later And then Interface with the lower class to implement our logging for the software. So if we see that two lines First thing we see that the logging dot get lower the instance that the method that returns us the class has name And this is the core Principle in the lower that they're named And this is the equivalent with the logging dot warning the method internally instantiate the root water Which is the default over in the Logging module The next thing that we can see is that we pass a string watch out Which can be whatever string we want and this is actually the event if the logging is Tool for tracking events the event is what we pass to this method And it's usually a string and we see the warning method, which is just an example of what we could go and it's actually a set of levels That an event could have the level refers to the urgency of the event that we are tracking and we have five predefined levels that we have from the Python debug which is used only for diagnostic and we I mean walking by definition is made for bad times. You usually don't want to see the walking when the software runs properly but debug is something that you should Want to see only while developing Info is Level that refers to a confirmation that everything is working. Okay. Good example in Django is the HTTP request for example or the seller it does Warning means something bad happened, but it's not urgent. We could delay the fix software is running. Okay Error means something bad happened and part of the software is not working. For example, your API is broken And critical means just everything under fire and it's interesting that these are predefined levels They have numeric values and you can actually define your custom level for your Logging events So events or records have levels, but it's also case that the lowers have levels and The difference between the events levels and the overs levels that the event is the urgency of the message the level the lower means Basically the urgency of the lower this lower is supposed to to output only for example origin messages errors and Criticos and then we can see that the records have a destination which is by default your terminal and The destination is defined by the so-called handwar. Handwar is a class that comes from the login module in Python and it's responsible for Forwarding the events that you track to the destination that you want terminal file or some Web cloud like the socket handwar is just forwarding to the web Your events and a good example for this is sentry for example You normally in production would want to use something like socket handwar and we have a third place that have defined own level the handwar So you could have Event level you can have a lower level which is a future Logger with level warning without put only warning carrier and critical But the handwar defined in itself what kind of levels it's supposed to handle and forward So we have three components lower is the universal class. That is an interface that the code uses lock record that is the event and the handwar that sends the walk records to the appropriate destination and if we see that visually an example if we have the lower with Level warning Handwar with level error that would mean the lower is supposed to output only error warning carrier and critical messages But the handwar will only forward the error and critical messages and This is this is actually a good example of how you could manually configure the walking But that is not the recommended way that Python says Because imagine every time you you're making a jungle up You have to define step-by-step adding handwar setting levels and everything is to be nightmare The preferred way is what they call a dict config dict config is The out-of-the-box way that Python provides for configuring your walking And it sounds really similar to what we have in jungle. We have the lower ski the handwar ski and it basically a Dictionary with links between the keys. You have the my logger name to logger On level warning and he has console which is defined in the handwords console Just the linking between the keys in the dictionary By the way, we are going to use this dict configuration for the rest of the So a quick recap Lovers are named name is always unique if you get a water twice by the same name. It is the same water Loggers work with records or events Handwords is what defines a destination for events and all of the lowers records and handwares have their own levels Addiction reconfiguration is the preferred way for to define a walking for your app. So two more things handwares can Define their all for matters for matter is a class that comes out of the box from the logging and it's supposed to Get the record format it in a way literally format the string that goes to the handwar and then forward to the destination You could use the Python class or you could use the direct interface with this string like format and The next thing we have is filters filters are something that you could bind to either the logger or the handwar and You could execute an explicit Python logic when the event is forwarded either forwarded from the water or arriving in the handwar and The way that John will use it is by so-called debug true or give up false filters for example, you would want to Look basically queries if you are in development mode and you're you've set the true button production you want and The filter looks like that. It's just a Python class that Inherits the the logging filter and then Make the explicit check and maybe the most important thing about the loggers are that they actually have a hierarchy when you have a login configuration is always a mathematical tree of loggers that you have and The here he defined by the names with a separation of a point For example, if you have the loggers parent parent dot child Parent dot child is always a child word parent And if we have these three words defined here parent dot child parent dot child dot one child parent and We output a message from all of them. What would happen is that? the parent logo We output this message once Because of its handler the console handler The parental child's logo will output his message once for its own console handler and once for the parent handler because it will handle the child messages We have two messages and the grand child logo will output his message three times And that's something that we usually don't want sometimes we want but usually don't And we can manually configure that by setting the propagate boolean by true or false. It's part of the configuration Where you can set for a certain logger for example grand child. I would want to propagate the grand child Events to the child events, but I don't want to propagate the child events with the parent events This is a kind of fine-tuning configuration so if we have a logger that has its own handler and Has a parent over which has a parent handler and the propagates true the message will be Forwarded to where the propagate is set to true. This is the example from the login configuration that we saw so more of the story the hero is really important and Ideally the hero he should match your application's module structure Most of the time that is a rule of thumb We'll see an exception to a few sites So what about Django? We saw how the walking in Python works, but how does Django uses it? Well, even if you open the documentation you you'll see Sentence that say that Django actually use The Python configuration out of the box. He doesn't upgrade something. He doesn't provide a new interface for it just use the Python configuration and What is really good is that Django provides the entire here here vloggers Comes out of the box and it's a here here Meanings basically it's each logo is for example Django server is supposed to work on the HTTP request Django DB is a parent for SQL queries transactions and scheme and everything Which is really powerful So get back to the login configuration of Django. What it means we have the lower ski with Hope you can see it We have the lower ski and Each of the lower have defined their own handlers. So we have a dark linking between the keys and then We have defined Formatter for Django server and that's how a sample format or use that's the source code Django Literally checks the status code of the request and formats making the 500 red and 200 wide for example, and then we have explicit filters for The terminal output and the My what means output and the reason is you wouldn't want to send emails locally and you wouldn't want to Logs over both output in production probably So this is how it looks like. This is a default when configuration in Python We have the Django logo and the Django server logo and there's an explicit Propagate false setting that says, okay, I want to configure my Django server logo But I don't want to get from the handlers with Django over explicit check and We have the format or attached our Django server Formatter Django server handler and the two filters attached to the Django handlers So what if we want to use the lock all of our SQL queries? Well What we do is define Django DB backends logo in our lower key and This is a lower that comes out of the box from Django. It's a Document in the Django documentation we define our handler, which is forwarding to the stream handler, which is supposed to output in the terminal and We have the our own format or SQL format or which Only outputs the SQL query string without the time of execution and all the other things in the record custom lowers so in our app, we would want to place locks for debugging if something happens and We can configure them by explicitly saying the name of the lower and again the same pattern handlers and Everting and you could see that these two keys in the top version and disable existing cloggers so version is something that's Provided from the Python logging module, but it's not used yet. It's kind of Made with the idea that some if someday Python decides to change the format of the logging configuration entirely It should be backward compatible to the old software Disable listening cloggers is saying Okay, I want to define my login configuration as a dictionary and overwrite everything that I had disable everything that I've had before and So the next question is where to store the walks When when we are developing it's easy there me now. Well for urgent walks Sentry does the great job for storing this. It's a In the example that we saw it would be a hand word that only captures warning error and critical messages and forwarded to the Web socket handler to to sentry and this is this is really good to have this Split by urgency because when you open sentry you remove all the spam from the confirmation that things are working okay, and you see only the The things that are bad For non urgent walks, there are plenty of services outside and if you use some cloud-based deployment like Heroku or AWS It's usually a bad idea to store Files on the operating system where you put the locks It's usually a good better idea to use some cloud service like that's a dog to Have a good interface for querying because that that's what's important when you have You're walking and a few tips. So The locks are made for bad times. This is something that you realized with the first production outage and It's a good idea to put as much context as you can in your error handling and walking because When production is down, you might not be the one who write the code and remember what happened. It might be other person So, yeah, save that in mind The next thing is use sound visualization tool I found a cool package walking tree which you can call a method to and see a tree representation of your all of your logos in your app for a certain moment and then as I said, ideally the hero he should match the module structure But that know not always a good idea and channels is a good example of that in an older version of channels They have used the underscore the internet method name With the module and it turned out to be bad idea once they refactor their code You're enaming a file and suddenly you're walking configuration breaks Not only you're walking configuration, but anyone that uses channels So if you you're making a library that is supposed to be reused to other software's It's usually a good idea to be a constant exception handling These are three equivalent methods for exception handling and the first of them is kind of bad because you Explicitly assign the exception to a variable and then put it as a string to your lower dot error method a better way it would be calling explicitly the error method and Pass X info equal to true which you automatically capture the context from the accept And of course the logic module provides a short clip for that lower dot exception, which does exactly the same thing So I hope you're more comfortable now in the way configuration of Python and I would be really happy if you can some questions And also our CEO hacks of CEO will be having a lecture on Friday and it will be Really interesting one. So I sure you don't miss it. Oh, well a very interesting presentation Let's give him a second around a pause We now open the floor for questions we have five minutes So keep your question brief and to the point and there are two microphones one standing if it sits closer to the standing Microphone just go to the microphone. Otherwise the microphone myself Hello, thank you for the talk just a quick question Some other work I deal with legacy code Let's say generally where the logging had no configuration Just use the default in Django And I need to change that Throughout the code is logger info logger debug fairly random Any advice on how to treat that kind of sectional code? So it's older version of Python and older version of Django or it's Django 3.2 Python 3.7 at the moment Well, what I would do is first of all visualize the current configuration if I don't have an idea what currently Configure it in the end I would use something like that to visualize it and then define it explicitly in one place In the setting and start modifying on by one So I need to create a convic Yeah, it's like it doesn't even have one or you could define a new configuration and pass the disable existing words to false But then you have the case of mutating the current or in configuration And it's kind of implicit what that's not going to break something Yeah Okay, thank you very much. Thank you Any further questions? Let me check whether there's any remote questions. No Well, this pretty much concludes our talk, but we can continue our conversation In the hallway of a coffee and in the beer garden Thank you very much for coming Thank you