Best way to log from wherever?
Hi all, Happy New Year. :) What is the current thinking on the "best" or "right" way to log from all parts of your program? I wrestle with this occasionally. I'm not a programmer by trade (these are mainly personal/hobby projects, although I have done stuff for $WORK before), so it seems to me that maybe there's some best practice that I just haven't picked up on. I want to be able to log from any part of my program, have all the logs go through the same processing, and come out in the same place, with a minimum of fuss. Preferably using the same simple debug/info/warning/error APIs (from the logging client's point of view). For the web-facing portions of the app, that's simple enough: "use Dancer2 appname => ..." and be happy. By "any part of my program", I'm thinking of code that doesn't use Dancer2 and so doesn't get the DSL. * Methods in DBIx::Class::Result classes. (Mainly for debugging.) * app.psgi, where I might add a middleware that wants to log something. * Utility modules that don't handle routes and don't use Dancer2. (Maybe they should anyway?) These days, I usually make a "MyApp::Log" module and do something like: package MyApp::Log; use Dancer2 appname => 'MyApp::App'; use Exporter qw/import/; our @EXPORT = qw/debug info warning error/; That actually works pretty nicely; should I just do that? It feels like if that's supposed to be the way, it wouldn't require playing tricks with import(). Once I went so far as to write a Dancer2::Logger::App (never uploaded anywhere) that would call my app back to log, and consolidating the output stream that way. That was kinda fun, but after I did it I felt like I'd re-invented the wheel inside-out. I know there's a giant ecosystem of logging modules on CPAN. I've even played with Log::Any. I suspect the solution involves using one of them, but talking about the data flows gets so abstract I have trouble getting my head around how to use them to make the various sources send logs to the same place, where to configure it all from, and so on. Can someone help straighten me out on this? :) - Aaron -- Aaron Hall Sleep, where is thy sting? vitaphone.net Bed, where is thy victory?
On Tue, 5 Jan 2021 02:06:59 -0600 Aaron Hall wrote:
What is the current thinking on the "best" or "right" way to log from all parts of your program?
My preferred way is to use Log::Report throughout applications. There is no dependency on Dancer, so you can use consistent logging in all your modules, and then there is a Dancer plugin which integrates with the Dancer logging ecosystem. Log::Report is very powerful and as such can be a bit difficult to get your head round initially; on the flipside, however, it will almost certainly do anything you need in the future. Some of its features include: - Language translations - Different "dispatchers" for sending messages to - Different classes for messages - Different logging levels for exceptions - Options to pipe specific messages to different logging dispatchers The pod for Dancer2::Plugin::LogReport is well worth a read: https://metacpan.org/pod/Dancer2::Plugin::LogReport It's also possible to use Log::Report::Optional in all your modules, which will then only use the full Log::Report if it has been loaded by the main application, thereby keeping dependencies to a minimum. Feel free to ask any questions about its functionality here. Andy
On Tue, Jan 05, 2021 at 11:12:11AM +0000, Andrew Beverley wrote:
On Tue, 5 Jan 2021 02:06:59 -0600 Aaron Hall wrote:
What is the current thinking on the "best" or "right" way to log from all parts of your program?
My preferred way is to use Log::Report throughout applications. There is no dependency on Dancer, so you can use consistent logging in all your modules, and then there is a Dancer plugin which integrates with the Dancer logging ecosystem.
Hi Andy, thanks for the pointer, and thanks for the advice to read Dancer2::Plugin::LogReport first. LogReport definitely looks versatile. I wouldn't use nearly everything it offers, but that's probably true for them all. Anyone else want to stump for their favorite engine? :) More generally, it seems like the idea is: pick a log engine, use its Dancer integration in the Dancer parts of your app, and use the log engine's native APIs elsewhere. Do I understand correctly? - Aaron -- Aaron Hall I do quarrel with logic that says, "Stupid people vitaphone.net are associated with X, therefore X is stupid." Stupid people are associated with everything. -- Larry Wall
participants (2)
-
Aaron Hall -
Andrew Beverley