{
    "mode": "perldoc",
    "parameter": "Log::Any",
    "section": "",
    "url": "https://www.chedong.com/phpMan.php/perldoc/Log%3A%3AAny/json",
    "generated": "2026-06-16T07:05:38Z",
    "synopsis": "In a CPAN or other module:\npackage Foo;\nuse Log::Any qw($log);\n# log a string\n$log->error(\"an error occurred\");\n# log a string and some data\n$log->info(\"program started\",\n{progname => $0, pid => $$, perlversion => $]});\n# log a string and data using a format string\n$log->debugf(\"arguments are: %s\", \\@);\n# log an error and throw an exception\ndie $log->fatal(\"a fatal error occurred\");\nIn a Moo/Moose-based module:\npackage Foo;\nuse Log::Any ();\nuse Moo;\nhas log => (\nis => 'ro',\ndefault => sub { Log::Any->getlogger },\n);\nIn your application:\nuse Foo;\nuse Log::Any::Adapter;\n# Send all logs to Log::Log4perl\nLog::Any::Adapter->set('Log4perl');\n# Send all logs to Log::Dispatch\nmy $log = Log::Dispatch->new(outputs => [[ ... ]]);\nLog::Any::Adapter->set( 'Dispatch', dispatcher => $log );\n# See Log::Any::Adapter documentation for more options",
    "sections": {
        "NAME": {
            "content": "Log::Any - Bringing loggers and listeners together\n",
            "subsections": []
        },
        "VERSION": {
            "content": "version 1.710\n",
            "subsections": []
        },
        "SYNOPSIS": {
            "content": "In a CPAN or other module:\n\npackage Foo;\nuse Log::Any qw($log);\n\n# log a string\n$log->error(\"an error occurred\");\n\n# log a string and some data\n$log->info(\"program started\",\n{progname => $0, pid => $$, perlversion => $]});\n\n# log a string and data using a format string\n$log->debugf(\"arguments are: %s\", \\@);\n\n# log an error and throw an exception\ndie $log->fatal(\"a fatal error occurred\");\n\nIn a Moo/Moose-based module:\n\npackage Foo;\nuse Log::Any ();\nuse Moo;\n\nhas log => (\nis => 'ro',\ndefault => sub { Log::Any->getlogger },\n);\n\nIn your application:\n\nuse Foo;\nuse Log::Any::Adapter;\n\n# Send all logs to Log::Log4perl\nLog::Any::Adapter->set('Log4perl');\n\n# Send all logs to Log::Dispatch\nmy $log = Log::Dispatch->new(outputs => [[ ... ]]);\nLog::Any::Adapter->set( 'Dispatch', dispatcher => $log );\n\n# See Log::Any::Adapter documentation for more options\n",
            "subsections": []
        },
        "DESCRIPTION": {
            "content": "\"Log::Any\" provides a standard log production API for modules. Log::Any::Adapter allows\napplications to choose the mechanism for log consumption, whether screen, file or another\nlogging mechanism like Log::Dispatch or Log::Log4perl.\n\nMany modules have something interesting to say. Unfortunately there is no standard way for them\nto say it - some output to STDERR, others to \"warn\", others to custom file logs. And there is no\nstandard way to get a module to start talking - sometimes you must call a uniquely named method,\nother times set a package variable.\n\nThis being Perl, there are many logging mechanisms available on CPAN. Each has their pros and\ncons. Unfortunately, the existence of so many mechanisms makes it difficult for a CPAN author to\ncommit his/her users to one of them. This may be why many CPAN modules invent their own logging\nor choose not to log at all.\n\nTo untangle this situation, we must separate the two parts of a logging API. The first, *log\nproduction*, includes methods to output logs (like \"$log->debug\") and methods to inspect whether\na log level is activated (like \"$log->isdebug\"). This is generally all that CPAN modules care\nabout. The second, *log consumption*, includes a way to configure where logging goes (a file,\nthe screen, etc.) and the code to send it there. This choice generally belongs to the\napplication.\n\nA CPAN module uses \"Log::Any\" to get a log producer object. An application, in turn, may choose\none or more logging mechanisms via Log::Any::Adapter, or none at all.\n\n\"Log::Any\" has a very tiny footprint and no dependencies beyond Perl 5.8.1, which makes it\nappropriate for even small CPAN modules to use. It defaults to 'null' logging activity, so a\nmodule can safely log without worrying about whether the application has chosen (or will ever\nchoose) a logging mechanism.\n\nSee <http://www.openswartz.com/2007/09/06/standard-logging-api/> for the original post proposing\nthis module.\n",
            "subsections": []
        },
        "LOG LEVELS": {
            "content": "\"Log::Any\" supports the following log levels and aliases, which is meant to be inclusive of the\nmajor logging packages:\n\ntrace\ndebug\ninfo (inform)\nnotice\nwarning (warn)\nerror (err)\ncritical (crit, fatal)\nalert\nemergency\n\nLevels are translated as appropriate to the underlying logging mechanism. For example, log4perl\nonly has six levels, so we translate 'notice' to 'info' and the top three levels to 'fatal'. See\nthe documentation of an adapter class for specifics.\n",
            "subsections": []
        },
        "CATEGORIES": {
            "content": "Every logger has a category, generally the name of the class that asked for the logger. Some\nlogging mechanisms, like log4perl, can direct logs to different places depending on category.\n\nPRODUCING LOGS (FOR MODULES)",
            "subsections": [
                {
                    "name": "Getting a logger",
                    "content": "The most convenient way to get a logger in your module is:\n\nuse Log::Any qw($log);\n\nThis creates a package variable *$log* and assigns it to the logger for the current package. It\nis equivalent to\n\nour $log = Log::Any->getlogger;\n\nIn general, to get a logger for a specified category:\n\nmy $log = Log::Any->getlogger(category => $category)\n\nIf no category is specified, the calling package is used.\n\nA logger object is an instance of Log::Any::Proxy, which passes on messages to the\nLog::Any::Adapter handling its category.\n\nIf the \"proxyclass\" argument is passed, an alternative to Log::Any::Proxy (such as a subclass)\nwill be instantiated and returned instead. The argument is automatically prepended with\n\"Log::Any::Proxy::\". If instead you want to pass the full name of a proxy class, prefix it with\na \"+\". E.g.\n\n# Log::Any::Proxy::Foo\nmy $log = Log::Any->getlogger(proxyclass => 'Foo');\n\n# MyLog::Proxy\nmy $log = Log::Any->getlogger(proxyclass => '+MyLog::Proxy');\n"
                },
                {
                    "name": "Logging",
                    "content": "To log a message, pass a single string to any of the log levels or aliases. e.g.\n\n$log->error(\"this is an error\");\n$log->warn(\"this is a warning\");\n$log->warning(\"this is also a warning\");\n\nThe log string will be returned so that it can be used further (e.g. for a \"die\" or \"warn\"\ncall).\n\nYou should not include a newline in your message; that is the responsibility of the logging\nmechanism, which may or may not want the newline.\n\nIf you want to log additional structured data alongside with your string, you can add a single\nhashref after your log string. e.g.\n\n$log->info(\"program started\",\n{progname => $0, pid => $$, perlversion => $]});\n\nIf the configured Log::Any::Adapter does not support logging structured data, the hash will be\nconverted to a string using Data::Dumper.\n\nThere are also versions of each of the logging methods with an additional \"f\" suffix (\"infof\",\n\"errorf\", \"debugf\", etc.) that format a list of arguments. The specific formatting mechanism and\nmeaning of the arguments is controlled by the Log::Any::Proxy object.\n\n$log->errorf(\"an error occurred: %s\", $@);\n$log->debugf(\"called with %d params: %s\", $paramcount, \\@params);\n\nBy default it renders like \"sprintf\", with the following additional features:\n\n*   Any complex references (like \"\\@params\" above) are automatically converted to single-line\nstrings with Data::Dumper.\n\n*   Any undefined values are automatically converted to the string \"<undef>\".\n"
                },
                {
                    "name": "Log level detection",
                    "content": "To detect whether a log level is on, use \"is\" followed by any of the log levels or aliases.\ne.g.\n\nif ($log->isinfo()) { ... }\n$log->debug(\"arguments are: \" . Dumper(\\@))\nif $log->isdebug();\n\nThis is important for efficiency, as you can avoid the work of putting together the logging\nmessage (in the above case, stringifying @) if the log level is not active.\n\nThe formatting methods (\"infof\", \"errorf\", etc.) check the log level for you.\n\nSome logging mechanisms don't support detection of log levels. In these cases the detection\nmethods will always return 1.\n\nIn contrast, the default logging mechanism - Null - will return 0 for all detection methods.\n"
                },
                {
                    "name": "Log context data",
                    "content": "\"Log::Any\" supports logging context data by exposing the \"context\" hashref. All the key/value\npairs added to this hash will be printed with every log message. You can localize the data so\nthat it will be removed again automatically at the end of the block:\n\n$log->context->{directory} = $dir;\nfor my $file (glob \"$dir/*\") {\nlocal $log->context->{file} = basename($file);\n$log->warn(\"Can't read file!\") unless -r $file;\n}\n\nThis will produce the following line:\n\nCan't read file! {directory => '/foo',file => 'bar'}\n\nIf the configured Log::Any::Adapter does not support structured data, the context hash will be\nconverted to a string using Data::Dumper, and will be appended to the log message.\n"
                },
                {
                    "name": "Setting an alternate default logger",
                    "content": "When no other adapters are configured for your logger, \"Log::Any\" uses the \"defaultadapter\". To\nchoose something other than Null as the default, either set the \"LOGANYDEFAULTADAPTER\"\nenvironment variable, or pass it as a parameter when loading \"Log::Any\"\n\nuse Log::Any '$log', defaultadapter => 'Stderr';\n\nThe name of the default class follows the same rules as used by Log::Any::Adapter.\n\nTo pass arguments to the default adapter's constructor, use an arrayref:\n\nuse Log::Any '$log', defaultadapter => [ 'File' => '/var/log/mylog.log' ];\n\nWhen a consumer configures their own adapter, the default adapter will be overridden. If they\nlater remove their adapter, the default adapter will be used again.\n"
                },
                {
                    "name": "Configuring the proxy",
                    "content": "Any parameters passed on the import line or via the \"getlogger\" method are passed on to the\nLog::Any::Proxy constructor.\n\nuse Log::Any '$log', filter => \\&myfilter;\n"
                },
                {
                    "name": "Testing",
                    "content": "Log::Any::Test provides a mechanism to test code that uses \"Log::Any\".\n\nCONSUMING LOGS (FOR APPLICATIONS)\nLog::Any provides modules with a Log::Any::Proxy object, which is the log producer. To consume\nits output and direct it where you want (a file, the screen, syslog, etc.), you use\nLog::Any::Adapter along with a destination-specific subclass.\n\nFor example, to send output to a file via Log::Any::Adapter::File, your application could do\nthis:\n\nuse Log::Any::Adapter ('File', '/path/to/file.log');\n\nSee the Log::Any::Adapter documentation for more details.\n\nTo detect if a consumer exists, use \"Log::Any->hasconsumer\".\n\nQ & A\nIsn't Log::Any just yet another logging mechanism?\nNo. \"Log::Any\" does not include code that knows how to log to a particular place (file,\nscreen, etc.) It can only forward logging requests to another logging mechanism.\n\nWhy don't you just pick the best logging mechanism, and use and promote it?\nEach of the logging mechanisms have their pros and cons, particularly in terms of how they\nare configured. For example, log4perl offers a great deal of power and flexibility but uses\na global and potentially heavy configuration, whereas Log::Dispatch is extremely\nconfiguration-light but doesn't handle categories. There is also the unnamed future logger\nthat may have advantages over either of these two, and all the custom in-house loggers\npeople have created and cannot (for whatever reason) stop using.\n\nIs it safe for my critical module to depend on Log::Any?\nOur intent is to keep \"Log::Any\" minimal, and change it only when absolutely necessary. Most\nof the \"innovation\", if any, is expected to occur in \"Log::Any::Adapter\", which your module\nshould not have to depend on (unless it wants to direct logs somewhere specific). \"Log::Any\"\nhas no non-core dependencies.\n\nWhy doesn't Log::Any use *insert modern Perl technique*?\nTo encourage CPAN module authors to adopt and use \"Log::Any\", we aim to have as few\ndependencies and chances of breakage as possible. Thus, no \"Moose\" or other niceties.\n"
                }
            ]
        },
        "AUTHORS": {
            "content": "*   Jonathan Swartz <swartz@pobox.com>\n\n*   David Golden <dagolden@cpan.org>\n\n*   Doug Bell <preaction@cpan.org>\n\n*   Daniel Pittman <daniel@rimspace.net>\n\n*   Stephen Thirlwall <sdt@cpan.org>\n",
            "subsections": []
        },
        "CONTRIBUTORS": {
            "content": "*   bj5004 <bartosz.jakubski@hurra.com>\n\n*   cm-perl <cm-perl@users.noreply.github.com>\n\n*   Jonathan <jjrs.pam+github@gmail.com>\n\n*   Karen Etheridge <ether@cpan.org>\n\n*   Konstantin S. Uvarin <khedin@gmail.com>\n\n*   Lucas Kanashiro <kanashiro.duarte@gmail.com>\n\n*   Maros Kollar <maros.kollar@geizhals.at>\n\n*   Maxim Vuets <maxim.vuets@booking.com>\n\n*   mephinet <mephinet@gmx.net>\n\n*   Michael Conrad <mconrad@intellitree.com>\n\n*   Nick Tonkin <1nickt@users.noreply.github.com>\n\n*   Paul Durden <alabamapaul@gmail.com>\n\n*   Philipp Gortan <philipp.gortan@apa.at>\n\n*   Phill Legault <saladdayllc@gmail.com>\n\n*   Shlomi Fish <shlomif@shlomifish.org>\n",
            "subsections": []
        },
        "COPYRIGHT AND LICENSE": {
            "content": "This software is copyright (c) 2017 by Jonathan Swartz, David Golden, and Doug Bell.\n\nThis is free software; you can redistribute it and/or modify it under the same terms as the Perl\n5 programming language system itself.\n",
            "subsections": []
        }
    },
    "summary": "Log::Any - Bringing loggers and listeners together",
    "flags": [],
    "examples": [],
    "see_also": []
}