{
    "mode": "perldoc",
    "parameter": "Log::Log4perl::Appender::Synchronized",
    "section": "",
    "url": "https://www.chedong.com/phpMan.php/perldoc/Log%3A%3ALog4perl%3A%3AAppender%3A%3ASynchronized/json",
    "generated": "2026-06-11T22:09:08Z",
    "synopsis": "use Log::Log4perl qw(:easy);\nmy $conf = qq(\nlog4perl.category                   = WARN, Syncer\n# File appender (unsynchronized)\nlog4perl.appender.Logfile           = Log::Log4perl::Appender::File\nlog4perl.appender.Logfile.autoflush = 1\nlog4perl.appender.Logfile.filename  = test.log\nlog4perl.appender.Logfile.mode      = truncate\nlog4perl.appender.Logfile.layout    = SimpleLayout\n# Synchronizing appender, using the file appender above\nlog4perl.appender.Syncer            = Log::Log4perl::Appender::Synchronized\nlog4perl.appender.Syncer.appender   = Logfile\n);\nLog::Log4perl->init(\\$conf);\nWARN(\"This message is guaranteed to be complete.\");",
    "sections": {
        "NAME": {
            "content": "Log::Log4perl::Appender::Synchronized - Synchronizing other appenders\n",
            "subsections": []
        },
        "SYNOPSIS": {
            "content": "use Log::Log4perl qw(:easy);\n\nmy $conf = qq(\nlog4perl.category                   = WARN, Syncer\n\n# File appender (unsynchronized)\nlog4perl.appender.Logfile           = Log::Log4perl::Appender::File\nlog4perl.appender.Logfile.autoflush = 1\nlog4perl.appender.Logfile.filename  = test.log\nlog4perl.appender.Logfile.mode      = truncate\nlog4perl.appender.Logfile.layout    = SimpleLayout\n\n# Synchronizing appender, using the file appender above\nlog4perl.appender.Syncer            = Log::Log4perl::Appender::Synchronized\nlog4perl.appender.Syncer.appender   = Logfile\n);\n\nLog::Log4perl->init(\\$conf);\nWARN(\"This message is guaranteed to be complete.\");\n",
            "subsections": []
        },
        "DESCRIPTION": {
            "content": "If multiple processes are using the same \"Log::Log4perl\" appender without synchronization,\noverwrites might happen. A typical scenario for this would be a process spawning children, each\nof which inherits the parent's Log::Log4perl configuration.\n\nIn most cases, you won't need an external synchronisation tool like\nLog::Log4perl::Appender::Synchronized at all. Log4perl's file appender,\nLog::Log4perl::Appender::File, for example, provides the \"syswrite\" mechanism for making sure\nthat even long log lines won't interleave. Short log lines won't interleave anyway, because the\noperating system makes sure the line gets written before a task switch occurs.\n\nIn cases where you need additional synchronization, however, you can use\n\"Log::Log4perl::Appender::Synchronized\" as a gateway between your loggers and your appenders. An\nappender itself, \"Log::Log4perl::Appender::Synchronized\" just takes two additional arguments:\n\n\"appender\"\nSpecifies the name of the appender it synchronizes access to. The appender specified must be\ndefined somewhere in the configuration file, not necessarily before the definition of\n\"Log::Log4perl::Appender::Synchronized\".\n\n\"key\"\nThis optional argument specifies the key for the semaphore that\n\"Log::Log4perl::Appender::Synchronized\" uses internally to ensure atomic operations. It\ndefaults to \"l4p\". If you define more than one \"Log::Log4perl::Appender::Synchronized\"\nappender, it is important to specify different keys for them, as otherwise every new\n\"Log::Log4perl::Appender::Synchronized\" appender will nuke previously defined semaphores.\nThe maximum key length is four characters, longer keys will be truncated to 4 characters --\n\"mylongkey1\" and \"mylongkey2\" are interpreted to be the same: \"mylo\" (thanks to David Viner\n<dviner@yahoo-inc.com> for pointing this out).\n\n\"Log::Log4perl::Appender::Synchronized\" uses Log::Log4perl::Util::Semaphore internally to\nperform locking with semaphores provided by the operating system used.\n",
            "subsections": [
                {
                    "name": "Performance tips",
                    "content": "The \"Log::Log4perl::Appender::Synchronized\" serializes access to a protected resource globally,\nslowing down actions otherwise performed in parallel.\n\nUnless specified otherwise, all instances of \"Log::Log4perl::Appender::Synchronized\" objects in\nthe system will use the same global IPC key \"l4p\".\n\nTo control access to different appender instances, it often makes sense to define different keys\nfor different synchronizing appenders. In this way, Log::Log4perl serializes access to each\nappender instance separately:\n\nlog4perl.category                   = WARN, Syncer1, Syncer2\n\n# File appender 1 (unsynchronized)\nlog4perl.appender.Logfile1           = Log::Log4perl::Appender::File\nlog4perl.appender.Logfile1.filename  = test1.log\nlog4perl.appender.Logfile1.layout    = SimpleLayout\n\n# File appender 2 (unsynchronized)\nlog4perl.appender.Logfile2           = Log::Log4perl::Appender::File\nlog4perl.appender.Logfile2.filename  = test2.log\nlog4perl.appender.Logfile2.layout    = SimpleLayout\n\n# Synchronizing appender, using the file appender above\nlog4perl.appender.Syncer1            = Log::Log4perl::Appender::Synchronized\nlog4perl.appender.Syncer1.appender   = Logfile1\nlog4perl.appender.Syncer1.key        = l4p1\n\n# Synchronizing appender, using the file appender above\nlog4perl.appender.Syncer2            = Log::Log4perl::Appender::Synchronized\nlog4perl.appender.Syncer2.appender   = Logfile2\nlog4perl.appender.Syncer2.key        = l4p2\n\nWithout the \".key = l4p1\" and \".key = l4p2\" lines, both Synchronized appenders would be using\nthe default \"l4p\" key, causing unnecessary serialization of output written to different files.\n"
                },
                {
                    "name": "Advanced configuration",
                    "content": "To configure the underlying Log::Log4perl::Util::Semaphore module in a different way than with\nthe default settings provided by Log::Log4perl::Appender::Synchronized, use the following\nparameters:\n\nlog4perl.appender.Syncer1.destroy  = 1\nlog4perl.appender.Syncer1.mode     = sub { 0775 }\nlog4perl.appender.Syncer1.uid      = hugo\nlog4perl.appender.Syncer1.gid      = 100\n\nValid options are \"destroy\" (Remove the semaphore on exit), \"mode\" (permissions on the\nsemaphore), \"uid\" (uid or user name the semaphore is owned by), and \"gid\" (group id the\nsemaphore is owned by),\n\nNote that \"mode\" is usually given in octal and therefore needs to be specified as a perl sub {},\nunless you want to calculate what 0755 means in decimal.\n\nChanging ownership or group settings for a semaphore will obviously only work if the current\nuser ID owns the semaphore already or if the current user is \"root\". The \"destroy\" option causes\nthe current process to destroy the semaphore on exit. Spawned children of the process won't\ninherit this behavior.\n"
                },
                {
                    "name": "Semaphore user and group IDs with modperl",
                    "content": "Setting user and group IDs is especially important when the Synchronized appender is used with\nmodperl. If Log4perl gets initialized by a startup handler, which runs as root, and not as the\nuser who will later use the semaphore, the settings for uid, gid, and mode can help establish\nmatching semaphore ownership and access rights.\n"
                }
            ]
        },
        "DEVELOPMENT NOTES": {
            "content": "\"Log::Log4perl::Appender::Synchronized\" is a *composite* appender. Unlike other appenders, it\ndoesn't log any messages, it just passes them on to its attached sub-appender. For this reason,\nit doesn't need a layout (contrary to regular appenders). If it defines none, messages are\npassed on unaltered.\n\nCustom filters are also applied to the composite appender only. They are *not* applied to the\nsub-appender. Same applies to appender thresholds. This behaviour might change in the future.\n",
            "subsections": []
        },
        "LICENSE": {
            "content": "Copyright 2002-2013 by Mike Schilli <m@perlmeister.com> and Kevin Goess <cpan@goess.org>.\n\nThis library is free software; you can redistribute it and/or modify it under the same terms as\nPerl itself.\n",
            "subsections": []
        },
        "AUTHOR": {
            "content": "Please contribute patches to the project on Github:\n\nhttp://github.com/mschilli/log4perl\n\nSend bug reports or requests for enhancements to the authors via our\n\nMAILING LIST (questions, bug reports, suggestions/patches): log4perl-devel@lists.sourceforge.net\n\nAuthors (please contact them via the list above, not directly): Mike Schilli\n<m@perlmeister.com>, Kevin Goess <cpan@goess.org>\n\nContributors (in alphabetical order): Ateeq Altaf, Cory Bennett, Jens Berthold, Jeremy Bopp,\nHutton Davidson, Chris R. Donnelly, Matisse Enzer, Hugh Esco, Anthony Foiani, James FitzGibbon,\nCarl Franks, Dennis Gregorovic, Andy Grundman, Paul Harrington, Alexander Hartmaier David Hull,\nRobert Jacobson, Jason Kohles, Jeff Macdonald, Markus Peter, Brett Rann, Peter Rabbitson, Erik\nSelberg, Aaron Straup Cope, Lars Thegler, David Viner, Mac Yang.\n",
            "subsections": []
        }
    },
    "summary": "Log::Log4perl::Appender::Synchronized - Synchronizing other appenders",
    "flags": [],
    "examples": [],
    "see_also": []
}