Log-Dispatch-2.67/0000775000175000017500000000000013162076057013577 5ustar autarchautarchLog-Dispatch-2.67/dist.ini0000644000175000017500000000200513162076057015236 0ustar autarchautarchname = Log-Dispatch author = Dave Rolsky license = Artistic_2_0 copyright_holder = Dave Rolsky [@DROLSKY] dist = Log-Dispatch pod_coverage_skip = Log::Dispatch::ApacheLog pod_coverage_skip = Log::Dispatch::Conflicts pod_coverage_trustme = Log::Dispatch => qr/^(?:warn|err|crit|emerg)$/ pod_coverage_trustme = Log::Dispatch => qr/^is_\w+$/ pod_coverage_trustme = Log::Dispatch::File => qr/^(?:O_)?APPEND$/ pod_coverage_trustme = Log::Dispatch::Output => qr/^new$/ stopwords_file = .stopwords prereqs_skip = Apache2?::Log prereqs_skip = ^Mail:: prereqs_skip = MIME::Lite prereqs_skip = threads prereqs_skip = threads::shared use_github_issues = 1 -remove = Test::CleanNamespaces -remove = Test::Compile -remove = Test::Synopsis -remove = Test::Version [Prereqs / DevelopRequires] MIME::Lite = 0 Mail::Send = 0 Mail::Sender = 0 Mail::Sendmail = 0 [FileFinder::ByName / MostLibs] dir = lib skip = Log/Dispatch/Conflicts.pm [Test::Version] finder = MostLibs [Conflicts] Log::Dispatch::File::Stamped = 0.17 Log-Dispatch-2.67/META.yml0000644000175000017500000006100113162076057015044 0ustar autarchautarch--- abstract: 'Dispatches messages to one or more outputs' author: - 'Dave Rolsky ' build_requires: Data::Dumper: '0' ExtUtils::MakeMaker: '0' File::Spec: '0' File::Temp: '0' FindBin: '0' Getopt::Long: '0' IO::File: '0' IPC::Run3: '0' POSIX: '0' PerlIO: '0' Test::Fatal: '0' Test::More: '0.96' Test::Needs: '0' lib: '0' utf8: '0' configure_requires: Dist::CheckConflicts: '0.02' ExtUtils::MakeMaker: '0' dynamic_config: 0 generated_by: 'Dist::Zilla version 6.010, CPAN::Meta::Converter version 2.150010' license: artistic_2 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Log-Dispatch provides: Log::Dispatch: file: lib/Log/Dispatch.pm version: '2.67' Log::Dispatch::ApacheLog: file: lib/Log/Dispatch/ApacheLog.pm version: '2.67' Log::Dispatch::Base: file: lib/Log/Dispatch/Base.pm version: '2.67' Log::Dispatch::Code: file: lib/Log/Dispatch/Code.pm version: '2.67' Log::Dispatch::Email: file: lib/Log/Dispatch/Email.pm version: '2.67' Log::Dispatch::Email::MIMELite: file: lib/Log/Dispatch/Email/MIMELite.pm version: '2.67' Log::Dispatch::Email::MailSend: file: lib/Log/Dispatch/Email/MailSend.pm version: '2.67' Log::Dispatch::Email::MailSender: file: lib/Log/Dispatch/Email/MailSender.pm version: '2.67' Log::Dispatch::Email::MailSendmail: file: lib/Log/Dispatch/Email/MailSendmail.pm version: '2.67' Log::Dispatch::File: file: lib/Log/Dispatch/File.pm version: '2.67' Log::Dispatch::File::Locked: file: lib/Log/Dispatch/File/Locked.pm version: '2.67' Log::Dispatch::Handle: file: lib/Log/Dispatch/Handle.pm version: '2.67' Log::Dispatch::Null: file: lib/Log/Dispatch/Null.pm version: '2.67' Log::Dispatch::Output: file: lib/Log/Dispatch/Output.pm version: '2.67' Log::Dispatch::Screen: file: lib/Log/Dispatch/Screen.pm version: '2.67' Log::Dispatch::Syslog: file: lib/Log/Dispatch/Syslog.pm version: '2.67' Log::Dispatch::Types: file: lib/Log/Dispatch/Types.pm version: '2.67' Log::Dispatch::Vars: file: lib/Log/Dispatch/Vars.pm version: '2.67' requires: Carp: '0' Devel::GlobalDestruction: '0' Dist::CheckConflicts: '0.02' Encode: '0' Exporter: '0' Fcntl: '0' IO::Handle: '0' Module::Runtime: '0' Params::ValidationCompiler: '0' Scalar::Util: '0' Specio: '0.32' Specio::Declare: '0' Specio::Exporter: '0' Specio::Library::Builtins: '0' Specio::Library::Numeric: '0' Specio::Library::String: '0' Sys::Syslog: '0.28' Try::Tiny: '0' base: '0' namespace::autoclean: '0' parent: '0' perl: '5.006' strict: '0' warnings: '0' resources: bugtracker: https://github.com/houseabsolute/Log-Dispatch/issues homepage: http://metacpan.org/release/Log-Dispatch repository: git://github.com/houseabsolute/Log-Dispatch.git version: '2.67' x_Dist_Zilla: perl: version: '5.024001' plugins: - class: Dist::Zilla::Plugin::MakeMaker config: Dist::Zilla::Role::TestRunner: default_jobs: 1 name: '@DROLSKY/MakeMaker' version: '6.010' - class: Dist::Zilla::Plugin::Git::GatherDir config: Dist::Zilla::Plugin::GatherDir: exclude_filename: - CONTRIBUTING.md - LICENSE - Makefile.PL - README.md - cpanfile exclude_match: [] follow_symlinks: 0 include_dotfiles: 0 prefix: '' prune_directory: [] root: . Dist::Zilla::Plugin::Git::GatherDir: include_untracked: 0 name: '@DROLSKY/Git::GatherDir' version: '2.042' - class: Dist::Zilla::Plugin::ManifestSkip name: '@DROLSKY/ManifestSkip' version: '6.010' - class: Dist::Zilla::Plugin::License name: '@DROLSKY/License' version: '6.010' - class: Dist::Zilla::Plugin::ExecDir name: '@DROLSKY/ExecDir' version: '6.010' - class: Dist::Zilla::Plugin::ShareDir name: '@DROLSKY/ShareDir' version: '6.010' - class: Dist::Zilla::Plugin::Manifest name: '@DROLSKY/Manifest' version: '6.010' - class: Dist::Zilla::Plugin::CheckVersionIncrement name: '@DROLSKY/CheckVersionIncrement' version: '0.121750' - class: Dist::Zilla::Plugin::TestRelease name: '@DROLSKY/TestRelease' version: '6.010' - class: Dist::Zilla::Plugin::ConfirmRelease name: '@DROLSKY/ConfirmRelease' version: '6.010' - class: Dist::Zilla::Plugin::UploadToCPAN name: '@DROLSKY/UploadToCPAN' version: '6.010' - class: Dist::Zilla::Plugin::VersionFromMainModule name: '@DROLSKY/VersionFromMainModule' version: '0.03' - class: Dist::Zilla::Plugin::Authority name: '@DROLSKY/Authority' version: '1.009' - class: Dist::Zilla::Plugin::AutoPrereqs name: '@DROLSKY/AutoPrereqs' version: '6.010' - class: Dist::Zilla::Plugin::CopyFilesFromBuild name: '@DROLSKY/CopyFilesFromBuild' version: '0.170880' - class: Dist::Zilla::Plugin::GitHub::Meta name: '@DROLSKY/GitHub::Meta' version: '0.44' - class: Dist::Zilla::Plugin::GitHub::Update config: Dist::Zilla::Plugin::GitHub::Update: metacpan: 1 name: '@DROLSKY/GitHub::Update' version: '0.44' - class: Dist::Zilla::Plugin::MetaResources name: '@DROLSKY/MetaResources' version: '6.010' - class: Dist::Zilla::Plugin::MetaProvides::Package config: Dist::Zilla::Plugin::MetaProvides::Package: finder_objects: - class: Dist::Zilla::Plugin::FinderCode name: '@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM' version: '6.010' include_underscores: 0 Dist::Zilla::Role::MetaProvider::Provider: $Dist::Zilla::Role::MetaProvider::Provider::VERSION: '2.002004' inherit_missing: '1' inherit_version: '1' meta_noindex: '1' Dist::Zilla::Role::ModuleMetadata: Module::Metadata: '1.000033' version: '0.004' name: '@DROLSKY/MetaProvides::Package' version: '2.004003' - class: Dist::Zilla::Plugin::Meta::Contributors name: '@DROLSKY/Meta::Contributors' version: '0.003' - class: Dist::Zilla::Plugin::MetaConfig name: '@DROLSKY/MetaConfig' version: '6.010' - class: Dist::Zilla::Plugin::MetaJSON name: '@DROLSKY/MetaJSON' version: '6.010' - class: Dist::Zilla::Plugin::MetaYAML name: '@DROLSKY/MetaYAML' version: '6.010' - class: Dist::Zilla::Plugin::NextRelease name: '@DROLSKY/NextRelease' version: '6.010' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: test type: requires name: '@DROLSKY/Test::More with subtest' version: '6.010' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: develop type: requires name: '@DROLSKY/Modules for use with tidyall' version: '6.010' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: develop type: requires name: '@DROLSKY/Test::Version which fixes https://github.com/plicease/Test-Version/issues/7' version: '6.010' - class: Dist::Zilla::Plugin::PromptIfStale config: Dist::Zilla::Plugin::PromptIfStale: check_all_plugins: 0 check_all_prereqs: 0 modules: - Dist::Zilla::PluginBundle::DROLSKY phase: build run_under_travis: 0 skip: [] name: '@DROLSKY/Dist::Zilla::PluginBundle::DROLSKY' version: '0.054' - class: Dist::Zilla::Plugin::PromptIfStale config: Dist::Zilla::Plugin::PromptIfStale: check_all_plugins: 1 check_all_prereqs: 1 modules: [] phase: release run_under_travis: 0 skip: - Dist::Zilla::Plugin::DROLSKY::Contributors - Dist::Zilla::Plugin::DROLSKY::Git::CheckFor::CorrectBranch - Dist::Zilla::Plugin::DROLSKY::License - Dist::Zilla::Plugin::DROLSKY::TidyAll - Dist::Zilla::Plugin::DROLSKY::WeaverConfig - Pod::Weaver::PluginBundle::DROLSKY name: '@DROLSKY/PromptIfStale' version: '0.054' - class: Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable name: '@DROLSKY/Test::Pod::Coverage::Configurable' version: '0.06' - class: Dist::Zilla::Plugin::Test::PodSpelling config: Dist::Zilla::Plugin::Test::PodSpelling: directories: - bin - lib spell_cmd: '' stopwords: - API - CPAN - Cholet - DROLSKY - "DROLSKY's" - Dumont - Goess - Manfredi - Miyagawa - NTLM - PayPal - PayPal - Pfeiffer - Rolsky - "Rolsky's" - STDERR - STDOUT - Schilli - Straup - Subclasses - Swartz - TLS - Tatsuhiko - UTF - apache - appenders - auth - authid - authpriv - authpwd - autoflushed - classname - crit - drolsky - emerg - fd - filename - ident - kern - logopt - multi - params - replyto - smtp - stderr - "subclass's" - subclasses - uucp wordlist: Pod::Wordlist name: '@DROLSKY/Test::PodSpelling' version: '2.007004' - class: Dist::Zilla::Plugin::PodSyntaxTests name: '@DROLSKY/PodSyntaxTests' version: '6.010' - class: Dist::Zilla::Plugin::RunExtraTests config: Dist::Zilla::Role::TestRunner: default_jobs: 1 name: '@DROLSKY/RunExtraTests' version: '0.029' - class: Dist::Zilla::Plugin::MojibakeTests name: '@DROLSKY/MojibakeTests' version: '0.8' - class: Dist::Zilla::Plugin::Test::CPAN::Changes config: Dist::Zilla::Plugin::Test::CPAN::Changes: changelog: Changes name: '@DROLSKY/Test::CPAN::Changes' version: '0.012' - class: Dist::Zilla::Plugin::Test::CPAN::Meta::JSON name: '@DROLSKY/Test::CPAN::Meta::JSON' version: '0.004' - class: Dist::Zilla::Plugin::Test::EOL config: Dist::Zilla::Plugin::Test::EOL: filename: xt/author/eol.t finder: - ':ExecFiles' - ':InstallModules' - ':TestFiles' trailing_whitespace: 1 name: '@DROLSKY/Test::EOL' version: '0.19' - class: Dist::Zilla::Plugin::Test::NoTabs config: Dist::Zilla::Plugin::Test::NoTabs: filename: xt/author/no-tabs.t finder: - ':InstallModules' - ':ExecFiles' - ':TestFiles' name: '@DROLSKY/Test::NoTabs' version: '0.15' - class: Dist::Zilla::Plugin::Test::Portability config: Dist::Zilla::Plugin::Test::Portability: options: '' name: '@DROLSKY/Test::Portability' version: '2.001000' - class: Dist::Zilla::Plugin::Test::TidyAll name: '@DROLSKY/Test::TidyAll' version: '0.04' - class: Dist::Zilla::Plugin::Test::ReportPrereqs name: '@DROLSKY/Test::ReportPrereqs' version: '0.027' - class: Dist::Zilla::Plugin::DROLSKY::Contributors name: '@DROLSKY/DROLSKY::Contributors' version: '0.85' - class: Dist::Zilla::Plugin::Git::Contributors config: Dist::Zilla::Plugin::Git::Contributors: git_version: 2.14.1 include_authors: 0 include_releaser: 1 order_by: name paths: [] name: '@DROLSKY/Git::Contributors' version: '0.030' - class: Dist::Zilla::Plugin::SurgicalPodWeaver config: Dist::Zilla::Plugin::PodWeaver: config_plugins: - '@DROLSKY' finder: - ':InstallModules' - ':ExecFiles' plugins: - class: Pod::Weaver::Plugin::EnsurePod5 name: '@CorePrep/EnsurePod5' version: '4.015' - class: Pod::Weaver::Plugin::H1Nester name: '@CorePrep/H1Nester' version: '4.015' - class: Pod::Weaver::Plugin::SingleEncoding name: '@DROLSKY/SingleEncoding' version: '4.015' - class: Pod::Weaver::Plugin::Transformer name: '@DROLSKY/List' version: '4.015' - class: Pod::Weaver::Plugin::Transformer name: '@DROLSKY/Verbatim' version: '4.015' - class: Pod::Weaver::Section::Region name: '@DROLSKY/header' version: '4.015' - class: Pod::Weaver::Section::Name name: '@DROLSKY/Name' version: '4.015' - class: Pod::Weaver::Section::Version name: '@DROLSKY/Version' version: '4.015' - class: Pod::Weaver::Section::Region name: '@DROLSKY/prelude' version: '4.015' - class: Pod::Weaver::Section::Generic name: SYNOPSIS version: '4.015' - class: Pod::Weaver::Section::Generic name: DESCRIPTION version: '4.015' - class: Pod::Weaver::Section::Generic name: OVERVIEW version: '4.015' - class: Pod::Weaver::Section::Collect name: ATTRIBUTES version: '4.015' - class: Pod::Weaver::Section::Collect name: METHODS version: '4.015' - class: Pod::Weaver::Section::Collect name: FUNCTIONS version: '4.015' - class: Pod::Weaver::Section::Collect name: TYPES version: '4.015' - class: Pod::Weaver::Section::Leftovers name: '@DROLSKY/Leftovers' version: '4.015' - class: Pod::Weaver::Section::Region name: '@DROLSKY/postlude' version: '4.015' - class: Pod::Weaver::Section::GenerateSection name: '@DROLSKY/generate SUPPORT' version: '1.06' - class: Pod::Weaver::Section::AllowOverride name: '@DROLSKY/allow override SUPPORT' version: '0.05' - class: Pod::Weaver::Section::GenerateSection name: '@DROLSKY/generate SOURCE' version: '1.06' - class: Pod::Weaver::Section::GenerateSection name: '@DROLSKY/generate DONATIONS' version: '1.06' - class: Pod::Weaver::Section::Authors name: '@DROLSKY/Authors' version: '4.015' - class: Pod::Weaver::Section::Contributors name: '@DROLSKY/Contributors' version: '0.009' - class: Pod::Weaver::Section::Legal name: '@DROLSKY/Legal' version: '4.015' - class: Pod::Weaver::Section::Region name: '@DROLSKY/footer' version: '4.015' name: '@DROLSKY/SurgicalPodWeaver' version: '0.0023' - class: Dist::Zilla::Plugin::DROLSKY::WeaverConfig name: '@DROLSKY/DROLSKY::WeaverConfig' version: '0.85' - class: Dist::Zilla::Plugin::ReadmeAnyFromPod config: Dist::Zilla::Role::FileWatcher: version: '0.006' name: '@DROLSKY/README.md in build' version: '0.163250' - class: Dist::Zilla::Plugin::GenerateFile::FromShareDir config: Dist::Zilla::Plugin::GenerateFile::FromShareDir: destination_filename: CONTRIBUTING.md dist: Dist-Zilla-PluginBundle-DROLSKY encoding: UTF-8 has_xs: '0' location: build source_filename: CONTRIBUTING.md Dist::Zilla::Role::RepoFileInjector: allow_overwrite: 1 repo_root: . version: '0.007' name: '@DROLSKY/Generate CONTRIBUTING.md' version: '0.013' - class: Dist::Zilla::Plugin::InstallGuide name: '@DROLSKY/InstallGuide' version: '1.200007' - class: Dist::Zilla::Plugin::CPANFile name: '@DROLSKY/CPANFile' version: '6.010' - class: Dist::Zilla::Plugin::DROLSKY::License name: '@DROLSKY/DROLSKY::License' version: '0.85' - class: Dist::Zilla::Plugin::CheckStrictVersion name: '@DROLSKY/CheckStrictVersion' version: '0.001' - class: Dist::Zilla::Plugin::CheckSelfDependency config: Dist::Zilla::Plugin::CheckSelfDependency: finder: - ':InstallModules' Dist::Zilla::Role::ModuleMetadata: Module::Metadata: '1.000033' version: '0.004' name: '@DROLSKY/CheckSelfDependency' version: '0.011' - class: Dist::Zilla::Plugin::CheckPrereqsIndexed name: '@DROLSKY/CheckPrereqsIndexed' version: '0.020' - class: Dist::Zilla::Plugin::DROLSKY::Git::CheckFor::CorrectBranch config: Dist::Zilla::Role::Git::Repo: git_version: 2.14.1 repo_root: . name: '@DROLSKY/DROLSKY::Git::CheckFor::CorrectBranch' version: '0.85' - class: Dist::Zilla::Plugin::EnsureChangesHasContent name: '@DROLSKY/EnsureChangesHasContent' version: '0.02' - class: Dist::Zilla::Plugin::Git::CheckFor::MergeConflicts config: Dist::Zilla::Role::Git::Repo: git_version: 2.14.1 repo_root: . name: '@DROLSKY/Git::CheckFor::MergeConflicts' version: '0.014' - class: Dist::Zilla::Plugin::DROLSKY::TidyAll name: '@DROLSKY/DROLSKY::TidyAll' version: '0.85' - class: Dist::Zilla::Plugin::Git::Check config: Dist::Zilla::Plugin::Git::Check: untracked_files: die Dist::Zilla::Role::Git::DirtyFiles: allow_dirty: - CONTRIBUTING.md - Changes - LICENSE - Makefile.PL - README.md - cpanfile - tidyall.ini allow_dirty_match: [] changelog: Changes Dist::Zilla::Role::Git::Repo: git_version: 2.14.1 repo_root: . name: '@DROLSKY/Git::Check' version: '2.042' - class: Dist::Zilla::Plugin::Git::Commit config: Dist::Zilla::Plugin::Git::Commit: add_files_in: [] commit_msg: v%v%n%n%c Dist::Zilla::Role::Git::DirtyFiles: allow_dirty: - CONTRIBUTING.md - Changes - LICENSE - Makefile.PL - README.md - cpanfile - tidyall.ini allow_dirty_match: [] changelog: Changes Dist::Zilla::Role::Git::Repo: git_version: 2.14.1 repo_root: . Dist::Zilla::Role::Git::StringFormatter: time_zone: local name: '@DROLSKY/Commit generated files' version: '2.042' - class: Dist::Zilla::Plugin::Git::Tag config: Dist::Zilla::Plugin::Git::Tag: branch: ~ changelog: Changes signed: 0 tag: v2.67 tag_format: v%v tag_message: v%v Dist::Zilla::Role::Git::Repo: git_version: 2.14.1 repo_root: . Dist::Zilla::Role::Git::StringFormatter: time_zone: local name: '@DROLSKY/Git::Tag' version: '2.042' - class: Dist::Zilla::Plugin::Git::Push config: Dist::Zilla::Plugin::Git::Push: push_to: - origin remotes_must_exist: 1 Dist::Zilla::Role::Git::Repo: git_version: 2.14.1 repo_root: . name: '@DROLSKY/Git::Push' version: '2.042' - class: Dist::Zilla::Plugin::BumpVersionAfterRelease config: Dist::Zilla::Plugin::BumpVersionAfterRelease: finders: - ':ExecFiles' - ':InstallModules' global: 0 munge_makefile_pl: 1 name: '@DROLSKY/BumpVersionAfterRelease' version: '0.015' - class: Dist::Zilla::Plugin::Git::Commit config: Dist::Zilla::Plugin::Git::Commit: add_files_in: [] commit_msg: 'Bump version after release' Dist::Zilla::Role::Git::DirtyFiles: allow_dirty: - Changes - dist.ini allow_dirty_match: - (?^:.+) changelog: Changes Dist::Zilla::Role::Git::Repo: git_version: 2.14.1 repo_root: . Dist::Zilla::Role::Git::StringFormatter: time_zone: local name: '@DROLSKY/Commit version bump' version: '2.042' - class: Dist::Zilla::Plugin::Git::Push config: Dist::Zilla::Plugin::Git::Push: push_to: - origin remotes_must_exist: 1 Dist::Zilla::Role::Git::Repo: git_version: 2.14.1 repo_root: . name: '@DROLSKY/Push version bump' version: '2.042' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: develop type: requires name: DevelopRequires version: '6.010' - class: Dist::Zilla::Plugin::FileFinder::ByName name: MostLibs version: '6.010' - class: Dist::Zilla::Plugin::Test::Version name: Test::Version version: '1.09' - class: Dist::Zilla::Plugin::Conflicts name: Conflicts version: '0.19' - class: Dist::Zilla::Plugin::FinderCode name: ':InstallModules' version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':IncModules' version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':TestFiles' version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':ExtraTestFiles' version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':ExecFiles' version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':PerlExecFiles' version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':ShareFiles' version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':MainModule' version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':AllFiles' version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':NoFiles' version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: '@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM' version: '6.010' zilla: class: Dist::Zilla::Dist::Builder config: is_trial: '0' version: '6.010' x_authority: cpan:DROLSKY x_breaks: Log::Dispatch::File::Stamped: '<= 0.17' x_contributors: - 'Anirvan Chatterjee ' - 'Carsten Grohmann ' - 'Doug Bell ' - 'Graham Ollis ' - 'Gregory Oschwald ' - 'Johann Rolschewski ' - 'Jonathan Swartz ' - 'Karen Etheridge ' - 'Kerin Millar ' - 'Kivanc Yazan ' - 'Konrad Bucheli ' - 'Michael Schout ' - 'Olaf Alders ' - 'Olivier MenguĆ© ' - 'Rohan Carly ' - 'Ross Attrill ' - 'Salvador FandiƱo ' - 'Slaven Rezic ' - 'Steve Bertrand ' - 'Whitney Jackson ' x_serialization_backend: 'YAML::Tiny version 1.70' Log-Dispatch-2.67/weaver.ini0000644000175000017500000000024613162076057015571 0ustar autarchautarch[@CorePrep] [Name] [Version] [Region / prelude] [Generic / SYNOPSIS] [Generic / DESCRIPTION] [Leftovers] [Region / postlude] [Authors] [Contributors] [Legal] Log-Dispatch-2.67/perltidyrc0000644000175000017500000000045513162076057015705 0ustar autarchautarch-l=78 -i=4 -ci=4 -se -b -bar -boc -vt=0 -vtc=0 -cti=0 -pt=1 -bt=1 -sbt=1 -bbt=1 -nolq -npro -nsfs --blank-lines-before-packages=0 --opening-hash-brace-right --no-outdent-long-comments --iterations=2 -wbb="% + - * / x != == >= <= =~ !~ < > | & >= < = **= += *= &= <<= &&= -= /= |= >>= ||= .= %= ^= x=" Log-Dispatch-2.67/appveyor.yml0000644000175000017500000000103413162076057016163 0ustar autarchautarchcache: - C:\projects\sources install: - if not exist "C:\projects\sources" mkdir "C:\projects\sources" - cd C:\projects\sources - ps: Start-FileDownload http://strawberryperl.com/download/5.20.1.1/strawberry-perl-5.20.1.1-64bit.msi - msiexec /i "C:\projects\sources\strawberry-perl-5.20.1.1-64bit.msi" /qn INSTALLDIR="C:\projects\perl" - set PATH=C:\projects\perl\perl\bin;C:\projects\perl\perl\site\bin;C:\projects\perl\c\bin;%PATH% - cd C:\projects\Log-Dispatch - cpanm --installdeps . build_script: - prove -lr t/ Log-Dispatch-2.67/t/0000775000175000017500000000000013162076057014042 5ustar autarchautarchLog-Dispatch-2.67/t/file-locked.t0000644000175000017500000000623513162076057016411 0ustar autarchautarchuse strict; use warnings; use Test::More; use File::Spec; use File::Temp qw( tempdir ); use Log::Dispatch; use Log::Dispatch::File::Locked; use POSIX qw( :sys_wait_h ); use Try::Tiny; my $ChildCount = 10; for my $close_after_write ( 0, 1 ) { my @v = _run_children($close_after_write); subtest( "close_after_write = $close_after_write", sub { _test_file_locked(@v); } ); } done_testing(); sub _run_children { my $close_after_write = shift; my $dir = tempdir( CLEANUP => 1 ); my $file = File::Spec->catfile( $dir, 'lock-test.log' ); my $logger = _dispatch_for_file( $close_after_write, $file ); my %pids; for ( 1 .. $ChildCount ) { if ( my $pid = fork ) { $pids{$pid} = 1; } else { _write_to_file( $close_after_write, $file ); exit 0; } } my %exit_status; try { local $SIG{ALRM} = sub { die 'Waited 10 seconds for children to exit' }; alarm 10; while ( keys %pids ) { my $pid = waitpid( -1, WNOHANG ); if ( delete $pids{$pid} ) { $exit_status{$pid} = $?; } } }; return ( $file, $@, \%exit_status ); } sub _write_to_file { my $close_after_write = shift; my $file = shift; my $dispatch = _dispatch_for_file( $close_after_write, $file ); # The sleep makes a deadlock much more likely if the locking logic is not # working correctly. Without it each child process runs so quickly that # they are unlikely to step on each other. $dispatch->info(1); sleep 1; $dispatch->info(2); $dispatch->info(3); return; } sub _dispatch_for_file { my $close_after_write = shift; my $file = shift; return Log::Dispatch->new( outputs => [ [ 'File::Locked', filename => $file, mode => 'append', close_after_write => $close_after_write, min_level => 'debug', newline => 1, ] ], ); } sub _test_file_locked { my $file = shift; my $exc = shift; my $exits = shift; is( $exc, q{}, 'no exception forking children and writing to file' ); is( keys %{$exits}, $ChildCount, "$ChildCount children exited", ); for my $pid ( keys %{$exits} ) { is( $exits->{$pid}, 0, "$pid exited with 0" ); } _test_file_content($file); } sub _test_file_content { my $file = shift; open my $fh, '<', $file or die "Cannot read $file: $!"; my @lines; while ( defined( my $line = <$fh> ) ) { chomp $line; push @lines, $line; } close $fh or die $!; return if is_deeply( [ sort @lines ], [ (1) x $ChildCount, (2) x $ChildCount, (3) x $ChildCount ], 'file contains expected content' ); open my $diag_fh, '<', $file or die $!; diag( do { local $/ = undef; <$diag_fh> } ); close $diag_fh or die $!; } Log-Dispatch-2.67/t/sendmail0000755000175000017500000000002513162076057015557 0ustar autarchautarch#!/bin/bash exit 0; Log-Dispatch-2.67/t/syslog-lock-without-preloaded-threads.t0000644000175000017500000000201213162076057023554 0ustar autarchautarchuse strict; use warnings; use Test::More 0.88; use Config; BEGIN { plan skip_all => 'This test only runs on threaded perls' unless $Config{usethreads}; } use Test::Needs { 'Sys::Syslog' => '0.28', }; use Log::Dispatch; use Log::Dispatch::Syslog; ## no critic (TestingAndDebugging::ProhibitNoWarnings) no warnings 'redefine', 'once'; my @sock; local *Sys::Syslog::setlogsock = sub { @sock = @_ }; local *Sys::Syslog::openlog = sub { return 1 }; local *Sys::Syslog::closelog = sub { return 1 }; my @log; local *Sys::Syslog::syslog = sub { push @log, [@_] }; SKIP: { @log = (); my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::Syslog->new( name => 'syslog', min_level => 'debug', lock => 1, ) ); $dispatch->info('Foo thread'); is_deeply( \@log, [ [ 'INFO', 'Foo thread' ] ], 'passed message to syslog (with thread lock, but no preloaded threads module)' ); } done_testing(); Log-Dispatch-2.67/t/00-report-prereqs.t0000644000175000017500000001342613162076057017442 0ustar autarchautarch#!perl use strict; use warnings; # This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.027 use Test::More tests => 1; use ExtUtils::MakeMaker; use File::Spec; # from $version::LAX my $lax_version_re = qr/(?: undef | (?: (?:[0-9]+) (?: \. | (?:\.[0-9]+) (?:_[0-9]+)? )? | (?:\.[0-9]+) (?:_[0-9]+)? ) | (?: v (?:[0-9]+) (?: (?:\.[0-9]+)+ (?:_[0-9]+)? )? | (?:[0-9]+)? (?:\.[0-9]+){2,} (?:_[0-9]+)? ) )/x; # hide optional CPAN::Meta modules from prereq scanner # and check if they are available my $cpan_meta = "CPAN::Meta"; my $cpan_meta_pre = "CPAN::Meta::Prereqs"; my $HAS_CPAN_META = eval "require $cpan_meta; $cpan_meta->VERSION('2.120900')" && eval "require $cpan_meta_pre"; ## no critic # Verify requirements? my $DO_VERIFY_PREREQS = 1; sub _max { my $max = shift; $max = ( $_ > $max ) ? $_ : $max for @_; return $max; } sub _merge_prereqs { my ($collector, $prereqs) = @_; # CPAN::Meta::Prereqs object if (ref $collector eq $cpan_meta_pre) { return $collector->with_merged_prereqs( CPAN::Meta::Prereqs->new( $prereqs ) ); } # Raw hashrefs for my $phase ( keys %$prereqs ) { for my $type ( keys %{ $prereqs->{$phase} } ) { for my $module ( keys %{ $prereqs->{$phase}{$type} } ) { $collector->{$phase}{$type}{$module} = $prereqs->{$phase}{$type}{$module}; } } } return $collector; } my @include = qw( ); my @exclude = qw( ); # Add static prereqs to the included modules list my $static_prereqs = do './t/00-report-prereqs.dd'; # Merge all prereqs (either with ::Prereqs or a hashref) my $full_prereqs = _merge_prereqs( ( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ), $static_prereqs ); # Add dynamic prereqs to the included modules list (if we can) my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml'; my $cpan_meta_error; if ( $source && $HAS_CPAN_META && (my $meta = eval { CPAN::Meta->load_file($source) } ) ) { $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs); } else { $cpan_meta_error = $@; # capture error from CPAN::Meta->load_file($source) $source = 'static metadata'; } my @full_reports; my @dep_errors; my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs; # Add static includes into a fake section for my $mod (@include) { $req_hash->{other}{modules}{$mod} = 0; } for my $phase ( qw(configure build test runtime develop other) ) { next unless $req_hash->{$phase}; next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING}); for my $type ( qw(requires recommends suggests conflicts modules) ) { next unless $req_hash->{$phase}{$type}; my $title = ucfirst($phase).' '.ucfirst($type); my @reports = [qw/Module Want Have/]; for my $mod ( sort keys %{ $req_hash->{$phase}{$type} } ) { next if $mod eq 'perl'; next if grep { $_ eq $mod } @exclude; my $file = $mod; $file =~ s{::}{/}g; $file .= ".pm"; my ($prefix) = grep { -e File::Spec->catfile($_, $file) } @INC; my $want = $req_hash->{$phase}{$type}{$mod}; $want = "undef" unless defined $want; $want = "any" if !$want && $want == 0; my $req_string = $want eq 'any' ? 'any version required' : "version '$want' required"; if ($prefix) { my $have = MM->parse_version( File::Spec->catfile($prefix, $file) ); $have = "undef" unless defined $have; push @reports, [$mod, $want, $have]; if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META && $type eq 'requires' ) { if ( $have !~ /\A$lax_version_re\z/ ) { push @dep_errors, "$mod version '$have' cannot be parsed ($req_string)"; } elsif ( ! $full_prereqs->requirements_for( $phase, $type )->accepts_module( $mod => $have ) ) { push @dep_errors, "$mod version '$have' is not in required range '$want'"; } } } else { push @reports, [$mod, $want, "missing"]; if ( $DO_VERIFY_PREREQS && $type eq 'requires' ) { push @dep_errors, "$mod is not installed ($req_string)"; } } } if ( @reports ) { push @full_reports, "=== $title ===\n\n"; my $ml = _max( map { length $_->[0] } @reports ); my $wl = _max( map { length $_->[1] } @reports ); my $hl = _max( map { length $_->[2] } @reports ); if ($type eq 'modules') { splice @reports, 1, 0, ["-" x $ml, "", "-" x $hl]; push @full_reports, map { sprintf(" %*s %*s\n", -$ml, $_->[0], $hl, $_->[2]) } @reports; } else { splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl]; push @full_reports, map { sprintf(" %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2]) } @reports; } push @full_reports, "\n"; } } } if ( @full_reports ) { diag "\nVersions for all modules listed in $source (including optional ones):\n\n", @full_reports; } if ( $cpan_meta_error || @dep_errors ) { diag "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n"; } if ( $cpan_meta_error ) { my ($orig_source) = grep { -f } 'MYMETA.json', 'MYMETA.yml'; diag "\nCPAN::Meta->load_file('$orig_source') failed with: $cpan_meta_error\n"; } if ( @dep_errors ) { diag join("\n", "\nThe following REQUIRED prerequisites were not satisfied:\n", @dep_errors, "\n" ); } pass; # vim: ts=4 sts=4 sw=4 et: Log-Dispatch-2.67/t/00-compile.t0000644000175000017500000000160013162076057016067 0ustar autarchautarchuse strict; use warnings; use Test::More; my %deps = ( ApacheLog => 'Apache::Log', Code => q{}, File => q{}, 'File::Locked' => q{}, Handle => q{}, Null => q{}, Screen => q{}, Syslog => 'Sys::Syslog 0.28', 'Email::MailSend' => 'Mail::Send', 'Email::MIMELite' => 'MIME::Lite', 'Email::MailSendmail' => 'Mail::Sendmail', 'Email::MailSender' => 'Mail::Sender', ); use_ok('Log::Dispatch'); for my $subclass ( sort keys %deps ) { my $module = "Log::Dispatch::$subclass"; if ( !$deps{$subclass} || ( eval "use $deps{$subclass}; 1" && !$@ ) ) { use_ok($module); } else { SKIP: { skip "Cannot load $module without $deps{$subclass}", 1; } } } done_testing(); Log-Dispatch-2.67/t/close-after-write.t0000644000175000017500000000462513162076057017570 0ustar autarchautarchuse strict; use warnings FATAL => 'all'; use Test::More 0.88; use File::Spec; use File::Temp qw( tempdir ); use Log::Dispatch; my $dir = tempdir( CLEANUP => 1 ); # test that the same handle is returned if close-on-write is not set... { my $logger = Log::Dispatch->new( outputs => [ [ 'File', min_level => 'debug', newline => 1, name => 'no_caw', filename => File::Spec->catfile( $dir, 'no_caw.log' ), close_after_write => 0, ], [ 'File', min_level => 'debug', newline => 1, name => 'caw', filename => File::Spec->catfile( $dir, 'caw.log' ), close_after_write => 1, ], ], ); ok( $logger->output('no_caw')->{fh}, 'no_caw output has created a fh before first write' ); ok( !$logger->output('caw')->{fh}, 'caw output has not created a fh before first write' ); $logger->log( level => 'info', message => 'first message' ); is( _slurp( $logger->output('no_caw')->{filename} ), "first message\n", 'first line from no_caw output' ); is( _slurp( $logger->output('caw')->{filename} ), "first message\n", 'first line from caw output' ); my %handle = ( no_caw => $logger->output('no_caw')->{fh}, caw => $logger->output('caw')->{fh}, ); $logger->log( level => 'info', message => 'second message' ); is( _slurp( $logger->output('no_caw')->{filename} ), "first message\nsecond message\n", 'full content from no_caw output' ); is( _slurp( $logger->output('caw')->{filename} ), "first message\nsecond message\n", 'full content from caw output' ); # check the filehandles again... is( $logger->output('no_caw')->{fh}, $handle{no_caw}, 'handle has not changed when not using CAW' ); is( $logger->output('caw')->{fh}, undef, 'handle is deleted when using CAW' ); } done_testing(); sub _slurp { open my $fh, '<', $_[0] or die "Cannot read $_[0]: $!"; my $s = do { local $/ = undef; <$fh>; }; close $fh or die $!; return $s; } Log-Dispatch-2.67/t/binmode.t0000644000175000017500000000252613162076057015647 0ustar autarchautarchuse strict; use warnings; use File::Spec; use File::Temp qw( tempdir ); use Test::More 0.88; use Log::Dispatch; use Log::Dispatch::File; ## no critic (ControlStructures::ProhibitNegativeExpressionsInUnlessAndUntilConditions) plan skip_all => "Cannot test utf8 files with this version of Perl ($])" unless $] >= 5.008; my $dir = tempdir( CLEANUP => 1 ); my %params = ( name => 'file', min_level => 'debug', filename => File::Spec->catfile( $dir, 'logfile_X.txt' ), ); my @tests = ( { params => { %params, 'binmode' => ':utf8' }, message => "foo bar\x{20AC}", expected_message => "foo bar\xe2\x82\xac", }, ); my $count = 0; for my $t (@tests) { my $dispatcher = Log::Dispatch->new(); ok( $dispatcher, 'got a logger object' ); $t->{params}{filename} =~ s/X\.txt$/$count++ . '.txt'/e; my $file = $t->{params}{filename}; my $logger = Log::Dispatch::File->new( %{ $t->{params} } ); ok( $logger, 'got a file output object' ); $dispatcher->add($logger); $dispatcher->log( level => 'info', message => $t->{message} ); ok( -e $file, "$file exists" ); open my $fh, '<', $file or die $!; my $line = do { local $/ = undef; <$fh> }; close $fh or die $!; is( $line, $t->{expected_message}, 'output contains UTF-8 bytes' ); } done_testing(); Log-Dispatch-2.67/t/short-syntax.t0000644000175000017500000000354213162076057016714 0ustar autarchautarchuse strict; use warnings; use Test::Fatal; use Test::More; use lib qw( t/lib ); use File::Temp qw( tempdir ); use Log::Dispatch::TestUtil qw( cmp_deeply ); use Log::Dispatch; my $tempdir = tempdir( CLEANUP => 1 ); { my $emerg_log = File::Spec->catdir( $tempdir, 'emerg.log' ); # Short syntax my $dispatch0 = Log::Dispatch->new( outputs => [ [ 'File', name => 'file', min_level => 'emerg', filename => $emerg_log, ], [ '+Log::Dispatch::Null', name => 'null', min_level => 'debug', ] ] ); # Short syntax alternate (2.23) my $dispatch1 = Log::Dispatch->new( outputs => [ 'File' => { name => 'file', min_level => 'emerg', filename => $emerg_log }, '+Log::Dispatch::Null' => { name => 'null', min_level => 'debug' } ] ); # Long syntax my $dispatch2 = Log::Dispatch->new; $dispatch2->add( Log::Dispatch::File->new( name => 'file', min_level => 'emerg', filename => $emerg_log ) ); $dispatch2->add( Log::Dispatch::Null->new( name => 'null', min_level => 'debug' ) ); cmp_deeply( $dispatch0, $dispatch2, 'created equivalent dispatchers - 0' ); cmp_deeply( $dispatch1, $dispatch2, 'created equivalent dispatchers - 1' ); } { like( exception { Log::Dispatch->new( outputs => ['File'] ) }, qr/expected arrayref/, 'got error for expected inner arrayref' ); } { like( exception { Log::Dispatch->new( outputs => 'File' ) }, qr/Validation failed for type named ArrayRef/, 'got error for expected outer arrayref' ); } done_testing(); Log-Dispatch-2.67/t/lazy-open.t0000644000175000017500000000274013162076057016146 0ustar autarchautarchuse strict; use warnings FATAL => 'all'; use Test::More 0.88; use File::Spec; use File::Temp qw( tempdir ); use Log::Dispatch; my $dir = tempdir( CLEANUP => 1 ); { my $logger = Log::Dispatch->new( outputs => [ [ 'File', min_level => 'debug', newline => 1, name => 'lazy_open', filename => File::Spec->catfile( $dir, 'lazy_open.log' ), lazy_open => 1, ], ], ); ok( !$logger->output('lazy_open')->{fh}, 'lazy_open output has not created a fh before first write' ); $logger->log( level => 'info', message => 'first message' ); is( _slurp( $logger->output('lazy_open')->{filename} ), "first message\n", 'first line from lazy_open output' ); ok( $logger->output('lazy_open')->{fh}, 'lazy_open output has still an open fh' ); $logger->log( level => 'info', message => 'second message' ); is( _slurp( $logger->output('lazy_open')->{filename} ), "first message\nsecond message\n", 'full content from caw output' ); ok( $logger->output('lazy_open')->{fh}, 'lazy_open output has still an open fh' ); } done_testing(); sub _slurp { open my $fh, '<', $_[0] or die "Cannot read $_[0]: $!"; my $s = do { local $/ = undef; <$fh>; }; close $fh or die $!; return $s; } Log-Dispatch-2.67/t/00-report-prereqs.dd0000644000175000017500000001201613162076057017560 0ustar autarchautarchdo { my $x = { 'configure' => { 'requires' => { 'Dist::CheckConflicts' => '0.02', 'ExtUtils::MakeMaker' => '0' }, 'suggests' => { 'JSON::PP' => '2.27300' } }, 'develop' => { 'requires' => { 'Code::TidyAll' => '0.56', 'Code::TidyAll::Plugin::SortLines::Naturally' => '0.000003', 'Code::TidyAll::Plugin::Test::Vars' => '0.02', 'Cwd' => '0', 'MIME::Lite' => '0', 'Mail::Send' => '0', 'Mail::Sender' => '0', 'Mail::Sendmail' => '0', 'Parallel::ForkManager' => '1.19', 'Perl::Critic' => '1.126', 'Perl::Tidy' => '20160302', 'Pod::Coverage::TrustPod' => '0', 'Pod::Wordlist' => '0', 'Test::CPAN::Changes' => '0.19', 'Test::CPAN::Meta::JSON' => '0.16', 'Test::Code::TidyAll' => '0.50', 'Test::DependentModules' => '0.22', 'Test::EOL' => '0', 'Test::Mojibake' => '0', 'Test::More' => '0.96', 'Test::Needs' => '0', 'Test::NoTabs' => '0', 'Test::Pod' => '1.41', 'Test::Pod::Coverage' => '1.08', 'Test::Portability::Files' => '0', 'Test::Spelling' => '0.12', 'Test::Vars' => '0.009', 'Test::Version' => '2.05' } }, 'runtime' => { 'requires' => { 'Carp' => '0', 'Devel::GlobalDestruction' => '0', 'Dist::CheckConflicts' => '0.02', 'Encode' => '0', 'Exporter' => '0', 'Fcntl' => '0', 'IO::Handle' => '0', 'Module::Runtime' => '0', 'Params::ValidationCompiler' => '0', 'Scalar::Util' => '0', 'Specio' => '0.32', 'Specio::Declare' => '0', 'Specio::Exporter' => '0', 'Specio::Library::Builtins' => '0', 'Specio::Library::Numeric' => '0', 'Specio::Library::String' => '0', 'Sys::Syslog' => '0.28', 'Try::Tiny' => '0', 'base' => '0', 'namespace::autoclean' => '0', 'parent' => '0', 'perl' => '5.006', 'strict' => '0', 'warnings' => '0' } }, 'test' => { 'recommends' => { 'CPAN::Meta' => '2.120900' }, 'requires' => { 'Data::Dumper' => '0', 'ExtUtils::MakeMaker' => '0', 'File::Spec' => '0', 'File::Temp' => '0', 'FindBin' => '0', 'Getopt::Long' => '0', 'IO::File' => '0', 'IPC::Run3' => '0', 'POSIX' => '0', 'PerlIO' => '0', 'Test::Fatal' => '0', 'Test::More' => '0.96', 'Test::Needs' => '0', 'lib' => '0', 'utf8' => '0' } } }; $x; }Log-Dispatch-2.67/t/email-exit.t0000644000175000017500000000045413162076057016266 0ustar autarchautarchuse strict; use warnings; use Test::More; unless ( -d '.git' ) { plan skip_all => 'This test only runs for the maintainer'; exit; } ## no critic (InputOutput::RequireCheckedSyscalls) system( $^X, 't/email-exit-helper.pl' ); is( $? >> 8, 5, 'exit code of helper was 5' ); done_testing(); Log-Dispatch-2.67/t/screen-helper.pl0000644000175000017500000000111713162076057017131 0ustar autarchautarchuse strict; use warnings; use Getopt::Long; use Log::Dispatch; use Log::Dispatch::Screen; my ( $stderr, $utf8 ); GetOptions( 'stderr' => \$stderr, 'utf8' => \$utf8, ); my $dispatch = Log::Dispatch->new( outputs => [ [ Screen => ( name => 'screen', min_level => 'debug', newline => 1, stderr => $stderr, utf8 => $utf8, ), ] ], ); my $message = 'test message'; $message .= " - \x{1f60}" if $utf8; $dispatch->warning($message); exit 0; Log-Dispatch-2.67/t/lib/0000775000175000017500000000000013162076057014610 5ustar autarchautarchLog-Dispatch-2.67/t/lib/Log/0000775000175000017500000000000013162076057015331 5ustar autarchautarchLog-Dispatch-2.67/t/lib/Log/Dispatch/0000775000175000017500000000000013162076057017070 5ustar autarchautarchLog-Dispatch-2.67/t/lib/Log/Dispatch/TestUtil.pm0000644000175000017500000000132413162076057021201 0ustar autarchautarchpackage Log::Dispatch::TestUtil; use strict; use warnings; use Data::Dumper; use Exporter qw( import ); our @EXPORT_OK = qw( cmp_deeply dump_one_line ); sub cmp_deeply { my ( $ref1, $ref2, $name ) = @_; my $tb = Test::Builder->new(); $tb->is_eq( dump_one_line($ref1), dump_one_line($ref2), $name ); } sub dump_one_line { my ($value) = @_; return Data::Dumper->new( [$value] )->Indent(0)->Sortkeys(1) ->Quotekeys(0)->Terse(1)->Dump(); } 1; # ABSTRACT: Utilities used internally by Log::Dispatch for testing __END__ =head1 METHODS =over =item cmp_deeply A cheap version of Test::Deep::cmp_deeply. =item dump_one_line Dump a value to a single line using Data::Dumper. =cut Log-Dispatch-2.67/t/screen.t0000644000175000017500000000534513162076057015513 0ustar autarchautarchuse strict; use warnings; use utf8; use lib 't/lib'; use Test::More 0.88; use Test::Needs { 'IPC::Run3' => 0, }; use FindBin qw( $Bin ); use IPC::Run3 qw( run3 ); use Log::Dispatch::Screen; use Log::Dispatch; use PerlIO; { my @orig_layers = PerlIO::get_layers(STDOUT); my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::Screen->new( name => 'screen', min_level => 'debug', stderr => 0, newline => 1, utf8 => 1, ) ); $dispatch->log( level => 'crit', message => '# testing' ); is_deeply( [ PerlIO::get_layers(STDOUT) ], \@orig_layers, 'STDOUT layers are not changed when Screen utf8 param is true' ); } { my @tests = ( [ { stderr => 0, utf8 => 0, }, { stdout => 'test message', stderr => q{}, }, ], [ { stderr => 1, utf8 => 0, }, { stdout => q{}, stderr => 'test message', }, ], [ { stderr => 0, utf8 => 1, }, { stdout => "test message - \x{1f60}", stderr => q{}, }, ], [ { stderr => 1, utf8 => 1, }, { stdout => q{}, stderr => "test message - \x{1f60}", }, ], ); for my $test (@tests) { my ( $p, $expect ) = @{$test}; subtest( "stderr = $p->{stderr}, utf8 = $p->{utf8}", sub { my ( $stdout, $stderr ) = _run_helper( %{$p} ); is( $stdout, $expect->{stdout}, 'got expected stdout from Screen output' ); is( $stderr, $expect->{stderr}, 'got expected stderr from Screen output' ); } ); } } sub _run_helper { my %p = @_; my @args; push @args, '--stderr' if $p{stderr}; push @args, '--utf8' if $p{utf8}; my ( $stdout, $stderr ); run3( [ $^X, "$Bin/screen-helper.pl", @args ], \undef, \$stdout, \$stderr, { binmode_stdout => ':encoding(UTF-8)', binmode_stderr => ':encoding(UTF-8)', }, ); # We want to remove all line endings on any platform. s/[\r\n]+$// for grep {defined} $stdout, $stderr; return ( $stdout, $stderr ); } done_testing(); Log-Dispatch-2.67/t/syslog.t0000644000175000017500000000337013162076057015550 0ustar autarchautarchuse strict; use warnings; use Test::More 0.88; use Test::Needs { 'Sys::Syslog' => '0.28', }; use Log::Dispatch; use Log::Dispatch::Syslog; use Try::Tiny; ## no critic (TestingAndDebugging::ProhibitNoWarnings) no warnings 'redefine', 'once'; my @sock; local *Sys::Syslog::setlogsock = sub { @sock = @_ }; local *Sys::Syslog::openlog = sub { return 1 }; local *Sys::Syslog::closelog = sub { return 1 }; my @log; local *Sys::Syslog::syslog = sub { push @log, [@_] }; { @log = (); my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::Syslog->new( name => 'syslog', min_level => 'debug', ) ); $dispatch->info('Foo'); ok( !@sock, 'no call to setlogsock unless socket is set explicitly' ); is_deeply( \@log, [ [ 'INFO', 'Foo' ] ], 'passed message to syslog' ); } { @log = (); my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::Syslog->new( name => 'syslog', min_level => 'debug', socket => { type => 'foo' }, ) ); $dispatch->info('Foo'); is_deeply( \@sock, [ { type => 'foo' } ], 'call to setlogsock is made when logging a message if socket was passed to LD::Syslog constructor' ); } { @log = (); my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::Syslog->new( name => 'syslog', min_level => 'debug', socket => { type => 'foo' }, ) ); local $@ = 'foo!'; $dispatch->debug('Foo'); like( $@, qr/^foo!/, '$@ is not changed when Log::Dispatch::Syslog does logging' ); } done_testing(); Log-Dispatch-2.67/t/email-exit-helper.pl0000755000175000017500000000061413162076057017714 0ustar autarchautarchuse strict; use warnings; use lib './lib', '../lib'; use Log::Dispatch::Email::MailSend; Mail::Mailer->import( sendmail => 't/sendmail' ); my $email = Log::Dispatch::Email::MailSend->new( name => 'email', min_level => 'emerg', to => 'foo@example.com', subject => 'Log this', ); $email->log( message => 'Something bad is happening', level => 'emerg' ); exit 5; Log-Dispatch-2.67/t/syslog-threads.t0000644000175000017500000000201313162076057017171 0ustar autarchautarchuse strict; use warnings; use Test::More 0.88; use Config; BEGIN { plan skip_all => 'This test only runs on threaded perls' unless $Config{usethreads}; } use Test::Needs { 'Sys::Syslog' => '0.28', }; use threads; use threads::shared; use Log::Dispatch; use Log::Dispatch::Syslog; ## no critic (TestingAndDebugging::ProhibitNoWarnings) no warnings 'redefine', 'once'; my @sock; local *Sys::Syslog::setlogsock = sub { @sock = @_ }; local *Sys::Syslog::openlog = sub { return 1 }; local *Sys::Syslog::closelog = sub { return 1 }; my @log; local *Sys::Syslog::syslog = sub { push @log, [@_] }; SKIP: { @log = (); my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::Syslog->new( name => 'syslog', min_level => 'debug', lock => 1, ) ); $dispatch->info('Foo thread'); is_deeply( \@log, [ [ 'INFO', 'Foo thread' ] ], 'passed message to syslog (with thread lock)' ); } done_testing(); Log-Dispatch-2.67/t/basic.t0000644000175000017500000011021213162076057015303 0ustar autarchautarch## no critic (Modules::ProhibitExcessMainComplexity) use strict; use warnings; use Test::More 0.96; use Test::Fatal; use File::Spec; use File::Temp qw( tempdir ); use Module::Runtime qw( use_module ); use Try::Tiny; use Log::Dispatch; my %tests; BEGIN { local $@ = undef; foreach (qw( MailSend MIMELite MailSendmail MailSender )) { ## no critic (BuiltinFunctions::ProhibitStringyEval, ErrorHandling::RequireCheckingReturnValueOfEval) eval "use Log::Dispatch::Email::$_"; $tests{$_} = !$@; $tests{$_} = 0 if $ENV{LD_NO_MAIL}; } } my %TestConfig; if ( my $email_address = $ENV{LOG_DISPATCH_TEST_EMAIL} ) { %TestConfig = ( email_address => $email_address ); } my @syswrite_strs; BEGIN { if ( $] >= 5.016 ) { my $syswrite = \&CORE::syswrite; *CORE::GLOBAL::syswrite = sub { my ( $fh, $str, @other ) = @_; push @syswrite_strs, $_[1]; return $syswrite->( $fh, $str, @other ); }; } } use Log::Dispatch::File; use Log::Dispatch::Handle; use Log::Dispatch::Null; use Log::Dispatch::Screen; use IO::File; my $tempdir = tempdir( CLEANUP => 1 ); subtest( 'Test Log::Dispatch::File', sub { my $dispatch = Log::Dispatch->new; ok( $dispatch, 'created Log::Dispatch object' ); my $emerg_log = File::Spec->catdir( $tempdir, 'emerg.log' ); $dispatch->add( Log::Dispatch::File->new( name => 'file1', min_level => 'emerg', filename => $emerg_log ) ); $dispatch->log( level => 'info', message => "info level 1\n" ); $dispatch->log( level => 'emerg', message => "emerg level 1\n" ); my $debug_log = File::Spec->catdir( $tempdir, 'debug.log' ); $dispatch->add( Log::Dispatch::File->new( name => 'file2', min_level => 'debug', syswrite => 1, filename => $debug_log ) ); my %outputs = map { $_->name() => ref $_ } $dispatch->outputs(); is_deeply( \%outputs, { file1 => 'Log::Dispatch::File', file2 => 'Log::Dispatch::File', }, '->outputs() method returns all output objects' ); $dispatch->log( level => 'info', message => "info level 2\n" ); $dispatch->log( level => 'emerg', message => "emerg level 2\n" ); # This'll close them filehandles! undef $dispatch; ## no critic (InputOutput::RequireBriefOpen) open my $emerg_fh, '<', $emerg_log or die "Can't read $emerg_log: $!"; open my $debug_fh, '<', $debug_log or die "Can't read $debug_log: $!"; my @log = <$emerg_fh>; is( $log[0], "emerg level 1\n", q{First line in log file set to level 'emerg' is 'emerg level 1'} ); is( $log[1], "emerg level 2\n", q{Second line in log file set to level 'emerg' is 'emerg level 2'} ); @log = <$debug_fh>; is( $log[0], "info level 2\n", q{First line in log file set to level 'debug' is 'info level 2'} ); is( $log[1], "emerg level 2\n", q{Second line in log file set to level 'debug' is 'emerg level 2'} ); close $emerg_fh or die $!; close $debug_fh or die $!; SKIP: { ## no critic (ControlStructures::ProhibitNegativeExpressionsInUnlessAndUntilConditions) skip 'This test requires Perl 5.16+', 1 unless $] >= 5.016; is_deeply( \@syswrite_strs, [ "info level 2\n", "emerg level 2\n", ], 'second LD object used syswrite', ); } } ); subtest( 'max_level', sub { my $max_log = File::Spec->catfile( $tempdir, 'max.log' ); my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::File->new( name => 'file1', min_level => 'debug', max_level => 'crit', filename => $max_log ) ); $dispatch->log( level => 'emerg', message => "emergency\n" ); $dispatch->log( level => 'crit', message => "critical\n" ); undef $dispatch; # close file handles open my $fh, '<', $max_log or die "Can't read $max_log: $!"; my @log = <$fh>; close $fh or die $!; is( $log[0], "critical\n", q{First line in log file with a max level of 'crit' is 'critical'} ); } ); subtest( 'Handle output', sub { my $handle_log = File::Spec->catfile( $tempdir, 'handle.log' ); my $fh = IO::File->new( $handle_log, 'w' ) or die "Can't write to $handle_log: $!"; my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::Handle->new( name => 'handle', min_level => 'debug', handle => $fh ) ); $dispatch->log( level => 'notice', message => "handle test\n" ); # close file handles undef $dispatch; undef $fh; open $fh, '<', $handle_log or die "Can't open $handle_log: $!"; my @log = <$fh>; close $fh or die $!; is( $log[0], "handle test\n", q{Log::Dispatch::Handle created log file should contain 'handle test\\n'} ); } ); subtest( 'Email::MailSend output', sub { SKIP: { skip 'Cannot do MailSend tests', 1 unless $tests{MailSend} && $TestConfig{email_address}; my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::Email::MailSend->new( name => 'Mail::Send', min_level => 'debug', to => $TestConfig{email_address}, subject => 'Log::Dispatch test suite' ) ); $dispatch->log( level => 'emerg', message => "Mail::Send test - If you can read this then the test succeeded (PID $$)" ); diag( "Sending email with Mail::Send to $TestConfig{email_address}.\nIf you get it then the test succeeded (PID $$)\n" ); undef $dispatch; ok( 1, 'sent email via MailSend' ); } } ); subtest( 'Email::MailSendmail output', sub { SKIP: { skip 'Cannot do MailSendmail tests', 1 unless $tests{MailSendmail} && $TestConfig{email_address}; my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::Email::MailSendmail->new( name => 'Mail::Sendmail', min_level => 'debug', to => $TestConfig{email_address}, subject => 'Log::Dispatch test suite' ) ); $dispatch->log( level => 'emerg', message => "Mail::Sendmail test - If you can read this then the test succeeded (PID $$)" ); diag( "Sending email with Mail::Sendmail to $TestConfig{email_address}.\nIf you get it then the test succeeded (PID $$)\n" ); undef $dispatch; ok( 1, 'sent email via MailSendmail' ); } } ); subtest( 'Email::MIMELite output', sub { SKIP: { skip 'Cannot do MIMELite tests', 1 unless $tests{MIMELite} && $TestConfig{email_address}; my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::Email::MIMELite->new( name => 'Mime::Lite', min_level => 'debug', to => $TestConfig{email_address}, subject => 'Log::Dispatch test suite' ) ); $dispatch->log( level => 'emerg', message => "MIME::Lite - If you can read this then the test succeeded (PID $$)" ); diag( "Sending email with MIME::Lite to $TestConfig{email_address}.\nIf you get it then the test succeeded (PID $$)\n" ); undef $dispatch; ok( 1, 'sent mail via MIMELite' ); } } ); subtest( 'Email::MailSender output', sub { SKIP: { skip 'Cannot do MailSender tests', 1 unless $tests{MailSender} && $TestConfig{email_address}; my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::Email::MailSender->new( name => 'Mail::Sender', min_level => 'debug', smtp => 'localhost', to => $TestConfig{email_address}, subject => 'Log::Dispatch test suite' ) ); $dispatch->log( level => 'emerg', message => "Mail::Sender - If you can read this then the test succeeded (PID $$)" ); diag( "Sending email with Mail::Sender to $TestConfig{email_address}.\nIf you get it then the test succeeded (PID $$)\n" ); undef $dispatch; ok( 1, 'sent email via MailSender' ); } } ); subtest( 'Log::Dispatch::Output->accepted_levels', sub { my $l = Log::Dispatch::Screen->new( name => 'foo', min_level => 'warning', max_level => 'alert', stderr => 0 ); my @expected = qw(warning error critical alert); my @levels = $l->accepted_levels; is_deeply( \@expected, \@levels, 'accepted_levels matches what is expected' ); } ); subtest( 'Log::Dispatch single callback', sub { my $reverse = sub { my %p = @_; return reverse $p{message}; }; my $dispatch = Log::Dispatch->new( callbacks => $reverse ); my $string; $dispatch->add( Log::Dispatch::String->new( name => 'foo', string => \$string, min_level => 'warning', max_level => 'alert', ) ); $dispatch->log( level => 'warning', message => 'esrever' ); is( $string, 'reverse', 'callback to reverse text' ); } ); subtest( 'Log::Dispatch multiple callbacks', sub { my $reverse = sub { my %p = @_; return reverse $p{message}; }; my $uc = sub { my %p = @_; return uc $p{message}; }; my $dispatch = Log::Dispatch->new( callbacks => [ $reverse, $uc ] ); my $string; $dispatch->add( Log::Dispatch::String->new( name => 'foo', string => \$string, min_level => 'warning', max_level => 'alert', ) ); $dispatch->log( level => 'warning', message => 'esrever' ); is( $string, 'REVERSE', 'callback to reverse and uppercase text' ); is_deeply( [ $dispatch->callbacks() ], [ $reverse, $uc ], '->callbacks() method returns all of the callback subs' ); my $clone = $dispatch->clone(); is_deeply( $clone, $dispatch, 'clone is a shallow clone of the original object' ); $clone->add( Log::Dispatch::Screen->new( name => 'screen', min_level => 'debug', ) ); my @orig_outputs = map { $_->name() } $dispatch->outputs(); my @clone_outputs = map { $_->name() } $clone->outputs(); isnt( scalar(@orig_outputs), scalar(@clone_outputs), 'clone is not the same as original after adding an output' ); $clone->add_callback( sub { return 'foo' } ); my @orig_cb = $dispatch->callbacks(); my @clone_cb = $clone->callbacks(); isnt( scalar(@orig_cb), scalar(@clone_cb), 'clone is not the same as original after adding a callback' ); } ); subtest( 'Log::Dispatch::Output single callback', sub { my $reverse = sub { my %p = @_; return reverse $p{message}; }; my $dispatch = Log::Dispatch->new; my $string; $dispatch->add( Log::Dispatch::String->new( name => 'foo', string => \$string, min_level => 'warning', max_level => 'alert', callbacks => $reverse ) ); $dispatch->log( level => 'warning', message => 'esrever' ); is( $string, 'reverse', 'Log::Dispatch::Output callback to reverse text' ); } ); subtest( 'Log::Dispatch::Output multiple callbacks', sub { my $reverse = sub { my %p = @_; return reverse $p{message}; }; my $uc = sub { my %p = @_; return uc $p{message}; }; my $dispatch = Log::Dispatch->new; my $string; $dispatch->add( Log::Dispatch::String->new( name => 'foo', string => \$string, min_level => 'warning', max_level => 'alert', callbacks => [ $reverse, $uc ] ) ); $dispatch->log( level => 'warning', message => 'esrever' ); is( $string, 'REVERSE', 'Log::Dispatch::Output callbacks to reverse and uppercase text' ); } ); subtest( 'level parameter to callbacks', sub { my $level = sub { my %p = @_; return uc $p{level}; }; my $dispatch = Log::Dispatch->new( callbacks => $level ); my $string; $dispatch->add( Log::Dispatch::String->new( name => 'foo', string => \$string, min_level => 'warning', max_level => 'alert', stderr => 0 ) ); $dispatch->log( level => 'warning', message => 'esrever' ); is( $string, 'WARNING', 'Log::Dispatch callback to uppercase the level parameter' ); } ); subtest( 'level name methods', sub { my %levels = map { $_ => $_ } (qw( debug info notice warning error critical alert emergency )); @levels{qw( warn err crit emerg )} = (qw( warning error critical emergency )); foreach my $allowed_level ( qw( debug info notice warning error critical alert emergency )) { my $dispatch = Log::Dispatch->new; my $string; $dispatch->add( Log::Dispatch::String->new( name => 'foo', string => \$string, min_level => $allowed_level, max_level => $allowed_level, ) ); foreach my $test_level ( qw( debug info notice warn warning err error crit critical alert emerg emergency ) ) { $string = q{}; $dispatch->$test_level( $test_level, 'test' ); if ( $levels{$test_level} eq $allowed_level ) { my $expect = join $", $test_level, 'test'; is( $string, $expect, qq{Calling $test_level method should send message '$expect'} ); } else { ok( !length $string, "Calling $test_level method should not log anything" ); } } } } ); subtest( 'argument variations to name method', sub { my $string; my $dispatch = Log::Dispatch->new( outputs => [ [ 'String', name => 'string', string => \$string, min_level => 'debug', ], ], ); $dispatch->debug( 'foo', 'bar' ); is( $string, 'foo bar', 'passing multiple elements to ->debug stringifies them like an array' ); $string = q{}; $dispatch->debug( sub {'foo'} ); is( $string, 'foo', 'passing single sub ref to ->debug calls the sub ref' ); } ); subtest( 'Log::Dispatch->level_is_valid method', sub { foreach my $l ( qw( debug info notice warning err error crit critical alert emerg emergency ) ) { ok( Log::Dispatch->level_is_valid($l), "$l is valid level" ); } foreach my $l (qw( debu inf foo bar )) { ok( !Log::Dispatch->level_is_valid($l), "$l is not valid level" ); } # Provide calling line if level missing my $string; my $dispatch = Log::Dispatch->new( outputs => [ [ 'String', name => 'string', string => \$string, min_level => 'debug', ], ], ); like( exception { $dispatch->log( msg => 'Message' ) }, qr/Logging level was not provided at .* line \d+./, 'Provide calling line if level not provided' ); } ); subtest( 'Log::Dispatch->would_log method', sub { my $string; my $dispatch = Log::Dispatch->new( outputs => [ [ 'String', name => 'string', string => \$string, min_level => 'debug', ], ], ); is( $dispatch->would_log('debug'), 1, 'Would log works with level name' ); is( $dispatch->would_log(0), 1, 'Would log works with level number' ); } ); subtest( 'File output mode=write', sub { my $mode_log = File::Spec->catfile( $tempdir, 'mode.log' ); my $f1 = Log::Dispatch::File->new( name => 'file', min_level => 1, filename => $mode_log, mode => 'write', ); $f1->log( level => 'emerg', message => "test2\n" ); undef $f1; open my $fh, '<', $mode_log or die "Cannot read $mode_log: $!"; my $data = do { local $/ = undef; <$fh> }; close $fh or die $!; like( $data, qr/^test2/, 'test write mode' ); } ); subtest( 'Log::Dispatch->dispatch by name', sub { my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::Screen->new( name => 'yomama', min_level => 'alert' ) ); ok( $dispatch->output('yomama'), 'yomama output should exist' ); ok( !$dispatch->output('nomama'), 'nomama output should not exist' ); } ); subtest( 'File output close_after_writer & permissions', sub { my $dispatch = Log::Dispatch->new; my $close_log = File::Spec->catfile( $tempdir, 'close.log' ); ## no critic (ValuesAndExpressions::ProhibitLeadingZeros) $dispatch->add( Log::Dispatch::File->new( name => 'close', min_level => 'info', filename => $close_log, permissions => 0777, close_after_write => 1 ) ); $dispatch->log( level => 'info', message => "info\n" ); open my $fh, '<', $close_log or die "Can't read $close_log: $!"; my @log = <$fh>; close $fh or die $!; is( $log[0], "info\n", q{First line in log file should be 'info\\n'} ); my $mode = ( stat $close_log )[2] or die "Cannot stat $close_log: $!"; my $mode_string = sprintf( '%04o', $mode & 07777 ); if ( $^O =~ /win32/i ) { ok( $mode_string eq '0777' || $mode_string eq '0666', 'Mode should be 0777 or 0666' ); } elsif ( $^O =~ /cygwin|msys/i ) { ok( $mode_string eq '0777' || $mode_string eq '0644', 'Mode should be 0777 or 0644' ); } else { is( $mode_string, '0777', 'Mode should be 0777' ); } } ); subtest( 'File output chmod calls', sub { my $dispatch = Log::Dispatch->new; my $chmod_log = File::Spec->catfile( $tempdir, 'chmod.log' ); open my $fh, '>', $chmod_log or die "Cannot write to $chmod_log: $!"; close $fh or die $!; chmod 0777, $chmod_log or die "Cannot chmod 0777 $chmod_log: $!"; my @chmod; ## no critic (TestingAndDebugging::ProhibitNoWarnings) no warnings 'once'; local *CORE::GLOBAL::chmod = sub { @chmod = @_; warn @chmod }; ## no critic (ValuesAndExpressions::ProhibitLeadingZeros) $dispatch->add( Log::Dispatch::File->new( name => 'chmod', min_level => 'info', filename => $chmod_log, permissions => 0777, ) ); $dispatch->warning('test'); ok( !scalar @chmod, 'chmod() was not called when permissions already matched what was specified' ); } ); subtest( 'File output binmode', sub { SKIP: { ## no critic (ControlStructures::ProhibitNegativeExpressionsInUnlessAndUntilConditions) skip "Cannot test utf8 files with this version of Perl ($])", 1 unless $] >= 5.008; my $dispatch = Log::Dispatch->new; my $utf8_log = File::Spec->catfile( $tempdir, 'utf8.log' ); $dispatch->add( Log::Dispatch::File->new( name => 'utf8', min_level => 'info', filename => $utf8_log, binmode => ':encoding(UTF-8)', ) ); my @warnings; { local $SIG{__WARN__} = sub { push @warnings, @_ }; $dispatch->warning("\x{999A}"); } ok( !scalar @warnings, 'utf8 binmode was applied to file and no warnings were issued' ); } } ); subtest( 'Log::Dispatch->would_log', sub { my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::Null->new( name => 'null', min_level => 'warning', ) ); ok( !$dispatch->would_log('foo'), q{will not log 'foo'} ); ok( !$dispatch->would_log('debug'), q{will not log 'debug'} ); ok( !$dispatch->is_debug(), 'is_debug returns false' ); ok( $dispatch->is_warning(), 'is_warning returns true' ); ok( $dispatch->would_log('crit'), q{will log 'crit'} ); ok( $dispatch->is_crit, q{will log 'crit'} ); } ); subtest( 'messages as coderefs are only called as needed', sub { my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::Null->new( name => 'null', min_level => 'info', max_level => 'critical', ) ); my $called = 0; my $message = sub { $called = 1 }; $dispatch->log( level => 'debug', message => $message ); ok( !$called, 'subref is not called if the message would not be logged' ); $called = 0; $dispatch->log( level => 'warning', message => $message ); ok( $called, 'subref is called when message is logged' ); $called = 0; $dispatch->log( level => 'emergency', message => $message ); ok( !$called, 'subref is not called when message would not be logged' ); } ); subtest( 'passing coderef to ->log', sub { my $string; my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::String->new( name => 'handle', string => \$string, min_level => 'debug', ) ); $dispatch->log( level => 'debug', message => sub {'this is my message'}, ); is( $string, 'this is my message', 'message returned by subref is logged' ); } ); subtest( 'newline parameter to output', sub { my $string; my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::String->new( name => 'handle', string => \$string, min_level => 'debug', newline => 1, ) ); $dispatch->debug('hello'); $dispatch->debug('goodbye'); is( $string, "hello\ngoodbye\n", 'added newlines' ); } ); subtest( 'log_and_die method', sub { my $string; my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::String->new( name => 'handle', string => \$string, min_level => 'debug', ) ); my $e = exception { _log_and_die( $dispatch, level => 'error', message => 'this is my message', ); }; ok( $e, 'died when calling log_and_die()' ); like( $e, qr{this is my message}, 'error contains expected message' ); like( $e, qr{basic\.t line 50\d\d}, 'error croaked' ); is( $string, 'this is my message', 'message is logged' ); undef $string; try { Croaker::croak($dispatch) } catch { $e = $_; }; ok( $e, 'died when calling log_and_croak()' ); like( $e, qr{croaking a message}, 'error contains expected message' ); like( $e, qr{basic\.t line 100\d\d}, 'error croaked from perspective of caller' ); is( $string, 'croaking a message', 'message is logged' ); } ); subtest( 'adding and removing callbacks in output', sub { my $string; my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::String->new( name => 'handle', string => \$string, min_level => 'debug', ) ); $dispatch->log( level => 'debug', message => 'foo' ); is( $string, 'foo', 'first test w/o callback' ); my $cb = sub { return 'bar' }; $string = q{}; $dispatch->add_callback($cb); $dispatch->log( level => 'debug', message => 'foo' ); is( $string, 'bar', 'second call, callback overrides message' ); $string = q{}; $dispatch->remove_callback($cb); $dispatch->log( level => 'debug', message => 'foo' ); is( $string, 'foo', 'third call, callback is removed' ); } ); subtest( 'adding and removing callbacks in Log::Dispatch', sub { my $string; my $dispatch = Log::Dispatch->new( callbacks => sub { return 'baz' }, ); $dispatch->add( Log::Dispatch::String->new( name => 'handle', string => \$string, min_level => 'debug', ) ); $dispatch->log( level => 'debug', message => 'foo' ); is( $string, 'baz', 'first test gets orig callback result' ); my $cb = sub { return 'bar' }; $string = q{}; $dispatch->add_callback($cb); $dispatch->log( level => 'debug', message => 'foo' ); is( $string, 'bar', 'second call, callback overrides message' ); $string = q{}; $dispatch->remove_callback($cb); $dispatch->log( level => 'debug', message => 'foo' ); is( $string, 'baz', 'third call, output callback is removed' ); } ); subtest( 'callback in output can overwrite message', sub { my $string; my $dispatch = Log::Dispatch->new; $dispatch->add( Log::Dispatch::String->new( name => 'handle', string => \$string, min_level => 'debug', ) ); $dispatch->log( level => 'debug', message => 'foo' ); is( $string, 'foo', 'first test w/o callback' ); $string = q{}; $dispatch->add_callback( sub { return 'bar' } ); $dispatch->log( level => 'debug', message => 'foo' ); is( $string, 'bar', 'second call, callback overrides message' ); } ); subtest( 'callback in Log::Dispatch can overwrite message', sub { my $string; my $dispatch = Log::Dispatch->new( callbacks => sub { return 'baz' }, ); $dispatch->add( Log::Dispatch::String->new( name => 'handle', string => \$string, min_level => 'debug', ) ); $dispatch->log( level => 'debug', message => 'foo' ); is( $string, 'baz', 'first test gets orig callback result' ); $string = q{}; $dispatch->add_callback( sub { return 'bar' } ); $dispatch->log( level => 'debug', message => 'foo' ); is( $string, 'bar', 'second call, callback overrides message' ); } ); subtest( 'default output name', sub { # Test defaults my $dispatch = Log::Dispatch::Null->new( min_level => 'debug' ); like( $dispatch->name, qr/anon/, 'generated anon name' ); is( $dispatch->max_level, 'emergency', 'max_level is emergency' ); } ); subtest( 'callbacks get correct level', sub { my $level; my $record_level = sub { my %p = @_; $level = $p{level}; return %p; }; my $dispatch = Log::Dispatch->new( callbacks => $record_level, outputs => [ [ 'Null', name => 'null', min_level => 'debug', ], ], ); $dispatch->warn('foo'); is( $level, 'warning', 'level for call to ->warn is warning' ); $dispatch->err('foo'); is( $level, 'error', 'level for call to ->err is error' ); $dispatch->crit('foo'); is( $level, 'critical', 'level for call to ->crit is critical' ); $dispatch->emerg('foo'); is( $level, 'emergency', 'level for call to ->emerg is emergency' ); } ); subtest( 'Code output', sub { my @calls; my $log = Log::Dispatch->new( outputs => [ [ 'Code', min_level => 'error', code => sub { push @calls, {@_} }, ], ] ); $log->error('foo'); $log->info('bar'); $log->critical('baz'); is_deeply( \@calls, [ { level => 'error', message => 'foo', }, { level => 'critical', message => 'baz', }, ], 'code received the expected messages' ); } ); subtest( 'passing level as name or integer', sub { my $dispatch = Log::Dispatch->new; my $log = File::Spec->catdir( $tempdir, 'emerg.log' ); $dispatch->add( Log::Dispatch::File->new( name => 'file1', min_level => 3, filename => $log, ) ); $dispatch->log( level => 'info', message => "info level 1\n" ); $dispatch->log( level => 'emerg', message => "emerg level 1\n" ); $dispatch->log( level => 'warn', message => "warn level 1\n" ); $dispatch->log( level => 3, message => "bug 106495 1\n" ); $dispatch->log( level => 4, message => "bug 106495 2\n" ); $dispatch->log( level => 1, message => "bug 106495 3\n" ); open my $fh, '<', $log or die $!; my @log = <$fh>; close $fh or die $!; is( $log[0], "emerg level 1\n", 'at level 3, emerg works' ); is( $log[1], "warn level 1\n", 'at level 3, warn works' ); is( $log[2], "bug 106495 1\n", 'level as integer works with min_level 3 and level 3' ); is( $log[3], "bug 106495 2\n", 'level as integer works with min_level 3 and level 4' ); is( $log[4], undef, 'using integer level works with min_level 3 and level 1' ); } ); subtest( 'more levels as integers', sub { my $dispatch = Log::Dispatch->new; my $log = File::Spec->catdir( $tempdir, 'emerg.log' ); $dispatch->add( Log::Dispatch::File->new( name => 'file1', min_level => 0, filename => $log, ) ); $dispatch->log( level => 0, message => "bug 106495 0\n" ); $dispatch->log( level => 1, message => "bug 106495 1\n" ); $dispatch->log( level => 2, message => "bug 106495 2\n" ); $dispatch->log( level => 3, message => "bug 106495 3\n" ); $dispatch->log( level => 4, message => "bug 106495 4\n" ); $dispatch->log( level => 5, message => "bug 106495 5\n" ); $dispatch->log( level => 6, message => "bug 106495 6\n" ); $dispatch->log( level => 7, message => "bug 106495 7\n" ); open my $fh, '<', $log or die $!; my @log = <$fh>; close $fh or die $!; is( $log[0], "bug 106495 0\n", 'at level 0, int works' ); is( $log[1], "bug 106495 1\n", 'at level 1, int works' ); is( $log[2], "bug 106495 2\n", 'at level 2, int works' ); is( $log[3], "bug 106495 3\n", 'at level 3, int works' ); is( $log[4], "bug 106495 4\n", 'at level 4, int works' ); is( $log[5], "bug 106495 5\n", 'at level 5, int works' ); is( $log[6], "bug 106495 6\n", 'at level 6, int works' ); is( $log[7], "bug 106495 7\n", 'at level 7, int works' ); } ); done_testing(); ## no critic (Modules::ProhibitMultiplePackages) { package Log::Dispatch::String; use strict; use Log::Dispatch::Output; use base qw( Log::Dispatch::Output ); sub new { my $proto = shift; my $class = ref $proto || $proto; my %p = @_; my $self = bless { string => $p{string} }, $class; $self->_basic_init(%p); return $self; } sub log_message { my $self = shift; my %p = @_; ${ $self->{string} } .= $p{message}; } } #line 5000 sub _log_and_die { shift->log_and_die(@_); } { #line 10000 package Croaker; sub croak { shift->log_and_croak( level => 'error', message => 'croaking a message' ); } } Log-Dispatch-2.67/xt/0000775000175000017500000000000013162076057014232 5ustar autarchautarchLog-Dispatch-2.67/xt/release/0000775000175000017500000000000013162076057015652 5ustar autarchautarchLog-Dispatch-2.67/xt/release/cpan-changes.t0000644000175000017500000000034413162076057020365 0ustar autarchautarchuse strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::CPAN::Changes 0.012 use Test::More 0.96 tests => 1; use Test::CPAN::Changes; subtest 'changes_ok' => sub { changes_file_ok('Changes'); }; Log-Dispatch-2.67/xt/release/meta-json.t0000644000175000017500000000006413162076057017732 0ustar autarchautarch#!perl use Test::CPAN::Meta::JSON; meta_json_ok(); Log-Dispatch-2.67/xt/author/0000775000175000017500000000000013162076057015534 5ustar autarchautarchLog-Dispatch-2.67/xt/author/test-dependents.t0000644000175000017500000000267713162076057021041 0ustar autarchautarchuse strict; use warnings; use Cwd qw( abs_path ); use Test::More; # You'd think Test::Needs would be good enough here but it'll bail out under # RELEASE_TESTING if the needed module can't be loaded. BEGIN { if ( $] < 5.010 ) { plan skip_all => 'Test::DependentModules cannot be loaded on Perl 5.8.x'; } } use Test::Needs { 'Test::DependentModules' => '0.22' }; use Test::DependentModules 0.22 qw( test_all_dependents ); plan skip_all => 'Must set LOG_DISPATCH_TEST_DEPS to true in order to run these tests' unless $ENV{LOG_DISPATCH_TEST_DEPS}; local $ENV{PERL_TEST_DM_LOG_DIR} = abs_path('.'); my %known_failures = map { $_ => 1 } ( 'Log-Dispatch-FileRotate', # Prints out broken TAP 'Log-Dispatch-Gtk2-Notify', # requires Gtk2 'Log-Dispatch-MacGrowl', # Mac only 'Log-Dispatch-Scribe', # fails its pod coverage test 'Log-Dispatch-Tk', # doesn't seem to actually exist on CPAN 'Log-Dispatch-Win32EventLog', # Win32 only 'Log-Dispatch-Wx', # requires wx 'Log-Dispatch-XML', # depends on non-existent Log::Dispatch::Buffer 'Log-Dispatch-ZMQ', # requires libzeromq and other deps ); test_all_dependents( 'Log::Dispatch', { filter => sub { my $dist = shift; return 0 unless $dist eq 'Dist-Zilla' || $dist =~ /^Log-Dispatch/; return !$known_failures{$dist}; } }, ); Log-Dispatch-2.67/xt/author/eol.t0000644000175000017500000000252013162076057016475 0ustar autarchautarchuse strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::EOL 0.19 use Test::More 0.88; use Test::EOL; my @files = ( 'lib/Log/Dispatch.pm', 'lib/Log/Dispatch/ApacheLog.pm', 'lib/Log/Dispatch/Base.pm', 'lib/Log/Dispatch/Code.pm', 'lib/Log/Dispatch/Conflicts.pm', 'lib/Log/Dispatch/Email.pm', 'lib/Log/Dispatch/Email/MIMELite.pm', 'lib/Log/Dispatch/Email/MailSend.pm', 'lib/Log/Dispatch/Email/MailSender.pm', 'lib/Log/Dispatch/Email/MailSendmail.pm', 'lib/Log/Dispatch/File.pm', 'lib/Log/Dispatch/File/Locked.pm', 'lib/Log/Dispatch/Handle.pm', 'lib/Log/Dispatch/Null.pm', 'lib/Log/Dispatch/Output.pm', 'lib/Log/Dispatch/Screen.pm', 'lib/Log/Dispatch/Syslog.pm', 'lib/Log/Dispatch/Types.pm', 'lib/Log/Dispatch/Vars.pm', 't/00-compile.t', 't/00-report-prereqs.dd', 't/00-report-prereqs.t', 't/basic.t', 't/binmode.t', 't/close-after-write.t', 't/email-exit-helper.pl', 't/email-exit.t', 't/file-locked.t', 't/lazy-open.t', 't/lib/Log/Dispatch/TestUtil.pm', 't/screen-helper.pl', 't/screen.t', 't/sendmail', 't/short-syntax.t', 't/syslog-lock-without-preloaded-threads.t', 't/syslog-threads.t', 't/syslog.t' ); eol_unix_ok($_, { trailing_whitespace => 1 }) foreach @files; done_testing; Log-Dispatch-2.67/xt/author/test-version.t0000644000175000017500000000223213162076057020360 0ustar autarchautarchuse strict; use warnings; use Test::More; # generated by Dist::Zilla::Plugin::Test::Version 1.09 use Test::Version; my @imports = qw( version_ok ); my $params = { is_strict => 0, has_version => 1, multiple => 0, }; push @imports, $params if version->parse( $Test::Version::VERSION ) >= version->parse('1.002'); Test::Version->import(@imports); version_ok('lib/Log/Dispatch.pm'); version_ok('lib/Log/Dispatch/ApacheLog.pm'); version_ok('lib/Log/Dispatch/Base.pm'); version_ok('lib/Log/Dispatch/Code.pm'); version_ok('lib/Log/Dispatch/Email.pm'); version_ok('lib/Log/Dispatch/Email/MIMELite.pm'); version_ok('lib/Log/Dispatch/Email/MailSend.pm'); version_ok('lib/Log/Dispatch/Email/MailSender.pm'); version_ok('lib/Log/Dispatch/Email/MailSendmail.pm'); version_ok('lib/Log/Dispatch/File.pm'); version_ok('lib/Log/Dispatch/File/Locked.pm'); version_ok('lib/Log/Dispatch/Handle.pm'); version_ok('lib/Log/Dispatch/Null.pm'); version_ok('lib/Log/Dispatch/Output.pm'); version_ok('lib/Log/Dispatch/Screen.pm'); version_ok('lib/Log/Dispatch/Syslog.pm'); version_ok('lib/Log/Dispatch/Types.pm'); version_ok('lib/Log/Dispatch/Vars.pm'); done_testing; Log-Dispatch-2.67/xt/author/portability.t0000644000175000017500000000026713162076057020266 0ustar autarchautarchuse strict; use warnings; use Test::More; eval 'use Test::Portability::Files'; plan skip_all => 'Test::Portability::Files required for testing portability' if $@; run_tests(); Log-Dispatch-2.67/xt/author/no-tabs.t0000644000175000017500000000246613162076057017272 0ustar autarchautarchuse strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::NoTabs 0.15 use Test::More 0.88; use Test::NoTabs; my @files = ( 'lib/Log/Dispatch.pm', 'lib/Log/Dispatch/ApacheLog.pm', 'lib/Log/Dispatch/Base.pm', 'lib/Log/Dispatch/Code.pm', 'lib/Log/Dispatch/Conflicts.pm', 'lib/Log/Dispatch/Email.pm', 'lib/Log/Dispatch/Email/MIMELite.pm', 'lib/Log/Dispatch/Email/MailSend.pm', 'lib/Log/Dispatch/Email/MailSender.pm', 'lib/Log/Dispatch/Email/MailSendmail.pm', 'lib/Log/Dispatch/File.pm', 'lib/Log/Dispatch/File/Locked.pm', 'lib/Log/Dispatch/Handle.pm', 'lib/Log/Dispatch/Null.pm', 'lib/Log/Dispatch/Output.pm', 'lib/Log/Dispatch/Screen.pm', 'lib/Log/Dispatch/Syslog.pm', 'lib/Log/Dispatch/Types.pm', 'lib/Log/Dispatch/Vars.pm', 't/00-compile.t', 't/00-report-prereqs.dd', 't/00-report-prereqs.t', 't/basic.t', 't/binmode.t', 't/close-after-write.t', 't/email-exit-helper.pl', 't/email-exit.t', 't/file-locked.t', 't/lazy-open.t', 't/lib/Log/Dispatch/TestUtil.pm', 't/screen-helper.pl', 't/screen.t', 't/sendmail', 't/short-syntax.t', 't/syslog-lock-without-preloaded-threads.t', 't/syslog-threads.t', 't/syslog.t' ); notabs_ok($_) foreach @files; done_testing; Log-Dispatch-2.67/xt/author/pod-coverage.t0000644000175000017500000000270413162076057020275 0ustar autarchautarch#!perl # This file was automatically generated by Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable. use Test::Pod::Coverage 1.08; use Test::More 0.88; BEGIN { if ( $] <= 5.008008 ) { plan skip_all => 'These tests require Pod::Coverage::TrustPod, which only works with Perl 5.8.9+'; } } use Pod::Coverage::TrustPod; my %skip = map { $_ => 1 } qw( Log::Dispatch::ApacheLog Log::Dispatch::Conflicts ); my @modules; for my $module ( all_modules() ) { next if $skip{$module}; push @modules, $module; } plan skip_all => 'All the modules we found were excluded from POD coverage test.' unless @modules; plan tests => scalar @modules; my %trustme = ( 'Log::Dispatch' => [ qr/^(?:warn|err|crit|emerg)$/, qr/^is_\w+$/ ], 'Log::Dispatch::Output' => [ qr/^new$/ ], 'Log::Dispatch::File' => [ qr/^(?:O_)?APPEND$/ ] ); my @also_private; for my $module ( sort @modules ) { pod_coverage_ok( $module, { coverage_class => 'Pod::Coverage::TrustPod', also_private => \@also_private, trustme => $trustme{$module} || [], }, "pod coverage for $module" ); } done_testing(); Log-Dispatch-2.67/xt/author/tidyall.t0000644000175000017500000000067413162076057017370 0ustar autarchautarch# This file was automatically generated by Dist::Zilla::Plugin::Test::TidyAll v$VERSION use Test::More 0.88; BEGIN { if ( $] < 5.010 ) { plan skip_all => 'This test requires Perl version 5.010'; } } use Test::Code::TidyAll 0.24; tidyall_ok( verbose => ( exists $ENV{TEST_TIDYALL_VERBOSE} ? $ENV{TEST_TIDYALL_VERBOSE} : 1 ), jobs => ( exists $ENV{TEST_TIDYALL_JOBS} ? $ENV{TEST_TIDYALL_JOBS} : 4 ), ); done_testing; Log-Dispatch-2.67/xt/author/mojibake.t0000644000175000017500000000015113162076057017475 0ustar autarchautarch#!perl use strict; use warnings qw(all); use Test::More; use Test::Mojibake; all_files_encoding_ok(); Log-Dispatch-2.67/xt/author/pod-syntax.t0000644000175000017500000000025213162076057020024 0ustar autarchautarch#!perl # This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests. use strict; use warnings; use Test::More; use Test::Pod 1.41; all_pod_files_ok(); Log-Dispatch-2.67/xt/author/pod-spell.t0000644000175000017500000000221413162076057017615 0ustar autarchautarchuse strict; use warnings; use Test::More; # generated by Dist::Zilla::Plugin::Test::PodSpelling 2.007004 use Test::Spelling 0.12; use Pod::Wordlist; add_stopwords(); all_pod_files_spelling_ok( qw( bin lib ) ); __DATA__ API Alders Anirvan ApacheLog Attrill Base Bell Bertrand Bucheli CPAN Carly Carsten Chatterjee Cholet Code Conflicts DROLSKY DROLSKY's Dave Dispatch Doug Dumont Email Etheridge FandiƱo File Goess Graham Gregory Grohmann Handle Jackson Johann Jonathan Karen Kerin Kivanc Konrad Locked Log MIMELite MailSend MailSender MailSendmail Manfredi MenguĆ© Michael Millar Miyagawa NTLM Null Olaf Olivier Ollis Oschwald Output PayPal Pfeiffer Rezic Rohan Rolschewski Rolsky Rolsky's Ross STDERR STDOUT Salvador Schilli Schout Screen Slaven Steve Straup Subclasses Swartz Syslog TLS Tatsuhiko Types UTF Vars Whitney Yazan anirvan apache appenders autarch auth authid authpriv authpwd autoflushed classname crit dolmen doug drolsky emerg ether fd filename goschwald ident jorol kb kern kfm kivancyazan lib logopt mail mschout multi olaf params plicease replyto ross se456 sfandino smtp srezic stderr steveb subclass's subclasses swartz uucp whitney Log-Dispatch-2.67/tidyall.ini0000644000175000017500000000112613162076057015740 0ustar autarchautarchignore = .build/**/* ignore = Log-Dispatch-*/**/* ignore = blib/**/* ignore = lib/Log/Dispatch/Conflicts.pm ignore = t/00-* ignore = t/author-* ignore = t/release-* ignore = t/zzz-* ignore = xt/**/* [PerlCritic] select = **/*.{pl,pm,t,psgi} argv = --profile=$ROOT/perlcriticrc [PerlCritic non-auto-generated xt] select = xt/author/test-dependents.t argv = --profile=$ROOT/perlcriticrc [PerlTidy] select = **/*.{pl,pm,t,psgi} argv = --profile=$ROOT/perltidyrc [PerlTidy non-auto-generated xt] select = xt/author/test-dependents.t argv = --profile=$ROOT/perltidyrc [Test::Vars] select = **/*.pm Log-Dispatch-2.67/INSTALL0000644000175000017500000000220013162076057014620 0ustar autarchautarchThis is the Perl distribution Log-Dispatch. Installing Log-Dispatch is straightforward. ## Installation with cpanm If you have cpanm, you only need one line: % cpanm Log::Dispatch If it does not have permission to install modules to the current perl, cpanm will automatically set up and install to a local::lib in your home directory. See the local::lib documentation (https://metacpan.org/pod/local::lib) for details on enabling it in your environment. ## Installing with the CPAN shell Alternatively, if your CPAN shell is set up, you should just be able to do: % cpan Log::Dispatch ## Manual installation As a last resort, you can manually install it. Download the tarball, untar it, then build it: % perl Makefile.PL % make && make test Then install it: % make install If your perl is system-managed, you can create a local::lib in your home directory to install modules to. For details, see the local::lib documentation: https://metacpan.org/pod/local::lib ## Documentation Log-Dispatch documentation is available as POD. You can run perldoc from a shell to read the documentation: % perldoc Log::Dispatch Log-Dispatch-2.67/Changes0000644000175000017500000005674613162076057015112 0ustar autarchautarch2.67 2017-09-24 - Added a lazy_open option to the File output. This delays opening the file until the first time a log message is written to it. Implemented by Slaven Rezić. GH #50. 2.66 2017-08-14 - Fixed the ApacheLog output, which was broken in 2.60. Fixed by Michael Schout. GitHub #48 and #49. 2.65 2017-06-11 - When Log::Dispatch::File is asked to chmod a file and that fails, show the requested permissions in octal. Patch by Carsten Grohmann. GitHub #46. 2.64 2017-02-25 (TRIAL RELEASE) - Improve level validation and canonicalization logic. Patch by Kerin Millar, minor changes and tests by Kivanc Yazan. Github #42. - The log_and_die and log_and_croak methods are now identical, as we set @CARP_NOT for Log::Dispatch to exclude the Log::Dispatch package. You can still explicitly pass carp_level to log_and_croak. 2.63 2017-02-19 - Updated the conflicting version for Log::Dispatch::File::Stamped in metadata (due to changes in handling of close_after_write). Patch by Karen Etheridge. GitHub #41. 2.62 2017-02-13 - Devel::Confess was accidentally being loaded in Log::Dispatch. Fixed by Karen Etheridge. GitHub #39. 2.61 2017-02-13 - The 2.60 release would throw an exception if the logged message was empty. While this makes sense, it also breaks backwards compatibility, so it has been reverted. Reported by Greg Oschwald. GitHub #38. - The 2.60 release would throw an exception if you tried to create a Syslog output where the ident was an empty string. Reported by Greg Oschwald. GitHub #38. 2.60 2017-02-12 - Same as 2.59 ... Switched from Params::Validate to Params::ValidationCompiler. This should speed up constructors and logging a little bit. This also allows Log::Dispatch::File to accept things like Path::Tiny objects for filenames. Reported by Joel Berger. GitHub #36. 2.59 2017-02-05 (TRIAL RELEASE) - Switched from Params::Validate to Params::ValidationCompiler. This should speed up constructors and logging a little bit. This also allows Log::Dispatch::File to accept things like Path::Tiny objects for filenames. Reported by Joel Berger. GitHub #36. 2.58 2016-11-13 - Switched from RT to the GitHub issue tracker. 2.57 2016-08-13 - Added a remove_callback method to the main Log::Dispatch object as well as all outputs. Patch by Doug Bell. GitHub #22. 2.56 2016-05-06 - Cleaned up some cruft in Pod. Some sections ended up in there twice. 2.55 2016-05-06 - The values of $@, $!, and $? are protected in various cases where they could end up being changed by logging code. Patch by Salvador FandiƱo. GitHub #18. - Treat MSYS2 like Cygwin in tests. Fix by Graham Ollis. GitHub #19. 2.54 2016-01-18 - Fixed File::Locked even more. While some deadlocks were eliminated, there was still an issue when a Log::Dispatch object was created in a parent process and then recreated in the children. If the close_after_write parameter was false, then there would be a deadlock. - Made Syslog work on a threaded Perl when the threads module was not explicitly loaded. Fixed by Konrad Bucheli. GitHub #13. - The log() method now accepts a level parameter as an integer. Fixed by Steve Bertrand. GitHub #15. 2.53 2016-01-14 - Actually fix File::Locked, this time with some actual tests. 2.52 2016-01-13 - Make File::Locked output do an explicit unlock if the close_after_write option is not set. Without this it would open the file once in each process, attempting to get a lock at open time, pretty much guaranteeing a deadlock in a multiprocess environment. Now it should work sanely whether close_after_write is true or not. 2.51 2015-09-19 - Fixed t/08-screen.t on Windows platforms. 2.50 2015-09-02 - Changed how the Screen output handles UTF-8 data once more. The Screen module has gone back to printing output directly to the global STDOUT and STDERR handles. The previous changes broke the tests for several modules, including Log::Dispatch::Config. This change should fix them. 2.49 2015-08-21 - The Screen output now enables autoflush on the handle it uses to send output to STDOUT or STDERR every time it sends a message. This does not affect the global STDOUT or STDERR, as the Screen module makes its own handle for output. This fixes a bug reported by Karen Etheridge that caused this module to not play nicely with Capture::Tiny in some cases. RT #106605. 2.48 2015-08-07 - Fixed (I hope) tests that were added in the last release that fail on Windows. 2.47 2015-08-06 - Really, really make per-thread locking work. Depending on when threads and threads::shared were loaded, you might get an error like 'Type of arg 1 to threads::shared::share must be one of $@% at .../Log/Dispatch/Syslog.pm line 67, near "$thread_lock)"'. Reported by David Schweikert. - Added support for auth-related parameters and replyto to Log::Dispatch::Email::MailSender. Implemented by Rohan Carly. Based on GitHub #10. - Added a utf8 flag for Log::Dispatch::Screen. If this is true, then it sets the ":encoding(UTF-8)" flag on the handle it uses for output (without affecting STDOUT or STDERR elsewhere). Suggested by Ivan Baidakou. 2.46 2015-08-05 - Really make the per-thread locking in the Syslog output work. Based on a patch by David Schweikert. GitHub #9. 2.45 2015-06-14 - Don't include threads and threads::shared in list of dependencies. This is only needed for Log::Dispatch::Syslog and is loaded at runtime as needed (which has its own issues but ...). Reported by Kent Fredric. RT #103392. 2.44 2014-10-18 - The fix for a buffered email output in the last release introduced a bug with _non-buffered_ email outputs. This would cause a fatal error during global destruction when the DESTROY method was called. Reported by Christ Hutchinson. RT #99474. 2.43 2014-10-05 - Fixed the thread locking in Log::Dispatch::Syslog (I hope). The previous version caused Perl to crash when per-thread locking was enabled. Note that I don't use threads so I haven't tested this. Patch by Sergio FernĆ”ndez MuƱoz. RT # 99208. - If a buffered email output is being destroyed during global destruction and still has messages in the buffer, we warn and do not attempt to send the messages. During global destruction, the package we use to send email may already be destroyed, leading to weird errors when we try to use it. Reported by Mark Overmeer. RT #97733. - In 2.42 I added the ability to pass a hashref for the socket parameter given to Log::Dispatch::Syslog, but I forgot to mention this here. This is necessary to support remote logging. Patch by David Coppit. RT #93045. 2.42 2014-08-12 - Added a Log::Dispatch->clone() method. This returns shallow clone. The outputs and callbacks are shared, but changes to outputs and callbacks in the clone do not affect the original, or vice versa. - Added Log::Dispatch->outputs() method. This returns all the output objects in a dispatch object. - Added Log::Dispatch->callbacks() method. This returns all the callback subs in a dispatch object. - The Syslog output now calls Sys::Syslog::setlogsock() every time a message is logged, since something else could have called it in between logging two messages. - Added a lock parameter to the Syslog output. If this is true, then logging is done in the scope of a per-thread lock. Reported by Cedric Carree and Franck Youssef. RT #67988 and #85013. - Replaced Class::Load with Module::Runtime. 2.41 2013-07-22 - An error is now thrown if you call Log::Dispatch->log without a level. Previously you'd just get a warning and then execution would continue (without logging anything). Patch by Ross Attrill. RT #87133. 2.40 2013-07-01 - Added a conflict entry for older Log::Dispatch::File::Stamped to the metadata. Patch by Karen Etheridge. RT #86215. 2.39 2013-04-21 - You can now pass a port option to the MailSender output. Patch by Whitney Jackson. 2.38 2013-04-14 - Fix test that used undeclared prereqs so it does not do that. 2.37 2013-04-14 - Moved Log::Dispatch::File constructor parameter validation moved to _basic_init() to facilitate proper subclassing. Patch by ether. RT #84545. 2.36 2013-04-08 - Added a very simple Log::Dispatch::Code output. This lets you log to a subroutine reference. - Added Sys::Syslog 0.25 as a prereq. This is a temporary fix to the problem of Log::Dispatch shipping lots of output modules with undeclared prereqs (so as not to require mod_perl, four email sending modules, etc.). In the future Log::Dispatch will be split into a core distro and a set of distros, one for each output that has prereqs. Reported by Michael Schwern. RT #84481. 2.35 2013-01-20 - Added a big warning about the potential for deadlocks in the documentation for Log::Dispatch::File::Locked. Patch by ether. 2.34 2012-12-08 - Fix a test bug that caused the tests to fail on all Perls before 5.16.0. 2.33 2012-12-07 - Added a 'syswrite' option to Log::Dispatch::File which causes all writes to use syswrite (so they're atomic). Patched by ether. RT #81669. - The File output's DESTROY method now checks to see if it's associated handle is open before trying to close it. Patch by Jeffrey Thalhammer. 2.32 2012-05-24 - Fix a test failure - test failed if you had 0.16 <= Sys::Syslog < 0.25 installed. - Added a kludgey test failure fix for failure on Cygwin. Patch by Christian Carey. RT #77364. 2.31 2012-05-21 - Added missing prereq - Class::Load. 2.30 2012-05-20 - Remove Sys::Syslog as a prereq, since you can use this distro perfectly well without it. Fixes RT #52065. - You can now pass a subroutine reference to the sugar methods like $dispatch->debug() and friends. Requested by Jeffrey Thalhammer. RT #77308. - Calling sugar methods like $dispatch->warn or $dispatch->crit did not normalize the log level, so the level would be passed to the outputs as "warn", not "warning". Reported by Karen Etheridge. RT #77203. 2.29 2011-03-18 - Add is_$level methods for compatibility with Log::Contextual. Patch by frew. 2.28 2010-12-13 - The Log::Dispatch module still had version 2.26 in the last release. Reported by Ƙyvind Skaar. RT #63876. 2.27 2010-10-16 - Fix docs on handling of arrays passed to ->debug, ->error, etc. Requested by Andrew Hanenkamp. RT #61400. - Allow an arrayref for the Syslog socket option. Requested by Paul Bennett. RT #57631. - License is now Artistic 2.0. 2.26 2009-09-22 - Doc updates. The 2.23 constructor API was still shown in all the output subclasses. Fixed by Jon Swartz. 2.25 2009-09-15 - Added a workaround for a weird tainting issue with Params::Validate. This caused a taint exception when a Log::Dispatch::Syslog was created under taint mode. Note that there is still a problem in Params::Validate itself, this is just a hack. 2.24 2009-09-13 - Simplified new constructor API (the 2.23 API is still silently supported but not documented): Log::Dispatch->new( outputs => [ [ 'File', ... ], [ 'Screen', ... ], ] ); Implemented by Jon Swartz. - All of the mail sending modules now warn unconditionally if sending mail fails. This removes the incorrect use of warnings::enabled() in some modules. RT #43516. 2.23 2009-09-12 - New constructor API that simplifies creating your Log::Dispatch object. Implemented by Jon Swartz. - Made name parameter optional. We now auto-generate a unique name if one is not given. Implemented by Jon Swartz. - Added a newline parameter that causes a newline to be added to each message, and updated the documentation regarding newlines. Implemented by Jon Swartz. - Removed repetitive boilerplate documentation from each output class. Implemented by Jon Swartz. - The level_names and level_numbers used internally are now computed once and shared between output objects. Implemented by Jon Swartz. - Updated repo url - now at http://hg.urth.org/hg/Log-Dispatch - Explicitly depend on Sys::Syslog 0.16. - Added warn as a synonym for warning. RT #44821. Requested by Dylan Martin. - Added an add_callback method to Log::Dispatch and Log::Dispatch::Output. This lets you add a new formatting callback after an object is created. Based on a patch from Ricardo Signes. RT #48283. - The Log::Dispatch docs mistakenly told you to provide a log() method when creating a new output class. RT #40561. - Made all modules have the same version as Log::Dispatch itself. 2.22 2008-11-11 - Fixed a bug where Log::Dispatch::Email would die when it tried to log under taint mode. Patch by Neil Hemingway. RT #40042. - Fixed a misuse of warnings::enabled(). Reported by Darian Patrick. RT #39784. - Syslog logging now requires Sys::Syslog 0.16+. - If you don't pass a socket argument to Log::Dispatch::Syslog, it does not call Sys::Syslog::setlogsock(), which is the preferred option for portability. * If any of the syslog calls die, this is trapped and the error is output as a warning if warnings are on. This is mostly a workaround for Sys::Sylog not handling utf-8. RT #35270 & #37397. This isn't backwards-compatible, but it's probably wrong for the logging code to die because it can't log (even though some other output modules still do). 2.21 2008-02-06 - Added log_and_die() and log_and_croak() methods. Patch by Yuval Kogman. 2.20 2007-11-02 - One of the tests failed on Perl 5.6.x. Thanks to Slaven Rezic for the report. 2.19 2007-11-01 - Switched to providing a traditional Makefile.PL as well as a Build.PL file. RT #27208. - When permissions are specified for a Log::Dispatch::File object, don't try to chmod the file unless the permissions of the file differ from what the file already has. Based on a patch by Kevin. RT #28151. - Require at least Perl 5.6.0. - Remove the tests for the email sending and exit codes, since the test had a heisenbug I could not understand. I _think_ the code in the email modules is correct, but the test isn't proving anything. - Added a binmode parameter for Log::Dispatch::File. Based on a patch by Angelo. RT #26063. 2.18 2007-05-12 - Log::Dispatch::ApacheLog should really now work under mod_perl 2, as well as mod_perl 1. RT #26910. 2.17 2007-03-31 - Log::Dispatch::ApacheLog should now work under mod_perl 2, as well as mod_perl 1. 2.16 2010-10-16 - Don't require IO::String for running the tests. Reported by Andreas Koenig. RT #23973. - Moved Test::More to build_requires. Suggested by Andreas Koenig. RT #23973. 2.15 2006-12-16 - Don't try to test compilation of L::D::Syslog unless Sys::Syslog is available. Patch by Kenichi Ishigaki. RT #23751. - Allow a subroutine reference as a log message when callin Log::Dispatch->log(). Suggested by Craig Manley. RT #23913. - Added Log::Dispatch::Null output, primarily for testing. 2.14 2006-11-18 This release only involves changes to the test suite. - Make sure we don't fail if Apache::Log is not installed on the system. RT #22791. Reported by Lee Goddard. - Separated out compilation tests from other tests. 2.13 2006-09-25 - No code changes, just added a SUPPORT section to the docs referring folks to RT for bug reports & patches. 2.12 2006-08-09 - The various email sending modules could overwrite if they were in buffered mode and they sent mail as a script exited. Reported by Dean Kopesky. - Doc tweaks. Make reference to "Log Levels" section in output module docs more explicit. RT #11224. 2.11 2005-07-27 - In tests, make sure filehandles are closed before reading or unlinking the file. Patch from Ron Savage. 2.10 2004-02-11 - No changes to the core code, just a change to the included Makefile.PL so it works with Module::Build 0.23, which breaks backwards compatibility (grr). - Fix a doc bug in Log::Dispatch::Syslog. It defaults to using a unix socket, not an inet socket. 2.09 2004-01-09 - Fix a test failure on Win32 platforms. The problem was in the test, not the code. Patch by David Viner. - Distro is now signed with Module::Signature. 2.08 2003-11-27 - Added Log::Dispatch->would_log method, which indicates whether logging will be done for a given log level. Suggested by Ruslan Zakirov. - Switched tests to use Test::More. 2.07 2003-09-27 - Added Log::Dispatch::File::Locked. Based on code from JAA Klunder. - Check all system call return values. - Fix warning from Log::Dispatch::File if it was loaded after Attribute::Handlers. Reported by Mike Schilli. - Fixed up POD to pass pod tests. 2.06 2003-05-01 "Arise ye workers from your slumbers Arise ye criminals of want For reason in revolt now thunders and at last ends the age of cant." - Added a permissions parameter to Log::Dispatch::File->new. Based on a patch from James FitzGibbon. 2.05 2003-04-18 - Changed a code construct that seems to provoke a bug for Meng Wong, but no one else ;) - Switched to Module::Build and removed interactive portion of installation process. - Log::Dispatch::Email::MailSender was causing Mail::Sender to send debug output to STDERR if warnings were on. Now it's not. 2.04 2003-03-21 - The close_after_write option didn't actually do anything. Fixed by JAA Klunder. 2.03 2003-02-27 - Log::Dispatch::ApacheLog would break if a log level was specified as a number. Reported by Kevin Goess. 2.02 2003-02-20 - Added close_after_write option to Log::Dispatch::File. Based on patch from JAA Klunder. 2.01 2002-06-21 - Added new module Log::Dispatch::Email::MailSender, provided by Joseph Annino. - Log::Dispatch::Output now contains "use Log::Dispatch". - Now requires Params::Validate, which is used to validate parameter for constructors and some other methods. - Add an 'autoflush' option to Log::Dispatch::File objects. Suggested by Jerrad Pierce. - Added some error checking to ::Email::MailSend. - Changed a carp to a warn in ::Email::MailSendmail. - Only warn if $^W is true. 2.00 2002-04-11 ** BACKWARDS INCOMPATIBILITY ALERT ** - Use a standard hash reference for objects instead of pseudo-hashes. ** THIS MAY BREAK EXISTING SUBCLASSES **. - Log::Dispatch::Screen claimed it defaulted to using STDERR but it was lying, it defaulted to using STDOUT. This has been changed so that it really does default to STDERR. Reported by James FitzGibbon. 1.80 2001-10-27 - Log::Dispatch::Syslog no longer requires syslog.ph for Perl >= 5.006. Patch by Benoit Beausejour. - If you passed a mode parameter to Log::Dispatch::File it always thought the mode was append, no matter what was passed. Patch from Luke Bakken. - Log::Dispatch::File no longer uses IO::File internally. 1.79 2001-05-15 - Don't use $, internally. Apparently this is usually undefined. Instead, the convenience methods now simply take an array of messages and turn it into a scalar by doing "@_". Thanks to Dean Kopesky for the bug report. 1.78 2001-04-19 - Allow ApacheLog to take either an Apache or Apache::Server object. - Fix callback documentation in Log::Dispatch::Output. Thanks to Rob Napier. - Add flush method to Log::Dispatch::Email. Patch submitted by Rob Napier. 1.77 2001-01-02 - The convenience methods named after the log levels ($log->debug, $log->alert, etc.) can now take a list of scalars. These are joined together just like Perl's print function does. Suggested by Tim Ayers. 1.76 2000-10-10 - New method: Log::Dispatch->level_is_valid($string). Suggested by Jeff Hamman. - Fix for version issues between CPAN versions of Log::Dispatch::ApacheLog. Reported by Jost Krieger. 1.75 2000-09-28 - Additional argument 'level' passed to message processing callbacks. Suggested by Jeff MacDonald. - Log/Dispatch.pm: added docs section on Log::Dispatch::Tk. 1.7 2000-08-30 - Added Log/Dispatch/ApacheLog.pm. This logs to the Apache error log. This is for use under mod_perl. 1.6 2000-07-04 NOTE: 1.5 was never released to CPAN. - Log/Dispatch.pm: Added convenience methods for log levels like $dispatcher->alert($message). Suggested by Dominique Dumont. - This version introduces some changes into the interface that will cause incompatibility with any Log::Dispatch::Output interface you may have created. However, it is fairly simple to fix. Simply change the method in your subclass named 'log' to be called 'log_message'. You can also remove the line: return unless $self->_should_log($params{level}); This is now done before the message ever gets to the Output subclass (which is what it should have done in the first place, really.) This was done so that I could allow per-Output object callbacks, a feature which several people have requested and which seems useful enough to warrant the breakage. NOTE: This change is transparent if you are only using the Output objects included with this distribution. - Many: Changed the interface to allow per-Output object level callbacks and documented this. - Log/Dispatch/Base.pm: new base class for both Log::Dispatch and Log::Dispatch::Output objects (contains callback related code). You should never need to deal with this class unless you are me. - Log/Dispatch/Output.pm: document _accepted_levels. - Log/Dispatch/Output.pm: Fix _accepted_levels so that emergency level is returned as 'emergency', not 'emerg'. - Log/Dispatch.pm: Fix doc bug (change 'file' to 'filename'). Thanks to Clayton Scott. - Log/Dispatch/File.pm: Do compile time check for O_APPEND constant rather than run time check. 1.2 2000-05-05 - Log/Dispatch.pm: Added callbacks parameter to Log::Dispatch->new. I will also be adding this to the Log::Dispatch::* classes via Log::Dispatch::Output but I wanted to get this new version out there because I think there are people out there who would benefit from this. - Log/Dispatch.pm: Added docs section on why Log::Dispatch doesn't add newlines to outgoing messages. 1.11 2000-02-24 - Realized I need to tweak the $VERSION in Log::Dispatch 1.1 2000-02-24 - Upped version to 1.1 to indicate my confidence in this release (I'm just asking for bug reports, I know). - Added accepted_levels method to Log::Dispatch::Output based on discussions with Dominique Dumont (author of the Log::Dispatch::Tk suite). - Canonical names for log levels are now the unabbreviated form (though the abbreviated ones used by syslog are still fine and there is no plan to deprecate them). This really only affects what is returned by the new accepted_levels method. 1.010 2000-01-17 - Fixed a bug in the DESTROY method of Log::Dispatch::Email that caused an annoying error and may have caused spurious emails to be sent (thanks to Radu Greab). - Fixed a bug in Log::Dispatch::Email::MailSendmail. For some reason this module demands a 'from' address. 1.009 2000-01-02 - Created this version simply to address an issue with CPAN and my internal version numbers having a conflict. This has no changes from 1.008. 1.008 1999-12-30 - Fixed a bug causing unitialized value warnings with -w (oops). - Fixed a minor mistake in Log::Dispatch::Syslog docs (thanks to Ilya Martynov) - Put newlines into messages in SYNOPSIS sections for some modules. This is to clarify that you need to do this. Just to be clear, Log::Dispatch does not alter message content in any manner whatsoever (and never will). However, it would be trivial to subclass Log::Dispatch to do this. 1.007 1999-12-01 - First public release. It passes its own test suite so it should work (he says hopefully). Log-Dispatch-2.67/README.md0000644000175000017500000003561313162076057015064 0ustar autarchautarch# NAME Log::Dispatch - Dispatches messages to one or more outputs # VERSION version 2.67 # SYNOPSIS use Log::Dispatch; # Simple API # my $log = Log::Dispatch->new( outputs => [ [ 'File', min_level => 'debug', filename => 'logfile' ], [ 'Screen', min_level => 'warning' ], ], ); $log->info('Blah, blah'); # More verbose API # my $log = Log::Dispatch->new(); $log->add( Log::Dispatch::File->new( name => 'file1', min_level => 'debug', filename => 'logfile' ) ); $log->add( Log::Dispatch::Screen->new( name => 'screen', min_level => 'warning', ) ); $log->log( level => 'info', message => 'Blah, blah' ); my $sub = sub { my %p = @_; return reverse $p{message}; }; my $reversing_dispatcher = Log::Dispatch->new( callbacks => $sub ); # DESCRIPTION This module manages a set of Log::Dispatch::\* output objects that can be logged to via a unified interface. The idea is that you create a Log::Dispatch object and then add various logging objects to it (such as a file logger or screen logger). Then you call the `log` method of the dispatch object, which passes the message to each of the objects, which in turn decide whether or not to accept the message and what to do with it. This makes it possible to call single method and send a message to a log file, via email, to the screen, and anywhere else, all with very little code needed on your part, once the dispatching object has been created. # METHODS This class provides the following methods: ## Log::Dispatch->new(...) This method takes the following parameters: - outputs( \[ \[ class, params, ... \], \[ class, params, ... \], ... \] ) This parameter is a reference to a list of lists. Each inner list consists of a class name and a set of constructor params. The class is automatically prefixed with 'Log::Dispatch::' unless it begins with '+', in which case the string following '+' is taken to be a full classname. e.g. outputs => [ [ 'File', min_level => 'debug', filename => 'logfile' ], [ '+My::Dispatch', min_level => 'info' ] ] For each inner list, a new output object is created and added to the dispatcher (via the `add()` method). See ["OUTPUT CLASSES"](#output-classes) for the parameters that can be used when creating an output object. - callbacks( \\& or \[ \\&, \\&, ... \] ) This parameter may be a single subroutine reference or an array reference of subroutine references. These callbacks will be called in the order they are given and passed a hash containing the following keys: ( message => $log_message, level => $log_level ) In addition, any key/value pairs passed to a logging method will be passed onto your callback. The callbacks are expected to modify the message and then return a single scalar containing that modified message. These callbacks will be called when either the `log` or `log_to` methods are called and will only be applied to a given message once. If they do not return the message then you will get no output. Make sure to return the message! ## $dispatch->clone() This returns a _shallow_ clone of the original object. The underlying output objects and callbacks are shared between the two objects. However any changes made to the outputs or callbacks that the object contains are not shared. ## $dispatch->log( level => $, message => $ or \\& ) Sends the message (at the appropriate level) to all the output objects that the dispatcher contains (by calling the `log_to` method repeatedly). The level can be specified by name or by an integer from 0 (debug) to 7 (emergency). This method also accepts a subroutine reference as the message argument. This reference will be called only if there is an output that will accept a message of the specified level. ## $dispatch->debug (message), info (message), ... You may call any valid log level (including valid abbreviations) as a method with a single argument that is the message to be logged. This is converted into a call to the `log` method with the appropriate level. For example: $log->alert('Strange data in incoming request'); translates to: $log->log( level => 'alert', message => 'Strange data in incoming request' ); If you pass an array to these methods, it will be stringified as is: my @array = ('Something', 'bad', 'is', 'here'); $log->alert(@array); # is equivalent to $log->alert("@array"); You can also pass a subroutine reference, just like passing one to the `log()` method. ## $dispatch->log\_and\_die( level => $, message => $ or \\& ) Has the same behavior as calling `log()` but calls `_die_with_message()` at the end. ## $dispatch->log\_and\_croak( level => $, message => $ or \\& ) This method adjusts the `$Carp::CarpLevel` scalar so that the croak comes from the context in which it is called. You can throw exception objects by subclassing this method. If the `carp_level` parameter is present its value will be added to the current value of `$Carp::CarpLevel`. ## $dispatch->log\_to( name => $, level => $, message => $ ) Sends the message only to the named object. Note: this will not properly handle a subroutine reference as the message. ## $dispatch->add\_callback( $code ) Adds a callback (like those given during construction). It is added to the end of the list of callbacks. Note that this can also be called on individual output objects. ## $dispatch->remove\_callback( $code ) Remove the given callback from the list of callbacks. Note that this can also be called on individual output objects. ## $dispatch->callbacks() Returns a list of the callbacks in a given output. ## $dispatch->level\_is\_valid( $string ) Returns true or false to indicate whether or not the given string is a valid log level. Can be called as either a class or object method. ## $dispatch->would\_log( $string ) Given a log level, returns true or false to indicate whether or not anything would be logged for that log level. ## $dispatch->is\_`$level` There are methods for every log level: `is_debug()`, `is_warning()`, etc. This returns true if the logger will log a message at the given level. ## $dispatch->add( Log::Dispatch::\* OBJECT ) Adds a new [output object](#output-classes) to the dispatcher. If an object of the same name already exists, then that object is replaced, with a warning if `$^W` is true. ## $dispatch->remove($) Removes the output object that matches the name given to the remove method. The return value is the object being removed or undef if no object matched this. ## $dispatch->outputs() Returns a list of output objects. ## $dispatch->output( $name ) Returns the output object of the given name. Returns undef or an empty list, depending on context, if the given output does not exist. ## $dispatch->\_die\_with\_message( message => $, carp\_level => $ ) This method is used by `log_and_die` and will either die() or croak() depending on the value of `message`: if it's a reference or it ends with a new line then a plain die will be used, otherwise it will croak. # OUTPUT CLASSES An output class - e.g. [Log::Dispatch::File](https://metacpan.org/pod/Log::Dispatch::File) or [Log::Dispatch::Screen](https://metacpan.org/pod/Log::Dispatch::Screen) - implements a particular way of dispatching logs. Many output classes come with this distribution, and others are available separately on CPAN. The following common parameters can be used when creating an output class. All are optional. Most output classes will have additional parameters beyond these, see their documentation for details. - name ($) A name for the object (not the filename!). This is useful if you want to refer to the object later, e.g. to log specifically to it or remove it. By default a unique name will be generated. You should not depend on the form of generated names, as they may change. - min\_level ($) The minimum [logging level](#log-levels) this object will accept. Required. - max\_level ($) The maximum [logging level](#log-levels) this object will accept. By default the maximum is the highest possible level (which means functionally that the object has no maximum). - callbacks( \\& or \[ \\&, \\&, ... \] ) This parameter may be a single subroutine reference or an array reference of subroutine references. These callbacks will be called in the order they are given and passed a hash containing the following keys: ( message => $log_message, level => $log_level ) The callbacks are expected to modify the message and then return a single scalar containing that modified message. These callbacks will be called when either the `log` or `log_to` methods are called and will only be applied to a given message once. If they do not return the message then you will get no output. Make sure to return the message! - newline (0|1) If true, a callback will be added to the end of the callbacks list that adds a newline to the end of each message. Default is false, but some output classes may decide to make the default true. # LOG LEVELS The log levels that Log::Dispatch uses are taken directly from the syslog man pages (except that I expanded them to full words). Valid levels are: - debug - info - notice - warning - error - critical - alert - emergency Alternately, the numbers 0 through 7 may be used (debug is 0 and emergency is 7). The syslog standard of 'err', 'crit', and 'emerg' is also acceptable. We also allow 'warn' as a synonym for 'warning'. # SUBCLASSING This module was designed to be easy to subclass. If you want to handle messaging in a way not implemented in this package, you should be able to add this with minimal effort. It is generally as simple as subclassing Log::Dispatch::Output and overriding the `new` and `log_message` methods. See the [Log::Dispatch::Output](https://metacpan.org/pod/Log::Dispatch::Output) docs for more details. If you would like to create your own subclass for sending email then it is even simpler. Simply subclass [Log::Dispatch::Email](https://metacpan.org/pod/Log::Dispatch::Email) and override the `send_email` method. See the [Log::Dispatch::Email](https://metacpan.org/pod/Log::Dispatch::Email) docs for more details. The logging levels that Log::Dispatch uses are borrowed from the standard UNIX syslog levels, except that where syslog uses partial words ("err") Log::Dispatch also allows the use of the full word as well ("error"). # RELATED MODULES ## Log::Dispatch::DBI Written by Tatsuhiko Miyagawa. Log output to a database table. ## Log::Dispatch::FileRotate Written by Mark Pfeiffer. Rotates log files periodically as part of its usage. ## Log::Dispatch::File::Stamped Written by Eric Cholet. Stamps log files with date and time information. ## Log::Dispatch::Jabber Written by Aaron Straup Cope. Logs messages via Jabber. ## Log::Dispatch::Tk Written by Dominique Dumont. Logs messages to a Tk window. ## Log::Dispatch::Win32EventLog Written by Arthur Bergman. Logs messages to the Windows event log. ## Log::Log4perl An implementation of Java's log4j API in Perl. Log messages can be limited by fine-grained controls, and if they end up being logged, both native Log4perl and Log::Dispatch appenders can be used to perform the actual logging job. Created by Mike Schilli and Kevin Goess. ## Log::Dispatch::Config Written by Tatsuhiko Miyagawa. Allows configuration of logging via a text file similar (or so I'm told) to how it is done with log4j. Simpler than Log::Log4perl. ## Log::Agent A very different API for doing many of the same things that Log::Dispatch does. Originally written by Raphael Manfredi. # SEE ALSO [Log::Dispatch::ApacheLog](https://metacpan.org/pod/Log::Dispatch::ApacheLog), [Log::Dispatch::Email](https://metacpan.org/pod/Log::Dispatch::Email), [Log::Dispatch::Email::MailSend](https://metacpan.org/pod/Log::Dispatch::Email::MailSend), [Log::Dispatch::Email::MailSender](https://metacpan.org/pod/Log::Dispatch::Email::MailSender), [Log::Dispatch::Email::MailSendmail](https://metacpan.org/pod/Log::Dispatch::Email::MailSendmail), [Log::Dispatch::Email::MIMELite](https://metacpan.org/pod/Log::Dispatch::Email::MIMELite), [Log::Dispatch::File](https://metacpan.org/pod/Log::Dispatch::File), [Log::Dispatch::File::Locked](https://metacpan.org/pod/Log::Dispatch::File::Locked), [Log::Dispatch::Handle](https://metacpan.org/pod/Log::Dispatch::Handle), [Log::Dispatch::Output](https://metacpan.org/pod/Log::Dispatch::Output), [Log::Dispatch::Screen](https://metacpan.org/pod/Log::Dispatch::Screen), [Log::Dispatch::Syslog](https://metacpan.org/pod/Log::Dispatch::Syslog) # SUPPORT Bugs may be submitted at [https://github.com/houseabsolute/Log-Dispatch/issues](https://github.com/houseabsolute/Log-Dispatch/issues). I am also usually active on IRC as 'autarch' on `irc://irc.perl.org`. # SOURCE The source code repository for Log-Dispatch can be found at [https://github.com/houseabsolute/Log-Dispatch](https://github.com/houseabsolute/Log-Dispatch). # DONATIONS If you'd like to thank me for the work I've done on this module, please consider making a "donation" to me via PayPal. I spend a lot of free time creating free software, and would appreciate any support you'd care to offer. Please note that **I am not suggesting that you must do this** in order for me to continue working on this particular software. I will continue to do so, inasmuch as I have in the past, for as long as it interests me. Similarly, a donation made in this way will probably not make me work on this software much more, unless I get so many donations that I can consider working on free software full time (let's all have a chuckle at that together). To donate, log into PayPal and send money to autarch@urth.org, or use the button at [http://www.urth.org/~autarch/fs-donation.html](http://www.urth.org/~autarch/fs-donation.html). # AUTHOR Dave Rolsky # CONTRIBUTORS - Anirvan Chatterjee - Carsten Grohmann - Doug Bell - Graham Ollis - Gregory Oschwald - Johann Rolschewski - Jonathan Swartz - Karen Etheridge - Kerin Millar - Kivanc Yazan - Konrad Bucheli - Michael Schout - Olaf Alders - Olivier MenguĆ© - Rohan Carly - Ross Attrill - Salvador FandiƱo - Slaven Rezic - Steve Bertrand - Whitney Jackson # COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the `LICENSE` file included with this distribution. Log-Dispatch-2.67/MANIFEST0000644000175000017500000000256613162076057014737 0ustar autarchautarch# This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.010. CONTRIBUTING.md Changes INSTALL LICENSE MANIFEST META.json META.yml Makefile.PL README.md appveyor.yml cpanfile dist.ini lib/Log/Dispatch.pm lib/Log/Dispatch/ApacheLog.pm lib/Log/Dispatch/Base.pm lib/Log/Dispatch/Code.pm lib/Log/Dispatch/Conflicts.pm lib/Log/Dispatch/Email.pm lib/Log/Dispatch/Email/MIMELite.pm lib/Log/Dispatch/Email/MailSend.pm lib/Log/Dispatch/Email/MailSender.pm lib/Log/Dispatch/Email/MailSendmail.pm lib/Log/Dispatch/File.pm lib/Log/Dispatch/File/Locked.pm lib/Log/Dispatch/Handle.pm lib/Log/Dispatch/Null.pm lib/Log/Dispatch/Output.pm lib/Log/Dispatch/Screen.pm lib/Log/Dispatch/Syslog.pm lib/Log/Dispatch/Types.pm lib/Log/Dispatch/Vars.pm perlcriticrc perltidyrc t/00-compile.t t/00-report-prereqs.dd t/00-report-prereqs.t t/basic.t t/binmode.t t/close-after-write.t t/email-exit-helper.pl t/email-exit.t t/file-locked.t t/lazy-open.t t/lib/Log/Dispatch/TestUtil.pm t/screen-helper.pl t/screen.t t/sendmail t/short-syntax.t t/syslog-lock-without-preloaded-threads.t t/syslog-threads.t t/syslog.t tidyall.ini weaver.ini xt/author/eol.t xt/author/mojibake.t xt/author/no-tabs.t xt/author/pod-coverage.t xt/author/pod-spell.t xt/author/pod-syntax.t xt/author/portability.t xt/author/test-dependents.t xt/author/test-version.t xt/author/tidyall.t xt/release/cpan-changes.t xt/release/meta-json.t Log-Dispatch-2.67/CONTRIBUTING.md0000644000175000017500000001006413162076057016027 0ustar autarchautarch# CONTRIBUTING Thank you for considering contributing to this distribution. This file contains instructions that will help you work with the source code. Please note that if you have any questions or difficulties, you can reach the maintainer(s) through the bug queue described later in this document (preferred), or by emailing the releaser directly. You are not required to follow any of the steps in this document to submit a patch or bug report; these are just recommendations, intended to help you (and help us help you faster). The distribution is managed with [Dist::Zilla](https://metacpan.org/release/Dist-Zilla). However, you can still compile and test the code with the `Makefile.PL` or `Build.PL` in the repository: perl Makefile.PL make make test or perl Build.PL ./Build ./Build test As well as: $ prove -bvr t or $ perl -Mblib t/some_test_file.t You may need to satisfy some dependencies. The easiest way to satisfy dependencies is to install the last release. This is available at https://metacpan.org/release/Log-Dispatch If you use cpanminus, you can do it without downloading the tarball first: $ cpanm --reinstall --installdeps --with-recommends Log::Dispatch Dist::Zilla is a very powerful authoring tool, but requires a number of author-specific plugins. If you would like to use it for contributing, install it from CPAN, then run one of the following commands, depending on your CPAN client: $ cpan `dzil authordeps --missing` or $ dzil authordeps --missing | cpanm They may also be additional requirements not needed by the dzil build which are needed for tests or other development: $ cpan `dzil listdeps --author --missing` or $ dzil listdeps --author --missing | cpanm Or, you can use the 'dzil stale' command to install all requirements at once: $ cpan Dist::Zilla::App::Command::stale $ cpan `dzil stale --all` or $ cpanm Dist::Zilla::App::Command::stale $ dzil stale --all | cpanm You can also do this via cpanm directly: $ cpanm --reinstall --installdeps --with-develop --with-recommends Log::Dispatch Once installed, here are some dzil commands you might try: $ dzil build $ dzil test $ dzil test --release $ dzil xtest $ dzil listdeps --json $ dzil build --notgz You can learn more about Dist::Zilla at http://dzil.org/. The code for this distribution is [hosted at GitHub](https://github.com/houseabsolute/Log-Dispatch). You can submit code changes by forking the repository, pushing your code changes to your clone, and then submitting a pull request. Detailed instructions for doing that is available here: https://help.github.com/articles/creating-a-pull-request If you have found a bug, but do not have an accompanying patch to fix it, you can submit an issue report [via the web](https://github.com/houseabsolute/Log-Dispatch/issues) ). This is a good place to send your questions about the usage of this distribution. ## Travis All pull requests for this distribution will be automatically tested by [Travis](https://travis-ci.org/) and the build status will be reported on the pull request page. If your build fails, please take a look at the output. ## TidyAll This distribution uses [Code::TidyAll](https://metacpan.org/release/Code-TidyAll) to enforce a uniform coding style. This is tested as part of the author testing suite. You can install and run tidyall by running the following commands: $ cpanm Code::TidyAll $ tidyall -a Please run this before committing your changes and address any issues it brings up. ## Contributor Names If you send a patch or pull request, your name and email address will be included in the documentation as a contributor (using the attribution on the commit or patch), unless you specifically request for it not to be. If you wish to be listed under a different name or address, you should submit a pull request to the .mailmap file to contain the correct mapping. This file was generated via Dist::Zilla::Plugin::GenerateFile::FromShareDir 0.013 from a template file originating in Dist-Zilla-PluginBundle-DROLSKY-0.85. Log-Dispatch-2.67/cpanfile0000644000175000017500000000516713162076057015312 0ustar autarchautarchrequires "Carp" => "0"; requires "Devel::GlobalDestruction" => "0"; requires "Dist::CheckConflicts" => "0.02"; requires "Encode" => "0"; requires "Exporter" => "0"; requires "Fcntl" => "0"; requires "IO::Handle" => "0"; requires "Module::Runtime" => "0"; requires "Params::ValidationCompiler" => "0"; requires "Scalar::Util" => "0"; requires "Specio" => "0.32"; requires "Specio::Declare" => "0"; requires "Specio::Exporter" => "0"; requires "Specio::Library::Builtins" => "0"; requires "Specio::Library::Numeric" => "0"; requires "Specio::Library::String" => "0"; requires "Sys::Syslog" => "0.28"; requires "Try::Tiny" => "0"; requires "base" => "0"; requires "namespace::autoclean" => "0"; requires "parent" => "0"; requires "perl" => "5.006"; requires "strict" => "0"; requires "warnings" => "0"; on 'test' => sub { requires "Data::Dumper" => "0"; requires "ExtUtils::MakeMaker" => "0"; requires "File::Spec" => "0"; requires "File::Temp" => "0"; requires "FindBin" => "0"; requires "Getopt::Long" => "0"; requires "IO::File" => "0"; requires "IPC::Run3" => "0"; requires "POSIX" => "0"; requires "PerlIO" => "0"; requires "Test::Fatal" => "0"; requires "Test::More" => "0.96"; requires "Test::Needs" => "0"; requires "lib" => "0"; requires "utf8" => "0"; }; on 'test' => sub { recommends "CPAN::Meta" => "2.120900"; }; on 'configure' => sub { requires "Dist::CheckConflicts" => "0.02"; requires "ExtUtils::MakeMaker" => "0"; }; on 'configure' => sub { suggests "JSON::PP" => "2.27300"; }; on 'develop' => sub { requires "Code::TidyAll" => "0.56"; requires "Code::TidyAll::Plugin::SortLines::Naturally" => "0.000003"; requires "Code::TidyAll::Plugin::Test::Vars" => "0.02"; requires "Cwd" => "0"; requires "MIME::Lite" => "0"; requires "Mail::Send" => "0"; requires "Mail::Sender" => "0"; requires "Mail::Sendmail" => "0"; requires "Parallel::ForkManager" => "1.19"; requires "Perl::Critic" => "1.126"; requires "Perl::Tidy" => "20160302"; requires "Pod::Coverage::TrustPod" => "0"; requires "Pod::Wordlist" => "0"; requires "Test::CPAN::Changes" => "0.19"; requires "Test::CPAN::Meta::JSON" => "0.16"; requires "Test::Code::TidyAll" => "0.50"; requires "Test::DependentModules" => "0.22"; requires "Test::EOL" => "0"; requires "Test::Mojibake" => "0"; requires "Test::More" => "0.96"; requires "Test::Needs" => "0"; requires "Test::NoTabs" => "0"; requires "Test::Pod" => "1.41"; requires "Test::Pod::Coverage" => "1.08"; requires "Test::Portability::Files" => "0"; requires "Test::Spelling" => "0.12"; requires "Test::Vars" => "0.009"; requires "Test::Version" => "2.05"; }; Log-Dispatch-2.67/LICENSE0000644000175000017500000002152013162076057014602 0ustar autarchautarchThis software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The Artistic License 2.0 Copyright (c) 2000-2006, The Perl Foundation. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble This license establishes the terms under which a given free software Package may be copied, modified, distributed, and/or redistributed. The intent is that the Copyright Holder maintains some artistic control over the development of that Package while still keeping the Package available as open source and free software. You are always permitted to make arrangements wholly outside of this license directly with the Copyright Holder of a given Package. If the terms of this license do not permit the full use that you propose to make of the Package, you should contact the Copyright Holder and seek a different licensing arrangement. Definitions "Copyright Holder" means the individual(s) or organization(s) named in the copyright notice for the entire Package. "Contributor" means any party that has contributed code or other material to the Package, in accordance with the Copyright Holder's procedures. "You" and "your" means any person who would like to copy, distribute, or modify the Package. "Package" means the collection of files distributed by the Copyright Holder, and derivatives of that collection and/or of those files. A given Package may consist of either the Standard Version, or a Modified Version. "Distribute" means providing a copy of the Package or making it accessible to anyone else, or in the case of a company or organization, to others outside of your company or organization. "Distributor Fee" means any fee that you charge for Distributing this Package or providing support for this Package to another party. It does not mean licensing fees. "Standard Version" refers to the Package if it has not been modified, or has been modified only in ways explicitly requested by the Copyright Holder. "Modified Version" means the Package, if it has been changed, and such changes were not explicitly requested by the Copyright Holder. "Original License" means this Artistic License as Distributed with the Standard Version of the Package, in its current version or as it may be modified by The Perl Foundation in the future. "Source" form means the source code, documentation source, and configuration files for the Package. "Compiled" form means the compiled bytecode, object code, binary, or any other form resulting from mechanical transformation or translation of the Source form. Permission for Use and Modification Without Distribution (1) You are permitted to use the Standard Version and create and use Modified Versions for any purpose without restriction, provided that you do not Distribute the Modified Version. Permissions for Redistribution of the Standard Version (2) You may Distribute verbatim copies of the Source form of the Standard Version of this Package in any medium without restriction, either gratis or for a Distributor Fee, provided that you duplicate all of the original copyright notices and associated disclaimers. At your discretion, such verbatim copies may or may not include a Compiled form of the Package. (3) You may apply any bug fixes, portability changes, and other modifications made available from the Copyright Holder. The resulting Package will still be considered the Standard Version, and as such will be subject to the Original License. Distribution of Modified Versions of the Package as Source (4) You may Distribute your Modified Version as Source (either gratis or for a Distributor Fee, and with or without a Compiled form of the Modified Version) provided that you clearly document how it differs from the Standard Version, including, but not limited to, documenting any non-standard features, executables, or modules, and provided that you do at least ONE of the following: (a) make the Modified Version available to the Copyright Holder of the Standard Version, under the Original License, so that the Copyright Holder may include your modifications in the Standard Version. (b) ensure that installation of your Modified Version does not prevent the user installing or running the Standard Version. In addition, the Modified Version must bear a name that is different from the name of the Standard Version. (c) allow anyone who receives a copy of the Modified Version to make the Source form of the Modified Version available to others under (i) the Original License or (ii) a license that permits the licensee to freely copy, modify and redistribute the Modified Version using the same licensing terms that apply to the copy that the licensee received, and requires that the Source form of the Modified Version, and of any works derived from it, be made freely available in that license fees are prohibited but Distributor Fees are allowed. Distribution of Compiled Forms of the Standard Version or Modified Versions without the Source (5) You may Distribute Compiled forms of the Standard Version without the Source, provided that you include complete instructions on how to get the Source of the Standard Version. Such instructions must be valid at the time of your distribution. If these instructions, at any time while you are carrying out such distribution, become invalid, you must provide new instructions on demand or cease further distribution. If you provide valid instructions or cease distribution within thirty days after you become aware that the instructions are invalid, then you do not forfeit any of your rights under this license. (6) You may Distribute a Modified Version in Compiled form without the Source, provided that you comply with Section 4 with respect to the Source of the Modified Version. Aggregating or Linking the Package (7) You may aggregate the Package (either the Standard Version or Modified Version) with other packages and Distribute the resulting aggregation provided that you do not charge a licensing fee for the Package. Distributor Fees are permitted, and licensing fees for other components in the aggregation are permitted. The terms of this license apply to the use and Distribution of the Standard or Modified Versions as included in the aggregation. (8) You are permitted to link Modified and Standard Versions with other works, to embed the Package in a larger work of your own, or to build stand-alone binary or bytecode versions of applications that include the Package, and Distribute the result without restriction, provided the result does not expose a direct interface to the Package. Items That are Not Considered Part of a Modified Version (9) Works (including, but not limited to, modules and scripts) that merely extend or make use of the Package, do not, by themselves, cause the Package to be a Modified Version. In addition, such works are not considered parts of the Package itself, and are not subject to the terms of this license. General Provisions (10) Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license. (11) If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license. (12) This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder. (13) This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed. (14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Log-Dispatch-2.67/META.json0000644000175000017500000011440713162076057015225 0ustar autarchautarch{ "abstract" : "Dispatches messages to one or more outputs", "author" : [ "Dave Rolsky " ], "dynamic_config" : 0, "generated_by" : "Dist::Zilla version 6.010, CPAN::Meta::Converter version 2.150010", "license" : [ "artistic_2" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Log-Dispatch", "prereqs" : { "configure" : { "requires" : { "Dist::CheckConflicts" : "0.02", "ExtUtils::MakeMaker" : "0" }, "suggests" : { "JSON::PP" : "2.27300" } }, "develop" : { "requires" : { "Code::TidyAll" : "0.56", "Code::TidyAll::Plugin::SortLines::Naturally" : "0.000003", "Code::TidyAll::Plugin::Test::Vars" : "0.02", "Cwd" : "0", "MIME::Lite" : "0", "Mail::Send" : "0", "Mail::Sender" : "0", "Mail::Sendmail" : "0", "Parallel::ForkManager" : "1.19", "Perl::Critic" : "1.126", "Perl::Tidy" : "20160302", "Pod::Coverage::TrustPod" : "0", "Pod::Wordlist" : "0", "Test::CPAN::Changes" : "0.19", "Test::CPAN::Meta::JSON" : "0.16", "Test::Code::TidyAll" : "0.50", "Test::DependentModules" : "0.22", "Test::EOL" : "0", "Test::Mojibake" : "0", "Test::More" : "0.96", "Test::Needs" : "0", "Test::NoTabs" : "0", "Test::Pod" : "1.41", "Test::Pod::Coverage" : "1.08", "Test::Portability::Files" : "0", "Test::Spelling" : "0.12", "Test::Vars" : "0.009", "Test::Version" : "2.05" } }, "runtime" : { "requires" : { "Carp" : "0", "Devel::GlobalDestruction" : "0", "Dist::CheckConflicts" : "0.02", "Encode" : "0", "Exporter" : "0", "Fcntl" : "0", "IO::Handle" : "0", "Module::Runtime" : "0", "Params::ValidationCompiler" : "0", "Scalar::Util" : "0", "Specio" : "0.32", "Specio::Declare" : "0", "Specio::Exporter" : "0", "Specio::Library::Builtins" : "0", "Specio::Library::Numeric" : "0", "Specio::Library::String" : "0", "Sys::Syslog" : "0.28", "Try::Tiny" : "0", "base" : "0", "namespace::autoclean" : "0", "parent" : "0", "perl" : "5.006", "strict" : "0", "warnings" : "0" } }, "test" : { "recommends" : { "CPAN::Meta" : "2.120900" }, "requires" : { "Data::Dumper" : "0", "ExtUtils::MakeMaker" : "0", "File::Spec" : "0", "File::Temp" : "0", "FindBin" : "0", "Getopt::Long" : "0", "IO::File" : "0", "IPC::Run3" : "0", "POSIX" : "0", "PerlIO" : "0", "Test::Fatal" : "0", "Test::More" : "0.96", "Test::Needs" : "0", "lib" : "0", "utf8" : "0" } } }, "provides" : { "Log::Dispatch" : { "file" : "lib/Log/Dispatch.pm", "version" : "2.67" }, "Log::Dispatch::ApacheLog" : { "file" : "lib/Log/Dispatch/ApacheLog.pm", "version" : "2.67" }, "Log::Dispatch::Base" : { "file" : "lib/Log/Dispatch/Base.pm", "version" : "2.67" }, "Log::Dispatch::Code" : { "file" : "lib/Log/Dispatch/Code.pm", "version" : "2.67" }, "Log::Dispatch::Email" : { "file" : "lib/Log/Dispatch/Email.pm", "version" : "2.67" }, "Log::Dispatch::Email::MIMELite" : { "file" : "lib/Log/Dispatch/Email/MIMELite.pm", "version" : "2.67" }, "Log::Dispatch::Email::MailSend" : { "file" : "lib/Log/Dispatch/Email/MailSend.pm", "version" : "2.67" }, "Log::Dispatch::Email::MailSender" : { "file" : "lib/Log/Dispatch/Email/MailSender.pm", "version" : "2.67" }, "Log::Dispatch::Email::MailSendmail" : { "file" : "lib/Log/Dispatch/Email/MailSendmail.pm", "version" : "2.67" }, "Log::Dispatch::File" : { "file" : "lib/Log/Dispatch/File.pm", "version" : "2.67" }, "Log::Dispatch::File::Locked" : { "file" : "lib/Log/Dispatch/File/Locked.pm", "version" : "2.67" }, "Log::Dispatch::Handle" : { "file" : "lib/Log/Dispatch/Handle.pm", "version" : "2.67" }, "Log::Dispatch::Null" : { "file" : "lib/Log/Dispatch/Null.pm", "version" : "2.67" }, "Log::Dispatch::Output" : { "file" : "lib/Log/Dispatch/Output.pm", "version" : "2.67" }, "Log::Dispatch::Screen" : { "file" : "lib/Log/Dispatch/Screen.pm", "version" : "2.67" }, "Log::Dispatch::Syslog" : { "file" : "lib/Log/Dispatch/Syslog.pm", "version" : "2.67" }, "Log::Dispatch::Types" : { "file" : "lib/Log/Dispatch/Types.pm", "version" : "2.67" }, "Log::Dispatch::Vars" : { "file" : "lib/Log/Dispatch/Vars.pm", "version" : "2.67" } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/houseabsolute/Log-Dispatch/issues" }, "homepage" : "http://metacpan.org/release/Log-Dispatch", "repository" : { "type" : "git", "url" : "git://github.com/houseabsolute/Log-Dispatch.git", "web" : "https://github.com/houseabsolute/Log-Dispatch" } }, "version" : "2.67", "x_Dist_Zilla" : { "perl" : { "version" : "5.024001" }, "plugins" : [ { "class" : "Dist::Zilla::Plugin::MakeMaker", "config" : { "Dist::Zilla::Role::TestRunner" : { "default_jobs" : 1 } }, "name" : "@DROLSKY/MakeMaker", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::Git::GatherDir", "config" : { "Dist::Zilla::Plugin::GatherDir" : { "exclude_filename" : [ "CONTRIBUTING.md", "LICENSE", "Makefile.PL", "README.md", "cpanfile" ], "exclude_match" : [], "follow_symlinks" : 0, "include_dotfiles" : 0, "prefix" : "", "prune_directory" : [], "root" : "." }, "Dist::Zilla::Plugin::Git::GatherDir" : { "include_untracked" : 0 } }, "name" : "@DROLSKY/Git::GatherDir", "version" : "2.042" }, { "class" : "Dist::Zilla::Plugin::ManifestSkip", "name" : "@DROLSKY/ManifestSkip", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::License", "name" : "@DROLSKY/License", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::ExecDir", "name" : "@DROLSKY/ExecDir", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::ShareDir", "name" : "@DROLSKY/ShareDir", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::Manifest", "name" : "@DROLSKY/Manifest", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::CheckVersionIncrement", "name" : "@DROLSKY/CheckVersionIncrement", "version" : "0.121750" }, { "class" : "Dist::Zilla::Plugin::TestRelease", "name" : "@DROLSKY/TestRelease", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::ConfirmRelease", "name" : "@DROLSKY/ConfirmRelease", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::UploadToCPAN", "name" : "@DROLSKY/UploadToCPAN", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::VersionFromMainModule", "name" : "@DROLSKY/VersionFromMainModule", "version" : "0.03" }, { "class" : "Dist::Zilla::Plugin::Authority", "name" : "@DROLSKY/Authority", "version" : "1.009" }, { "class" : "Dist::Zilla::Plugin::AutoPrereqs", "name" : "@DROLSKY/AutoPrereqs", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::CopyFilesFromBuild", "name" : "@DROLSKY/CopyFilesFromBuild", "version" : "0.170880" }, { "class" : "Dist::Zilla::Plugin::GitHub::Meta", "name" : "@DROLSKY/GitHub::Meta", "version" : "0.44" }, { "class" : "Dist::Zilla::Plugin::GitHub::Update", "config" : { "Dist::Zilla::Plugin::GitHub::Update" : { "metacpan" : 1 } }, "name" : "@DROLSKY/GitHub::Update", "version" : "0.44" }, { "class" : "Dist::Zilla::Plugin::MetaResources", "name" : "@DROLSKY/MetaResources", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::MetaProvides::Package", "config" : { "Dist::Zilla::Plugin::MetaProvides::Package" : { "finder_objects" : [ { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : "@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM", "version" : "6.010" } ], "include_underscores" : 0 }, "Dist::Zilla::Role::MetaProvider::Provider" : { "$Dist::Zilla::Role::MetaProvider::Provider::VERSION" : "2.002004", "inherit_missing" : 1, "inherit_version" : 1, "meta_noindex" : 1 }, "Dist::Zilla::Role::ModuleMetadata" : { "Module::Metadata" : "1.000033", "version" : "0.004" } }, "name" : "@DROLSKY/MetaProvides::Package", "version" : "2.004003" }, { "class" : "Dist::Zilla::Plugin::Meta::Contributors", "name" : "@DROLSKY/Meta::Contributors", "version" : "0.003" }, { "class" : "Dist::Zilla::Plugin::MetaConfig", "name" : "@DROLSKY/MetaConfig", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::MetaJSON", "name" : "@DROLSKY/MetaJSON", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::MetaYAML", "name" : "@DROLSKY/MetaYAML", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::NextRelease", "name" : "@DROLSKY/NextRelease", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "test", "type" : "requires" } }, "name" : "@DROLSKY/Test::More with subtest", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "develop", "type" : "requires" } }, "name" : "@DROLSKY/Modules for use with tidyall", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "develop", "type" : "requires" } }, "name" : "@DROLSKY/Test::Version which fixes https://github.com/plicease/Test-Version/issues/7", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::PromptIfStale", "config" : { "Dist::Zilla::Plugin::PromptIfStale" : { "check_all_plugins" : 0, "check_all_prereqs" : 0, "modules" : [ "Dist::Zilla::PluginBundle::DROLSKY" ], "phase" : "build", "run_under_travis" : 0, "skip" : [] } }, "name" : "@DROLSKY/Dist::Zilla::PluginBundle::DROLSKY", "version" : "0.054" }, { "class" : "Dist::Zilla::Plugin::PromptIfStale", "config" : { "Dist::Zilla::Plugin::PromptIfStale" : { "check_all_plugins" : 1, "check_all_prereqs" : 1, "modules" : [], "phase" : "release", "run_under_travis" : 0, "skip" : [ "Dist::Zilla::Plugin::DROLSKY::Contributors", "Dist::Zilla::Plugin::DROLSKY::Git::CheckFor::CorrectBranch", "Dist::Zilla::Plugin::DROLSKY::License", "Dist::Zilla::Plugin::DROLSKY::TidyAll", "Dist::Zilla::Plugin::DROLSKY::WeaverConfig", "Pod::Weaver::PluginBundle::DROLSKY" ] } }, "name" : "@DROLSKY/PromptIfStale", "version" : "0.054" }, { "class" : "Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable", "name" : "@DROLSKY/Test::Pod::Coverage::Configurable", "version" : "0.06" }, { "class" : "Dist::Zilla::Plugin::Test::PodSpelling", "config" : { "Dist::Zilla::Plugin::Test::PodSpelling" : { "directories" : [ "bin", "lib" ], "spell_cmd" : "", "stopwords" : [ "API", "CPAN", "Cholet", "DROLSKY", "DROLSKY's", "Dumont", "Goess", "Manfredi", "Miyagawa", "NTLM", "PayPal", "PayPal", "Pfeiffer", "Rolsky", "Rolsky's", "STDERR", "STDOUT", "Schilli", "Straup", "Subclasses", "Swartz", "TLS", "Tatsuhiko", "UTF", "apache", "appenders", "auth", "authid", "authpriv", "authpwd", "autoflushed", "classname", "crit", "drolsky", "emerg", "fd", "filename", "ident", "kern", "logopt", "multi", "params", "replyto", "smtp", "stderr", "subclass's", "subclasses", "uucp" ], "wordlist" : "Pod::Wordlist" } }, "name" : "@DROLSKY/Test::PodSpelling", "version" : "2.007004" }, { "class" : "Dist::Zilla::Plugin::PodSyntaxTests", "name" : "@DROLSKY/PodSyntaxTests", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::RunExtraTests", "config" : { "Dist::Zilla::Role::TestRunner" : { "default_jobs" : 1 } }, "name" : "@DROLSKY/RunExtraTests", "version" : "0.029" }, { "class" : "Dist::Zilla::Plugin::MojibakeTests", "name" : "@DROLSKY/MojibakeTests", "version" : "0.8" }, { "class" : "Dist::Zilla::Plugin::Test::CPAN::Changes", "config" : { "Dist::Zilla::Plugin::Test::CPAN::Changes" : { "changelog" : "Changes" } }, "name" : "@DROLSKY/Test::CPAN::Changes", "version" : "0.012" }, { "class" : "Dist::Zilla::Plugin::Test::CPAN::Meta::JSON", "name" : "@DROLSKY/Test::CPAN::Meta::JSON", "version" : "0.004" }, { "class" : "Dist::Zilla::Plugin::Test::EOL", "config" : { "Dist::Zilla::Plugin::Test::EOL" : { "filename" : "xt/author/eol.t", "finder" : [ ":ExecFiles", ":InstallModules", ":TestFiles" ], "trailing_whitespace" : 1 } }, "name" : "@DROLSKY/Test::EOL", "version" : "0.19" }, { "class" : "Dist::Zilla::Plugin::Test::NoTabs", "config" : { "Dist::Zilla::Plugin::Test::NoTabs" : { "filename" : "xt/author/no-tabs.t", "finder" : [ ":InstallModules", ":ExecFiles", ":TestFiles" ] } }, "name" : "@DROLSKY/Test::NoTabs", "version" : "0.15" }, { "class" : "Dist::Zilla::Plugin::Test::Portability", "config" : { "Dist::Zilla::Plugin::Test::Portability" : { "options" : "" } }, "name" : "@DROLSKY/Test::Portability", "version" : "2.001000" }, { "class" : "Dist::Zilla::Plugin::Test::TidyAll", "name" : "@DROLSKY/Test::TidyAll", "version" : "0.04" }, { "class" : "Dist::Zilla::Plugin::Test::ReportPrereqs", "name" : "@DROLSKY/Test::ReportPrereqs", "version" : "0.027" }, { "class" : "Dist::Zilla::Plugin::DROLSKY::Contributors", "name" : "@DROLSKY/DROLSKY::Contributors", "version" : "0.85" }, { "class" : "Dist::Zilla::Plugin::Git::Contributors", "config" : { "Dist::Zilla::Plugin::Git::Contributors" : { "git_version" : "2.14.1", "include_authors" : 0, "include_releaser" : 1, "order_by" : "name", "paths" : [] } }, "name" : "@DROLSKY/Git::Contributors", "version" : "0.030" }, { "class" : "Dist::Zilla::Plugin::SurgicalPodWeaver", "config" : { "Dist::Zilla::Plugin::PodWeaver" : { "config_plugins" : [ "@DROLSKY" ], "finder" : [ ":InstallModules", ":ExecFiles" ], "plugins" : [ { "class" : "Pod::Weaver::Plugin::EnsurePod5", "name" : "@CorePrep/EnsurePod5", "version" : "4.015" }, { "class" : "Pod::Weaver::Plugin::H1Nester", "name" : "@CorePrep/H1Nester", "version" : "4.015" }, { "class" : "Pod::Weaver::Plugin::SingleEncoding", "name" : "@DROLSKY/SingleEncoding", "version" : "4.015" }, { "class" : "Pod::Weaver::Plugin::Transformer", "name" : "@DROLSKY/List", "version" : "4.015" }, { "class" : "Pod::Weaver::Plugin::Transformer", "name" : "@DROLSKY/Verbatim", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Region", "name" : "@DROLSKY/header", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Name", "name" : "@DROLSKY/Name", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Version", "name" : "@DROLSKY/Version", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Region", "name" : "@DROLSKY/prelude", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Generic", "name" : "SYNOPSIS", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Generic", "name" : "DESCRIPTION", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Generic", "name" : "OVERVIEW", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Collect", "name" : "ATTRIBUTES", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Collect", "name" : "METHODS", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Collect", "name" : "FUNCTIONS", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Collect", "name" : "TYPES", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Leftovers", "name" : "@DROLSKY/Leftovers", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Region", "name" : "@DROLSKY/postlude", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::GenerateSection", "name" : "@DROLSKY/generate SUPPORT", "version" : "1.06" }, { "class" : "Pod::Weaver::Section::AllowOverride", "name" : "@DROLSKY/allow override SUPPORT", "version" : "0.05" }, { "class" : "Pod::Weaver::Section::GenerateSection", "name" : "@DROLSKY/generate SOURCE", "version" : "1.06" }, { "class" : "Pod::Weaver::Section::GenerateSection", "name" : "@DROLSKY/generate DONATIONS", "version" : "1.06" }, { "class" : "Pod::Weaver::Section::Authors", "name" : "@DROLSKY/Authors", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Contributors", "name" : "@DROLSKY/Contributors", "version" : "0.009" }, { "class" : "Pod::Weaver::Section::Legal", "name" : "@DROLSKY/Legal", "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Region", "name" : "@DROLSKY/footer", "version" : "4.015" } ] } }, "name" : "@DROLSKY/SurgicalPodWeaver", "version" : "0.0023" }, { "class" : "Dist::Zilla::Plugin::DROLSKY::WeaverConfig", "name" : "@DROLSKY/DROLSKY::WeaverConfig", "version" : "0.85" }, { "class" : "Dist::Zilla::Plugin::ReadmeAnyFromPod", "config" : { "Dist::Zilla::Role::FileWatcher" : { "version" : "0.006" } }, "name" : "@DROLSKY/README.md in build", "version" : "0.163250" }, { "class" : "Dist::Zilla::Plugin::GenerateFile::FromShareDir", "config" : { "Dist::Zilla::Plugin::GenerateFile::FromShareDir" : { "destination_filename" : "CONTRIBUTING.md", "dist" : "Dist-Zilla-PluginBundle-DROLSKY", "encoding" : "UTF-8", "has_xs" : 0, "location" : "build", "source_filename" : "CONTRIBUTING.md" }, "Dist::Zilla::Role::RepoFileInjector" : { "allow_overwrite" : 1, "repo_root" : ".", "version" : "0.007" } }, "name" : "@DROLSKY/Generate CONTRIBUTING.md", "version" : "0.013" }, { "class" : "Dist::Zilla::Plugin::InstallGuide", "name" : "@DROLSKY/InstallGuide", "version" : "1.200007" }, { "class" : "Dist::Zilla::Plugin::CPANFile", "name" : "@DROLSKY/CPANFile", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::DROLSKY::License", "name" : "@DROLSKY/DROLSKY::License", "version" : "0.85" }, { "class" : "Dist::Zilla::Plugin::CheckStrictVersion", "name" : "@DROLSKY/CheckStrictVersion", "version" : "0.001" }, { "class" : "Dist::Zilla::Plugin::CheckSelfDependency", "config" : { "Dist::Zilla::Plugin::CheckSelfDependency" : { "finder" : [ ":InstallModules" ] }, "Dist::Zilla::Role::ModuleMetadata" : { "Module::Metadata" : "1.000033", "version" : "0.004" } }, "name" : "@DROLSKY/CheckSelfDependency", "version" : "0.011" }, { "class" : "Dist::Zilla::Plugin::CheckPrereqsIndexed", "name" : "@DROLSKY/CheckPrereqsIndexed", "version" : "0.020" }, { "class" : "Dist::Zilla::Plugin::DROLSKY::Git::CheckFor::CorrectBranch", "config" : { "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.14.1", "repo_root" : "." } }, "name" : "@DROLSKY/DROLSKY::Git::CheckFor::CorrectBranch", "version" : "0.85" }, { "class" : "Dist::Zilla::Plugin::EnsureChangesHasContent", "name" : "@DROLSKY/EnsureChangesHasContent", "version" : "0.02" }, { "class" : "Dist::Zilla::Plugin::Git::CheckFor::MergeConflicts", "config" : { "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.14.1", "repo_root" : "." } }, "name" : "@DROLSKY/Git::CheckFor::MergeConflicts", "version" : "0.014" }, { "class" : "Dist::Zilla::Plugin::DROLSKY::TidyAll", "name" : "@DROLSKY/DROLSKY::TidyAll", "version" : "0.85" }, { "class" : "Dist::Zilla::Plugin::Git::Check", "config" : { "Dist::Zilla::Plugin::Git::Check" : { "untracked_files" : "die" }, "Dist::Zilla::Role::Git::DirtyFiles" : { "allow_dirty" : [ "CONTRIBUTING.md", "Changes", "LICENSE", "Makefile.PL", "README.md", "cpanfile", "tidyall.ini" ], "allow_dirty_match" : [], "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.14.1", "repo_root" : "." } }, "name" : "@DROLSKY/Git::Check", "version" : "2.042" }, { "class" : "Dist::Zilla::Plugin::Git::Commit", "config" : { "Dist::Zilla::Plugin::Git::Commit" : { "add_files_in" : [], "commit_msg" : "v%v%n%n%c" }, "Dist::Zilla::Role::Git::DirtyFiles" : { "allow_dirty" : [ "CONTRIBUTING.md", "Changes", "LICENSE", "Makefile.PL", "README.md", "cpanfile", "tidyall.ini" ], "allow_dirty_match" : [], "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.14.1", "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { "time_zone" : "local" } }, "name" : "@DROLSKY/Commit generated files", "version" : "2.042" }, { "class" : "Dist::Zilla::Plugin::Git::Tag", "config" : { "Dist::Zilla::Plugin::Git::Tag" : { "branch" : null, "changelog" : "Changes", "signed" : 0, "tag" : "v2.67", "tag_format" : "v%v", "tag_message" : "v%v" }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.14.1", "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { "time_zone" : "local" } }, "name" : "@DROLSKY/Git::Tag", "version" : "2.042" }, { "class" : "Dist::Zilla::Plugin::Git::Push", "config" : { "Dist::Zilla::Plugin::Git::Push" : { "push_to" : [ "origin" ], "remotes_must_exist" : 1 }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.14.1", "repo_root" : "." } }, "name" : "@DROLSKY/Git::Push", "version" : "2.042" }, { "class" : "Dist::Zilla::Plugin::BumpVersionAfterRelease", "config" : { "Dist::Zilla::Plugin::BumpVersionAfterRelease" : { "finders" : [ ":ExecFiles", ":InstallModules" ], "global" : 0, "munge_makefile_pl" : 1 } }, "name" : "@DROLSKY/BumpVersionAfterRelease", "version" : "0.015" }, { "class" : "Dist::Zilla::Plugin::Git::Commit", "config" : { "Dist::Zilla::Plugin::Git::Commit" : { "add_files_in" : [], "commit_msg" : "Bump version after release" }, "Dist::Zilla::Role::Git::DirtyFiles" : { "allow_dirty" : [ "Changes", "dist.ini" ], "allow_dirty_match" : [ "(?^:.+)" ], "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.14.1", "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { "time_zone" : "local" } }, "name" : "@DROLSKY/Commit version bump", "version" : "2.042" }, { "class" : "Dist::Zilla::Plugin::Git::Push", "config" : { "Dist::Zilla::Plugin::Git::Push" : { "push_to" : [ "origin" ], "remotes_must_exist" : 1 }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.14.1", "repo_root" : "." } }, "name" : "@DROLSKY/Push version bump", "version" : "2.042" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "develop", "type" : "requires" } }, "name" : "DevelopRequires", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FileFinder::ByName", "name" : "MostLibs", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::Test::Version", "name" : "Test::Version", "version" : "1.09" }, { "class" : "Dist::Zilla::Plugin::Conflicts", "name" : "Conflicts", "version" : "0.19" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":InstallModules", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":IncModules", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":TestFiles", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ExtraTestFiles", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ExecFiles", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":PerlExecFiles", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ShareFiles", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":MainModule", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":AllFiles", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":NoFiles", "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : "@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM", "version" : "6.010" } ], "zilla" : { "class" : "Dist::Zilla::Dist::Builder", "config" : { "is_trial" : 0 }, "version" : "6.010" } }, "x_authority" : "cpan:DROLSKY", "x_breaks" : { "Log::Dispatch::File::Stamped" : "<= 0.17" }, "x_contributors" : [ "Anirvan Chatterjee ", "Carsten Grohmann ", "Doug Bell ", "Graham Ollis ", "Gregory Oschwald ", "Johann Rolschewski ", "Jonathan Swartz ", "Karen Etheridge ", "Kerin Millar ", "Kivanc Yazan ", "Konrad Bucheli ", "Michael Schout ", "Olaf Alders ", "Olivier Mengu\u00e9 ", "Rohan Carly ", "Ross Attrill ", "Salvador Fandi\u00f1o ", "Slaven Rezic ", "Steve Bertrand ", "Whitney Jackson " ], "x_serialization_backend" : "Cpanel::JSON::XS version 3.0233" } Log-Dispatch-2.67/lib/0000775000175000017500000000000013162076057014345 5ustar autarchautarchLog-Dispatch-2.67/lib/Log/0000775000175000017500000000000013162076057015066 5ustar autarchautarchLog-Dispatch-2.67/lib/Log/Dispatch.pm0000644000175000017500000005111613162076057017165 0ustar autarchautarchpackage Log::Dispatch; use 5.006; use strict; use warnings; our $VERSION = '2.67'; use Carp (); use Log::Dispatch::Types; use Log::Dispatch::Vars qw( %CanonicalLevelNames @OrderedLevels ); use Module::Runtime qw( use_package_optimistically ); use Params::ValidationCompiler qw( validation_for ); use base qw( Log::Dispatch::Base ); BEGIN { foreach my $l ( keys %CanonicalLevelNames ) { my $sub = sub { my $self = shift; $self->log( level => $CanonicalLevelNames{$l}, message => @_ > 1 ? "@_" : $_[0], ); }; ## no critic (TestingAndDebugging::ProhibitNoStrict) no strict 'refs'; *{$l} = $sub; } } { my $validator = validation_for( params => { outputs => { type => t('ArrayRef'), optional => 1, }, callbacks => { type => t('Callbacks'), optional => 1, }, }, ); sub new { my $class = shift; my %p = $validator->(@_); my $self = bless {}, $class; $self->{callbacks} = $p{callbacks} if $p{callbacks}; if ( my $outputs = $p{outputs} ) { if ( ref $outputs->[1] eq 'HASH' ) { # 2.23 API # outputs => [ # File => { min_level => 'debug', filename => 'logfile' }, # Screen => { min_level => 'warning' } # ] while ( my ( $class, $params ) = splice @$outputs, 0, 2 ) { $self->_add_output( $class, %$params ); } } else { # 2.24+ syntax # outputs => [ # [ 'File', min_level => 'debug', filename => 'logfile' ], # [ 'Screen', min_level => 'warning' ] # ] foreach my $arr ( @{$outputs} ) { die "expected arrayref, not '$arr'" unless ref $arr eq 'ARRAY'; $self->_add_output( @{$arr} ); } } } return $self; } } sub clone { my $self = shift; my %clone = ( callbacks => [ @{ $self->{callbacks} || [] } ], outputs => { %{ $self->{outputs} || {} } }, ); return bless \%clone, ref $self; } sub _add_output { my $self = shift; my $class = shift; my $full_class = substr( $class, 0, 1 ) eq '+' ? substr( $class, 1 ) : "Log::Dispatch::$class"; use_package_optimistically($full_class); $self->add( $full_class->new(@_) ); } sub add { my $self = shift; my $object = shift; # Once 5.6 is more established start using the warnings module. if ( exists $self->{outputs}{ $object->name } && $^W ) { Carp::carp( 'Log::Dispatch::* object ', $object->name, ' already exists.' ); } $self->{outputs}{ $object->name } = $object; } sub remove { my $self = shift; my $name = shift; return delete $self->{outputs}{$name}; } sub outputs { my $self = shift; return values %{ $self->{outputs} }; } sub callbacks { my $self = shift; return @{ $self->{callbacks} }; } ## no critic (Subroutines::ProhibitBuiltinHomonyms) sub log { my $self = shift; my %p = @_; return unless $self->would_log( $p{level} ); $self->_log_to_outputs( $self->_prepare_message(%p) ); } ## use critic sub _prepare_message { my $self = shift; my %p = @_; $p{message} = $p{message}->() if ref $p{message} eq 'CODE'; $p{message} = $self->_apply_callbacks(%p) if $self->{callbacks}; return %p; } sub _log_to_outputs { my $self = shift; my %p = @_; foreach ( keys %{ $self->{outputs} } ) { $p{name} = $_; $self->_log_to(%p); } } sub log_and_die { my $self = shift; my %p = $self->_prepare_message(@_); $self->_log_to_outputs(%p) if $self->would_log( $p{level} ); $self->_die_with_message(%p); } sub log_and_croak { my $self = shift; $self->log_and_die(@_); } my @CARP_NOT = __PACKAGE__; sub _die_with_message { my $self = shift; my %p = @_; my $msg = $p{message}; local $Carp::CarpLevel = ( $Carp::CarpLevel || 0 ) + $p{carp_level} if exists $p{carp_level}; Carp::croak($msg); } sub log_to { my $self = shift; my %p = @_; $p{message} = $self->_apply_callbacks(%p) if $self->{callbacks}; $self->_log_to(%p); } sub _log_to { my $self = shift; my %p = @_; my $name = $p{name}; if ( exists $self->{outputs}{$name} ) { $self->{outputs}{$name}->log(@_); } elsif ($^W) { Carp::carp( "Log::Dispatch::* object named '$name' not in dispatcher\n"); } } sub output { my $self = shift; my $name = shift; return unless exists $self->{outputs}{$name}; return $self->{outputs}{$name}; } sub level_is_valid { shift; my $level = shift; if ( !defined $level ) { Carp::croak('Logging level was not provided'); } if ( $level =~ /\A[0-9]+\z/ && $level <= $#OrderedLevels ) { return $OrderedLevels[$level]; } return $CanonicalLevelNames{$level}; } sub would_log { my $self = shift; my $level = shift; return 0 unless $self->level_is_valid($level); foreach ( values %{ $self->{outputs} } ) { return 1 if $_->_should_log($level); } return 0; } sub is_debug { $_[0]->would_log('debug') } sub is_info { $_[0]->would_log('info') } sub is_notice { $_[0]->would_log('notice') } sub is_warning { $_[0]->would_log('warning') } sub is_warn { $_[0]->would_log('warn') } sub is_error { $_[0]->would_log('error') } sub is_err { $_[0]->would_log('err') } sub is_critical { $_[0]->would_log('critical') } sub is_crit { $_[0]->would_log('crit') } sub is_alert { $_[0]->would_log('alert') } sub is_emerg { $_[0]->would_log('emerg') } sub is_emergency { $_[0]->would_log('emergency') } 1; # ABSTRACT: Dispatches messages to one or more outputs __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch - Dispatches messages to one or more outputs =head1 VERSION version 2.67 =head1 SYNOPSIS use Log::Dispatch; # Simple API # my $log = Log::Dispatch->new( outputs => [ [ 'File', min_level => 'debug', filename => 'logfile' ], [ 'Screen', min_level => 'warning' ], ], ); $log->info('Blah, blah'); # More verbose API # my $log = Log::Dispatch->new(); $log->add( Log::Dispatch::File->new( name => 'file1', min_level => 'debug', filename => 'logfile' ) ); $log->add( Log::Dispatch::Screen->new( name => 'screen', min_level => 'warning', ) ); $log->log( level => 'info', message => 'Blah, blah' ); my $sub = sub { my %p = @_; return reverse $p{message}; }; my $reversing_dispatcher = Log::Dispatch->new( callbacks => $sub ); =head1 DESCRIPTION This module manages a set of Log::Dispatch::* output objects that can be logged to via a unified interface. The idea is that you create a Log::Dispatch object and then add various logging objects to it (such as a file logger or screen logger). Then you call the C method of the dispatch object, which passes the message to each of the objects, which in turn decide whether or not to accept the message and what to do with it. This makes it possible to call single method and send a message to a log file, via email, to the screen, and anywhere else, all with very little code needed on your part, once the dispatching object has been created. =head1 METHODS This class provides the following methods: =head2 Log::Dispatch->new(...) This method takes the following parameters: =over 4 =item * outputs( [ [ class, params, ... ], [ class, params, ... ], ... ] ) This parameter is a reference to a list of lists. Each inner list consists of a class name and a set of constructor params. The class is automatically prefixed with 'Log::Dispatch::' unless it begins with '+', in which case the string following '+' is taken to be a full classname. e.g. outputs => [ [ 'File', min_level => 'debug', filename => 'logfile' ], [ '+My::Dispatch', min_level => 'info' ] ] For each inner list, a new output object is created and added to the dispatcher (via the C method). See L for the parameters that can be used when creating an output object. =item * callbacks( \& or [ \&, \&, ... ] ) This parameter may be a single subroutine reference or an array reference of subroutine references. These callbacks will be called in the order they are given and passed a hash containing the following keys: ( message => $log_message, level => $log_level ) In addition, any key/value pairs passed to a logging method will be passed onto your callback. The callbacks are expected to modify the message and then return a single scalar containing that modified message. These callbacks will be called when either the C or C methods are called and will only be applied to a given message once. If they do not return the message then you will get no output. Make sure to return the message! =back =head2 $dispatch->clone() This returns a I clone of the original object. The underlying output objects and callbacks are shared between the two objects. However any changes made to the outputs or callbacks that the object contains are not shared. =head2 $dispatch->log( level => $, message => $ or \& ) Sends the message (at the appropriate level) to all the output objects that the dispatcher contains (by calling the C method repeatedly). The level can be specified by name or by an integer from 0 (debug) to 7 (emergency). This method also accepts a subroutine reference as the message argument. This reference will be called only if there is an output that will accept a message of the specified level. =head2 $dispatch->debug (message), info (message), ... You may call any valid log level (including valid abbreviations) as a method with a single argument that is the message to be logged. This is converted into a call to the C method with the appropriate level. For example: $log->alert('Strange data in incoming request'); translates to: $log->log( level => 'alert', message => 'Strange data in incoming request' ); If you pass an array to these methods, it will be stringified as is: my @array = ('Something', 'bad', 'is', 'here'); $log->alert(@array); # is equivalent to $log->alert("@array"); You can also pass a subroutine reference, just like passing one to the C method. =head2 $dispatch->log_and_die( level => $, message => $ or \& ) Has the same behavior as calling C but calls C<_die_with_message()> at the end. =head2 $dispatch->log_and_croak( level => $, message => $ or \& ) This method adjusts the C<$Carp::CarpLevel> scalar so that the croak comes from the context in which it is called. You can throw exception objects by subclassing this method. If the C parameter is present its value will be added to the current value of C<$Carp::CarpLevel>. =head2 $dispatch->log_to( name => $, level => $, message => $ ) Sends the message only to the named object. Note: this will not properly handle a subroutine reference as the message. =head2 $dispatch->add_callback( $code ) Adds a callback (like those given during construction). It is added to the end of the list of callbacks. Note that this can also be called on individual output objects. =head2 $dispatch->remove_callback( $code ) Remove the given callback from the list of callbacks. Note that this can also be called on individual output objects. =head2 $dispatch->callbacks() Returns a list of the callbacks in a given output. =head2 $dispatch->level_is_valid( $string ) Returns true or false to indicate whether or not the given string is a valid log level. Can be called as either a class or object method. =head2 $dispatch->would_log( $string ) Given a log level, returns true or false to indicate whether or not anything would be logged for that log level. =head2 $dispatch->is_C<$level> There are methods for every log level: C, C, etc. This returns true if the logger will log a message at the given level. =head2 $dispatch->add( Log::Dispatch::* OBJECT ) Adds a new L to the dispatcher. If an object of the same name already exists, then that object is replaced, with a warning if C<$^W> is true. =head2 $dispatch->remove($) Removes the output object that matches the name given to the remove method. The return value is the object being removed or undef if no object matched this. =head2 $dispatch->outputs() Returns a list of output objects. =head2 $dispatch->output( $name ) Returns the output object of the given name. Returns undef or an empty list, depending on context, if the given output does not exist. =head2 $dispatch->_die_with_message( message => $, carp_level => $ ) This method is used by C and will either die() or croak() depending on the value of C: if it's a reference or it ends with a new line then a plain die will be used, otherwise it will croak. =head1 OUTPUT CLASSES An output class - e.g. L or L - implements a particular way of dispatching logs. Many output classes come with this distribution, and others are available separately on CPAN. The following common parameters can be used when creating an output class. All are optional. Most output classes will have additional parameters beyond these, see their documentation for details. =over 4 =item * name ($) A name for the object (not the filename!). This is useful if you want to refer to the object later, e.g. to log specifically to it or remove it. By default a unique name will be generated. You should not depend on the form of generated names, as they may change. =item * min_level ($) The minimum L this object will accept. Required. =item * max_level ($) The maximum L this object will accept. By default the maximum is the highest possible level (which means functionally that the object has no maximum). =item * callbacks( \& or [ \&, \&, ... ] ) This parameter may be a single subroutine reference or an array reference of subroutine references. These callbacks will be called in the order they are given and passed a hash containing the following keys: ( message => $log_message, level => $log_level ) The callbacks are expected to modify the message and then return a single scalar containing that modified message. These callbacks will be called when either the C or C methods are called and will only be applied to a given message once. If they do not return the message then you will get no output. Make sure to return the message! =item * newline (0|1) If true, a callback will be added to the end of the callbacks list that adds a newline to the end of each message. Default is false, but some output classes may decide to make the default true. =back =head1 LOG LEVELS The log levels that Log::Dispatch uses are taken directly from the syslog man pages (except that I expanded them to full words). Valid levels are: =over 4 =item debug =item info =item notice =item warning =item error =item critical =item alert =item emergency =back Alternately, the numbers 0 through 7 may be used (debug is 0 and emergency is 7). The syslog standard of 'err', 'crit', and 'emerg' is also acceptable. We also allow 'warn' as a synonym for 'warning'. =head1 SUBCLASSING This module was designed to be easy to subclass. If you want to handle messaging in a way not implemented in this package, you should be able to add this with minimal effort. It is generally as simple as subclassing Log::Dispatch::Output and overriding the C and C methods. See the L docs for more details. If you would like to create your own subclass for sending email then it is even simpler. Simply subclass L and override the C method. See the L docs for more details. The logging levels that Log::Dispatch uses are borrowed from the standard UNIX syslog levels, except that where syslog uses partial words ("err") Log::Dispatch also allows the use of the full word as well ("error"). =head1 RELATED MODULES =head2 Log::Dispatch::DBI Written by Tatsuhiko Miyagawa. Log output to a database table. =head2 Log::Dispatch::FileRotate Written by Mark Pfeiffer. Rotates log files periodically as part of its usage. =head2 Log::Dispatch::File::Stamped Written by Eric Cholet. Stamps log files with date and time information. =head2 Log::Dispatch::Jabber Written by Aaron Straup Cope. Logs messages via Jabber. =head2 Log::Dispatch::Tk Written by Dominique Dumont. Logs messages to a Tk window. =head2 Log::Dispatch::Win32EventLog Written by Arthur Bergman. Logs messages to the Windows event log. =head2 Log::Log4perl An implementation of Java's log4j API in Perl. Log messages can be limited by fine-grained controls, and if they end up being logged, both native Log4perl and Log::Dispatch appenders can be used to perform the actual logging job. Created by Mike Schilli and Kevin Goess. =head2 Log::Dispatch::Config Written by Tatsuhiko Miyagawa. Allows configuration of logging via a text file similar (or so I'm told) to how it is done with log4j. Simpler than Log::Log4perl. =head2 Log::Agent A very different API for doing many of the same things that Log::Dispatch does. Originally written by Raphael Manfredi. =head1 SEE ALSO L, L, L, L, L, L, L, L, L, L, L, L =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 DONATIONS If you'd like to thank me for the work I've done on this module, please consider making a "donation" to me via PayPal. I spend a lot of free time creating free software, and would appreciate any support you'd care to offer. Please note that B in order for me to continue working on this particular software. I will continue to do so, inasmuch as I have in the past, for as long as it interests me. Similarly, a donation made in this way will probably not make me work on this software much more, unless I get so many donations that I can consider working on free software full time (let's all have a chuckle at that together). To donate, log into PayPal and send money to autarch@urth.org, or use the button at L. =head1 AUTHOR Dave Rolsky =head1 CONTRIBUTORS =for stopwords Anirvan Chatterjee Carsten Grohmann Doug Bell Graham Ollis Gregory Oschwald Johann Rolschewski Jonathan Swartz Karen Etheridge Kerin Millar Kivanc Yazan Konrad Bucheli Michael Schout Olaf Alders Olivier MenguĆ© Rohan Carly Ross Attrill Salvador FandiƱo Slaven Rezic Steve Bertrand Whitney Jackson =over 4 =item * Anirvan Chatterjee =item * Carsten Grohmann =item * Doug Bell =item * Graham Ollis =item * Gregory Oschwald =item * Johann Rolschewski =item * Jonathan Swartz =item * Karen Etheridge =item * Kerin Millar =item * Kivanc Yazan =item * Konrad Bucheli =item * Michael Schout =item * Olaf Alders =item * Olivier MenguĆ© =item * Rohan Carly =item * Ross Attrill =item * Salvador FandiƱo =item * Slaven Rezic =item * Steve Bertrand =item * Whitney Jackson =back =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/0000775000175000017500000000000013162076057016625 5ustar autarchautarchLog-Dispatch-2.67/lib/Log/Dispatch/Email/0000775000175000017500000000000013162076057017654 5ustar autarchautarchLog-Dispatch-2.67/lib/Log/Dispatch/Email/MailSend.pm0000644000175000017500000000472713162076057021716 0ustar autarchautarchpackage Log::Dispatch::Email::MailSend; use strict; use warnings; our $VERSION = '2.67'; use Mail::Send; use Try::Tiny; use base qw( Log::Dispatch::Email ); sub send_email { my $self = shift; my %p = @_; my $msg = Mail::Send->new; $msg->to( join ',', @{ $self->{to} } ); $msg->subject( $self->{subject} ); # Does this ever work for this module? $msg->set( 'From', $self->{from} ) if $self->{from}; local $? = 0; return if try { my $fh = $msg->open or die 'Cannot open handle to mail program'; $fh->print( $p{message} ) or die 'Cannot print message to mail program handle'; $fh->close or die 'Cannot close handle to mail program'; 1; }; warn $@ if $@; } 1; # ABSTRACT: Subclass of Log::Dispatch::Email that uses the Mail::Send module __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::Email::MailSend - Subclass of Log::Dispatch::Email that uses the Mail::Send module =head1 VERSION version 2.67 =head1 SYNOPSIS use Log::Dispatch; my $log = Log::Dispatch->new( outputs => [ [ 'Email::MailSend', min_level => 'emerg', to => [qw( foo@example.com bar@example.org )], subject => 'Big error!' ] ], ); $log->emerg('Something bad is happening'); =head1 DESCRIPTION This is a subclass of L that implements the send_email method using the L module. =head1 CHANGING HOW MAIL IS SENT Since L is a subclass of L, you can change how mail is sent from this module by simply Cing L in your code before mail is sent. For example, to send mail via smtp, you could do: use Mail::Mailer 'smtp', Server => 'foo.example.com'; For more details, see the L docs. =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/Email/MailSender.pm0000644000175000017500000001171413162076057022237 0ustar autarchautarchpackage Log::Dispatch::Email::MailSender; # By: Joseph Annino # (c) 2002 # Licensed under the same terms as Perl # use strict; use warnings; our $VERSION = '2.67'; use Log::Dispatch::Types; use Mail::Sender (); use Params::ValidationCompiler qw( validation_for ); use base qw( Log::Dispatch::Email ); { my $validator = validation_for( params => { smtp => { default => 'localhost' }, port => { default => 25 }, authid => 0, authpwd => 0, auth => 0, tls_required => 0, replyto => 0, fake_from => 0, }, slurpy => 1, ); sub new { my $class = shift; my %p = $validator->(@_); my $smtp = delete $p{smtp}; my $port = delete $p{port}; my $authid = delete $p{authid}; my $authpwd = delete $p{authpwd}; my $auth = delete $p{auth}; my $tls_required = delete $p{tls_required}; my $replyto = delete $p{replyto}; my $fake_from = delete $p{fake_from}; my $self = $class->SUPER::new(%p); $self->{smtp} = $smtp; $self->{port} = $port; $self->{authid} = $authid; $self->{authpwd} = $authpwd; $self->{auth} = $auth; $self->{tls_required} = $tls_required; $self->{fake_from} = $fake_from; $self->{replyto} = $replyto; return $self; } } sub send_email { my $self = shift; my %p = @_; local ( $?, $@, $SIG{__DIE__} ) = ( undef, undef, undef ); return if eval { my $sender = Mail::Sender->new( { from => $self->{from} || 'LogDispatch@foo.bar', fake_from => $self->{fake_from}, replyto => $self->{replyto}, to => ( join ',', @{ $self->{to} } ), subject => $self->{subject}, smtp => $self->{smtp}, port => $self->{port}, authid => $self->{authid}, authpwd => $self->{authpwd}, auth => $self->{auth}, tls_required => $self->{tls_required}, #debug => \*STDERR, } ); die "Error sending mail ($sender): $Mail::Sender::Error" unless ref $sender; ref $sender->MailMsg( { msg => $p{message} } ) or die "Error sending mail: $Mail::Sender::Error"; 1; }; warn $@ if $@; } 1; # ABSTRACT: Subclass of Log::Dispatch::Email that uses the Mail::Sender module __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::Email::MailSender - Subclass of Log::Dispatch::Email that uses the Mail::Sender module =head1 VERSION version 2.67 =head1 SYNOPSIS use Log::Dispatch; my $log = Log::Dispatch->new( outputs => [ [ 'Email::MailSender', min_level => 'emerg', to => [qw( foo@example.com bar@example.org )], subject => 'Big error!' ] ], ); $log->emerg("Something bad is happening"); =head1 DESCRIPTION This is a subclass of L that implements the send_email method using the L module. =head1 CONSTRUCTOR The constructor takes the following parameters in addition to the parameters documented in L and L: =over 4 =item * smtp ($) The smtp server to connect to. This defaults to "localhost". =item * port ($) The port to use when connecting. This defaults to 25. =item * auth ($) Optional. The SMTP authentication protocol to use to login to the server. At the time of writing Mail::Sender only supports LOGIN, PLAIN, CRAM-MD5 and NTLM. Some protocols have module dependencies. CRAM-MD5 depends on Digest::HMAC_MD5 and NTLM on Authen::NTLM. =item * authid ($) Optional. The username used to login to the server. =item * authpwd ($) Optional. The password used to login to the server. =item * tls_required ($) Optional. If you set this option to a true value, Mail::Sender will fail whenever it's unable to use TLS. =item * fake_from ($) The From address that will be shown in headers. If not specified we use the value of from. =item * replyto ($) The reply-to address. =back =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/Email/MIMELite.pm0000644000175000017500000000360213162076057021556 0ustar autarchautarchpackage Log::Dispatch::Email::MIMELite; use strict; use warnings; our $VERSION = '2.67'; use MIME::Lite; use base qw( Log::Dispatch::Email ); sub send_email { my $self = shift; my %p = @_; my %mail = ( To => ( join ',', @{ $self->{to} } ), Subject => $self->{subject}, Type => 'TEXT', Data => $p{message}, ); $mail{From} = $self->{from} if defined $self->{from}; local $? = 0; unless ( MIME::Lite->new(%mail)->send ) { warn 'Error sending mail with MIME::Lite'; } } 1; # ABSTRACT: Subclass of Log::Dispatch::Email that uses the MIME::Lite module __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::Email::MIMELite - Subclass of Log::Dispatch::Email that uses the MIME::Lite module =head1 VERSION version 2.67 =head1 SYNOPSIS use Log::Dispatch; my $log = Log::Dispatch->new( outputs => [ [ 'Email::MIMELite', min_level => 'emerg', to => [qw( foo@example.com bar@example.org )], subject => 'Big error!' ] ], ); $log->emerg("Something bad is happening"); =head1 DESCRIPTION This is a subclass of L that implements the send_email method using the L module. =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/Email/MailSendmail.pm0000644000175000017500000000371213162076057022552 0ustar autarchautarchpackage Log::Dispatch::Email::MailSendmail; use strict; use warnings; our $VERSION = '2.67'; use Mail::Sendmail (); use base qw( Log::Dispatch::Email ); sub send_email { my $self = shift; my %p = @_; my %mail = ( To => ( join ',', @{ $self->{to} } ), Subject => $self->{subject}, Message => $p{message}, # Mail::Sendmail insists on having this parameter. From => $self->{from} || 'LogDispatch@foo.bar', ); local $? = 0; unless ( Mail::Sendmail::sendmail(%mail) ) { warn "Error sending mail: $Mail::Sendmail::error"; } } 1; # ABSTRACT: Subclass of Log::Dispatch::Email that uses the Mail::Sendmail module __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::Email::MailSendmail - Subclass of Log::Dispatch::Email that uses the Mail::Sendmail module =head1 VERSION version 2.67 =head1 SYNOPSIS use Log::Dispatch; my $log = Log::Dispatch->new( outputs => [ [ 'Email::MailSendmail', min_level => 'emerg', to => [qw( foo@example.com bar@example.org )], subject => 'Big error!' ] ], ); $log->emerg("Something bad is happening"); =head1 DESCRIPTION This is a subclass of L that implements the send_email method using the L module. =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/Screen.pm0000644000175000017500000000662713162076057020413 0ustar autarchautarchpackage Log::Dispatch::Screen; use strict; use warnings; our $VERSION = '2.67'; use Encode qw( encode ); use IO::Handle; use Log::Dispatch::Types; use Params::ValidationCompiler qw( validation_for ); use base qw( Log::Dispatch::Output ); { my $validator = validation_for( params => { stderr => { type => t('Bool'), default => 1, }, utf8 => { type => t('Bool'), default => 0, }, }, slurpy => 1, ); sub new { my $class = shift; my %p = $validator->(@_); my $self = bless { map { $_ => delete $p{$_} } qw( stderr utf8 ) }, $class; $self->_basic_init(%p); return $self; } } sub log_message { my $self = shift; my %p = @_; # This is a bit gross but it's important that we print directly to the # STDOUT or STDERR handle for backwards compatibility. Various modules # have tests which rely on this, so we can't open a new filehandle to fd 1 # or 2 and use that. my $message = $self->{utf8} ? encode( 'UTF-8', $p{message} ) : $p{message}; ## no critic (InputOutput::RequireCheckedSyscalls) if ( $self->{stderr} ) { print STDERR $message; } else { print STDOUT $message; } } 1; # ABSTRACT: Object for logging to the screen __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::Screen - Object for logging to the screen =head1 VERSION version 2.67 =head1 SYNOPSIS use Log::Dispatch; my $log = Log::Dispatch->new( outputs => [ [ 'Screen', min_level => 'debug', stderr => 1, newline => 1 ] ], ); $log->alert("I'm searching the city for sci-fi wasabi"); =head1 DESCRIPTION This module provides an object for logging to the screen (really C or C). Note that a newline will I be added automatically at the end of a message by default. To do that, pass C<< newline => 1 >>. The handle will be autoflushed, but this module opens it's own handle to fd 1 or 2 instead of using the global C or C. =for Pod::Coverage new log_message =head1 CONSTRUCTOR The constructor takes the following parameters in addition to the standard parameters documented in L: =over 4 =item * stderr (0 or 1) Indicates whether or not logging information should go to C. If false, logging information is printed to C instead. This defaults to true. =item * utf8 (0 or 1) If this is true, then the output uses C to apply the C<:encoding(UTF-8)> layer to the relevant handle for output. This will not affect C or C in other parts of your code. This defaults to false. =back =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/ApacheLog.pm0000644000175000017500000000460613162076057021012 0ustar autarchautarchpackage Log::Dispatch::ApacheLog; use strict; use warnings; our $VERSION = '2.67'; use Log::Dispatch::Types; use Params::ValidationCompiler qw( validation_for ); BEGIN { if ( $ENV{MOD_PERL} && $ENV{MOD_PERL} =~ /2\./ ) { require Apache2::Log; } else { require Apache::Log; } } use base qw( Log::Dispatch::Output ); { my $validator = validation_for( params => { apache => { type => t('ApacheLog') } }, slurpy => 1, ); sub new { my $class = shift; my %p = $validator->(@_); my $self = bless { apache_log => ( delete $p{apache} )->log }, $class; $self->_basic_init(%p); return $self; } } { my %methods = ( emergency => 'emerg', critical => 'crit', warning => 'warn', ); sub log_message { my $self = shift; my %p = @_; my $level = $self->_level_as_name( $p{level} ); my $method = $methods{$level} || $level; $self->{apache_log}->$method( $p{message} ); } } 1; # ABSTRACT: Object for logging to Apache::Log objects __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::ApacheLog - Object for logging to Apache::Log objects =head1 VERSION version 2.67 =head1 SYNOPSIS use Log::Dispatch; my $log = Log::Dispatch->new( outputs => [ [ 'ApacheLog', apache => $r ], ], ); $log->emerg('Kaboom'); =head1 DESCRIPTION This module allows you to pass messages to Apache's log object, represented by the L class. =head1 CONSTRUCTOR The constructor takes the following parameters in addition to the standard parameters documented in L: =over 4 =item * apache ($) An object of either the L or L classes. Required. =back =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/Syslog.pm0000644000175000017500000001327113162076057020445 0ustar autarchautarchpackage Log::Dispatch::Syslog; use strict; use warnings; our $VERSION = '2.67'; use Log::Dispatch::Types; use Params::ValidationCompiler qw( validation_for ); use Scalar::Util qw( reftype ); use Sys::Syslog 0.28 (); use Try::Tiny; use base qw( Log::Dispatch::Output ); my $thread_lock; { my ($DefaultIdent) = $0 =~ /(.+)/; my $validator = validation_for( params => { ident => { # It's weird to allow an empty string but that's how this # worked pre-PVC. type => t('Str'), default => $DefaultIdent }, logopt => { type => t('Str'), default => q{}, }, facility => { type => t('NonEmptyStr'), default => 'user' }, socket => { type => t('SyslogSocket'), default => undef, }, lock => { type => t('Bool'), default => 0, }, }, slurpy => 1, ); my $threads_loaded; sub new { my $class = shift; my %p = $validator->(@_); my $self = bless { map { $_ => delete $p{$_} } qw( ident logopt facility socket lock ) }, $class; if ( $self->{lock} ) { unless ($threads_loaded) { local ( $@, $SIG{__DIE__} ) = ( undef, undef ); ## no critic (BuiltinFunctions::ProhibitStringyEval) # These need to be loaded with use, not require. die $@ unless eval 'use threads; use threads::shared; 1;'; $threads_loaded = 1; } &threads::shared::share( \$thread_lock ); } $self->_basic_init(%p); return $self; } } { my @priorities = ( 'DEBUG', 'INFO', 'NOTICE', 'WARNING', 'ERR', 'CRIT', 'ALERT', 'EMERG', ); sub log_message { my $self = shift; my %p = @_; my $pri = $self->_level_as_number( $p{level} ); lock($thread_lock) if $self->{lock}; return if try { if ( defined $self->{socket} ) { Sys::Syslog::setlogsock( ref $self->{socket} && reftype( $self->{socket} ) eq 'ARRAY' ? @{ $self->{socket} } : $self->{socket} ); } Sys::Syslog::openlog( $self->{ident}, $self->{logopt}, $self->{facility} ); Sys::Syslog::syslog( $priorities[$pri], $p{message} ); Sys::Syslog::closelog(); 1; }; warn $@ if $@ and $^W; } } 1; # ABSTRACT: Object for logging to system log. __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::Syslog - Object for logging to system log. =head1 VERSION version 2.67 =head1 SYNOPSIS use Log::Dispatch; my $log = Log::Dispatch->new( outputs => [ [ 'Syslog', min_level => 'info', ident => 'Yadda yadda' ] ] ); $log->emerg("Time to die."); =head1 DESCRIPTION This module provides a simple object for sending messages to the system log (via UNIX syslog calls). Note that logging may fail if you try to pass UTF-8 characters in the log message. If logging fails and warnings are enabled, the error message will be output using Perl's C. =for Pod::Coverage new log_message =head1 CONSTRUCTOR The constructor takes the following parameters in addition to the standard parameters documented in L: =over 4 =item * ident ($) This string will be prepended to all messages in the system log. Defaults to $0. =item * logopt ($) A string containing the log options (separated by any separator you like). See the openlog(3) and Sys::Syslog docs for more details. Defaults to ''. =item * facility ($) Specifies what type of program is doing the logging to the system log. Valid options are 'auth', 'authpriv', 'cron', 'daemon', 'kern', 'local0' through 'local7', 'mail, 'news', 'syslog', 'user', 'uucp'. Defaults to 'user' =item * socket ($, \@, or \%) Tells what type of socket to use for sending syslog messages. Valid options are listed in C. If you don't provide this, then we let C simply pick one that works, which is the preferred option, as it makes your code more portable. If you pass an array reference, it is dereferenced and passed to C. If you pass a hash reference, it is passed to C as is. =item * lock ($) If this is set to a true value, then the calls to C, C, C, and C will all be guarded by a thread-locked variable. This is only relevant when running you are using Perl threads in your application. Setting this to a true value will cause the L and L modules to be loaded. This defaults to false. =back =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/Output.pm0000644000175000017500000002062413162076057020465 0ustar autarchautarchpackage Log::Dispatch::Output; use strict; use warnings; our $VERSION = '2.67'; use Carp (); use Try::Tiny; use Log::Dispatch; use Log::Dispatch::Types; use Log::Dispatch::Vars qw( %LevelNamesToNumbers @OrderedLevels ); use Params::ValidationCompiler qw( validation_for ); use base qw( Log::Dispatch::Base ); sub new { my $proto = shift; my $class = ref $proto || $proto; die "The new method must be overridden in the $class subclass"; } { my $validator = validation_for( params => { level => { type => t('LogLevel') }, # Pre-PVC we accepted empty strings, which is weird, but we don't # want to break back-compat. See # https://github.com/houseabsolute/Log-Dispatch/issues/38. message => { type => t('Str') }, }, slurpy => 1, ); ## no critic (Subroutines::ProhibitBuiltinHomonyms) sub log { my $self = shift; my %p = $validator->(@_); return unless $self->_should_log( $p{level} ); local $! = undef; $p{message} = $self->_apply_callbacks(%p) if $self->{callbacks}; $self->log_message(%p); } } { my $validator = validation_for( params => { name => { type => t('NonEmptyStr'), optional => 1, }, min_level => { type => t('LogLevel') }, max_level => { type => t('LogLevel'), optional => 1, }, callbacks => { type => t('Callbacks'), optional => 1, }, newline => { type => t('Bool'), default => 0, }, }, # This is primarily here for the benefit of outputs outside of this # distro which may be passing who-knows-what to this method. slurpy => 1, ); ## no critic (Subroutines::ProhibitUnusedPrivateSubroutines) sub _basic_init { my $self = shift; my %p = $validator->(@_); $self->{level_names} = \@OrderedLevels; $self->{level_numbers} = \%LevelNamesToNumbers; $self->{name} = $p{name} || $self->_unique_name(); $self->{min_level} = $self->_level_as_number( $p{min_level} ); # Either use the parameter supplied or just the highest possible level. $self->{max_level} = ( exists $p{max_level} ? $self->_level_as_number( $p{max_level} ) : $#{ $self->{level_names} } ); $self->{callbacks} = $p{callbacks} if $p{callbacks}; if ( $p{newline} ) { push @{ $self->{callbacks} }, \&_add_newline_callback; } } } sub name { my $self = shift; return $self->{name}; } sub min_level { my $self = shift; return $self->{level_names}[ $self->{min_level} ]; } sub max_level { my $self = shift; return $self->{level_names}[ $self->{max_level} ]; } sub accepted_levels { my $self = shift; return @{ $self->{level_names} } [ $self->{min_level} .. $self->{max_level} ]; } sub _should_log { my $self = shift; my $msg_level = $self->_level_as_number(shift); return ( ( $msg_level >= $self->{min_level} ) && ( $msg_level <= $self->{max_level} ) ); } sub _level_as_number { my $self = shift; my $level = shift; unless ( defined $level ) { Carp::croak 'undefined value provided for log level'; } unless ( Log::Dispatch->level_is_valid($level) ) { Carp::croak "$level is not a valid Log::Dispatch log level"; } return $level if $level =~ /\A[0-7]+\z/; return $self->{level_numbers}{$level}; } ## no critic (Subroutines::ProhibitUnusedPrivateSubroutines) sub _level_as_name { my $self = shift; my $level = shift; unless ( defined $level ) { Carp::croak 'undefined value provided for log level'; } my $canonical_level; unless ( $canonical_level = Log::Dispatch->level_is_valid($level) ) { Carp::croak "$level is not a valid Log::Dispatch log level"; } return $canonical_level unless $level =~ /\A[0-7]+\z/; return $self->{level_names}[$level]; } ## use critic my $_unique_name_counter = 0; sub _unique_name { my $self = shift; return '_anon_' . $_unique_name_counter++; } sub _add_newline_callback { # This weird construct is an optimization since this might be called a lot # - see https://github.com/autarch/Log-Dispatch/pull/7 +{@_}->{message} . "\n"; } 1; # ABSTRACT: Base class for all Log::Dispatch::* objects __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::Output - Base class for all Log::Dispatch::* objects =head1 VERSION version 2.67 =head1 SYNOPSIS package Log::Dispatch::MySubclass; use Log::Dispatch::Output; use base qw( Log::Dispatch::Output ); sub new { my $proto = shift; my $class = ref $proto || $proto; my %p = @_; my $self = bless {}, $class; $self->_basic_init(%p); # Do more if you like return $self; } sub log_message { my $self = shift; my %p = @_; # Do something with message in $p{message} } 1; =head1 DESCRIPTION This module is the base class from which all Log::Dispatch::* objects should be derived. =head1 CONSTRUCTOR The constructor, C, must be overridden in a subclass. See L for a description of the common parameters accepted by this constructor. =head1 METHODS This class provides the following methods: =head2 $output->_basic_init(%p) This should be called from a subclass's constructor. Make sure to pass the arguments in @_ to it. It sets the object's name and minimum level from the passed parameters It also sets up two other attributes which are used by other Log::Dispatch::Output methods, level_names and level_numbers. Subclasses will perform parameter validation in this method, and must also call the superclass's method. =head2 $output->name Returns the object's name. =head2 $output->min_level Returns the object's minimum log level. =head2 $output->max_level Returns the object's maximum log level. =head2 $output->accepted_levels Returns a list of the object's accepted levels (by name) from minimum to maximum. =head2 $output->log( level => $, message => $ ) Sends a message if the level is greater than or equal to the object's minimum level. This method applies any message formatting callbacks that the object may have. =head2 $output->_should_log ($) This method is called from the C method with the log level of the message to be logged as an argument. It returns a boolean value indicating whether or not the message should be logged by this particular object. The C method will not process the message if the return value is false. =head2 $output->_level_as_number ($) This method will take a log level as a string (or a number) and return the number of that log level. If not given an argument, it returns the calling object's log level instead. If it cannot determine the level then it will croak. =head2 $output->add_callback( $code ) Adds a callback (like those given during construction). It is added to the end of the list of callbacks. =head2 $dispatch->remove_callback( $code ) Remove the given callback from the list of callbacks. =head1 SUBCLASSING This class should be used as the base class for all logging objects you create that you would like to work under the Log::Dispatch architecture. Subclassing is fairly trivial. For most subclasses, if you simply copy the code in the SYNOPSIS and then put some functionality into the C method then you should be all set. Please make sure to use the C<_basic_init> method as described above. The actual logging implementation should be done in a C method that you write. B!>. =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/Code.pm0000644000175000017500000000446613162076057020045 0ustar autarchautarchpackage Log::Dispatch::Code; use strict; use warnings; our $VERSION = '2.67'; use Log::Dispatch::Types; use Params::ValidationCompiler qw( validation_for ); use base qw( Log::Dispatch::Output ); { my $validator = validation_for( params => { code => { type => t('CodeRef') } }, slurpy => 1, ); sub new { my $class = shift; my %p = $validator->(@_); my $self = bless { code => delete $p{code} }, $class; $self->_basic_init(%p); return $self; } } sub log_message { my $self = shift; my %p = @_; delete $p{name}; $self->{code}->(%p); } 1; # ABSTRACT: Object for logging to a subroutine reference __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::Code - Object for logging to a subroutine reference =head1 VERSION version 2.67 =head1 SYNOPSIS use Log::Dispatch; my $log = Log::Dispatch->new( outputs => [ [ 'Code', min_level => 'emerg', code => \&_log_it, ], ] ); sub _log_it { my %p = @_; warn $p{message}; } =head1 DESCRIPTION This module supplies a simple object for logging to a subroutine reference. =for Pod::Coverage new log_message =head1 CONSTRUCTOR The constructor takes the following parameters in addition to the standard parameters documented in L: =over 4 =item * code ($) The subroutine reference. =back =head1 HOW IT WORKS The subroutine you provide will be called with a hash of named arguments. The two arguments are: =over 4 =item * level The log level of the message. This will be a string like "info" or "error". =item * message The message being logged. =back =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/Types.pm0000644000175000017500000000420213162076057020263 0ustar autarchautarchpackage Log::Dispatch::Types; use strict; use warnings; use namespace::autoclean; our $VERSION = '2.67'; use parent 'Specio::Exporter'; use Log::Dispatch::Vars qw( %CanonicalLevelNames ); use Specio 0.32; use Specio::Declare; use Specio::Library::Builtins -reexport; use Specio::Library::Numeric -reexport; use Specio::Library::String -reexport; any_can_type( 'ApacheLog', methods => ['log'], ); declare( 'ArrayOfAddresses', parent => t( 'ArrayRef', of => t('NonEmptySimpleStr') ), ); coerce( t('ArrayOfAddresses'), from => t('NonEmptySimpleStr'), inline => sub {"[ $_[1] ]"}, ); declare( 'Callbacks', parent => t( 'ArrayRef', of => t('CodeRef') ), ); coerce( t('Callbacks'), from => t('CodeRef'), inline => sub {"[ $_[1] ]"}, ); any_can_type( 'CanPrint', methods => ['print'], ); { my $level_names_re = join '|', keys %CanonicalLevelNames; declare( 'LogLevel', parent => t('Value'), inline => sub { sprintf( <<'EOF', $_[1], $level_names_re ); %s =~ /\A(?:[0-7]|%s)\z/ EOF }, ); } declare( 'SyslogSocket', parent => t( 'Maybe', of => union( of => [ t('NonEmptyStr'), t('ArrayRef'), t('HashRef') ] ) ), ); 1; # ABSTRACT: Types used for parameter checking in Log::Dispatch __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::Types - Types used for parameter checking in Log::Dispatch =head1 VERSION version 2.67 =head1 DESCRIPTION This module has no user-facing parts. =for Pod::Coverage .* =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/Vars.pm0000644000175000017500000000334113162076057020075 0ustar autarchautarchpackage Log::Dispatch::Vars; use strict; use warnings; our $VERSION = '2.67'; use Exporter qw( import ); our @EXPORT_OK = qw( %CanonicalLevelNames %LevelNamesToNumbers @OrderedLevels ); ## no critic (Variables::ProhibitPackageVars) our %CanonicalLevelNames = ( ( map { $_ => $_ } qw( debug info notice warning error critical alert emergency ) ), warn => 'warning', err => 'error', crit => 'critical', emerg => 'emergency', ); our @OrderedLevels = qw( debug info notice warning error critical alert emergency ); our %LevelNamesToNumbers = ( ( map { $OrderedLevels[$_] => $_ } 0 .. $#OrderedLevels ), warn => 3, err => 4, crit => 5, emerg => 7, ); 1; # ABSTRACT: Variables used internally by multiple packages __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::Vars - Variables used internally by multiple packages =head1 VERSION version 2.67 =head1 DESCRIPTION There are no user-facing parts here. =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/Conflicts.pm0000644000175000017500000000163613162076057021113 0ustar autarchautarchpackage # hide from PAUSE Log::Dispatch::Conflicts; use strict; use warnings; # this module was generated with Dist::Zilla::Plugin::Conflicts 0.19 use Dist::CheckConflicts -dist => 'Log::Dispatch', -conflicts => { 'Log::Dispatch::File::Stamped' => '0.17', }, -also => [ qw( Carp Devel::GlobalDestruction Dist::CheckConflicts Encode Exporter Fcntl IO::Handle Module::Runtime Params::ValidationCompiler Scalar::Util Specio Specio::Declare Specio::Exporter Specio::Library::Builtins Specio::Library::Numeric Specio::Library::String Sys::Syslog Try::Tiny base namespace::autoclean parent strict warnings ) ], ; 1; # ABSTRACT: Provide information on conflicts for Log::Dispatch # Dist::Zilla: -PodWeaver Log-Dispatch-2.67/lib/Log/Dispatch/File.pm0000644000175000017500000001637513162076057020054 0ustar autarchautarchpackage Log::Dispatch::File; use strict; use warnings; our $VERSION = '2.67'; use IO::Handle; use Log::Dispatch::Types; use Params::ValidationCompiler qw( validation_for ); use Scalar::Util qw( openhandle ); use base qw( Log::Dispatch::Output ); # Prevents death later on if IO::File can't export this constant. *O_APPEND = \&APPEND unless defined &O_APPEND; sub APPEND {0} { my $validator = validation_for( params => { filename => { type => t('NonEmptyStr') }, mode => { type => t('Value'), default => '>', }, binmode => { type => t('Str'), optional => 1, }, autoflush => { type => t('Bool'), default => 1, }, close_after_write => { type => t('Bool'), default => 0, }, lazy_open => { type => t('Bool'), default => 0, }, permissions => { type => t('PositiveOrZeroInt'), optional => 1, }, syswrite => { type => t('Bool'), default => 0, }, }, slurpy => 1, ); # We stick these in $self as-is without looking at them in new(). my @self_p = qw( autoflush binmode close_after_write filename lazy_open permissions syswrite ); sub new { my $class = shift; my %p = $validator->(@_); my $self = bless { map { $_ => delete $p{$_} } @self_p }, $class; if ( $self->{close_after_write} ) { $self->{mode} = '>>'; } elsif ( $p{mode} =~ /^(?:>>|append)$/ || ( $p{mode} =~ /^\d+$/ && $p{mode} == O_APPEND() ) ) { $self->{mode} = '>>'; } else { $self->{mode} = '>'; } delete $p{mode}; $self->_basic_init(%p); $self->_open_file() unless $self->{close_after_write} || $self->{lazy_open}; return $self; } } sub _open_file { my $self = shift; ## no critic (InputOutput::RequireBriefOpen) open my $fh, $self->{mode}, $self->{filename} or die "Cannot write to '$self->{filename}': $!"; if ( $self->{autoflush} ) { $fh->autoflush(1); } if ( $self->{permissions} && !$self->{chmodded} ) { ## no critic (ValuesAndExpressions::ProhibitLeadingZeros) my $current_mode = ( stat $self->{filename} )[2] & 07777; if ( $current_mode ne $self->{permissions} ) { chmod $self->{permissions}, $self->{filename} or die sprintf( 'Cannot chmod %s to %04o: %s', $self->{filename}, $self->{permissions} & 07777, $! ); } $self->{chmodded} = 1; } if ( $self->{binmode} ) { binmode $fh, $self->{binmode} or die "Cannot set binmode on filehandle: $!"; } $self->{fh} = $fh; } sub log_message { my $self = shift; my %p = @_; if ( $self->{close_after_write} ) { $self->_open_file; } elsif ( $self->{lazy_open} ) { $self->_open_file; $self->{lazy_open} = 0; } my $fh = $self->{fh}; if ( $self->{syswrite} ) { defined syswrite( $fh, $p{message} ) or die "Cannot write to '$self->{filename}': $!"; } else { print $fh $p{message} or die "Cannot write to '$self->{filename}': $!"; } if ( $self->{close_after_write} ) { close $fh or die "Cannot close '$self->{filename}': $!"; delete $self->{fh}; } } sub DESTROY { my $self = shift; if ( $self->{fh} ) { my $fh = $self->{fh}; ## no critic (InputOutput::RequireCheckedSyscalls) close $fh if openhandle($fh); } } 1; # ABSTRACT: Object for logging to files __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::File - Object for logging to files =head1 VERSION version 2.67 =head1 SYNOPSIS use Log::Dispatch; my $log = Log::Dispatch->new( outputs => [ [ 'File', min_level => 'info', filename => 'Somefile.log', mode => '>>', newline => 1 ] ], ); $log->emerg("I've fallen and I can't get up"); =head1 DESCRIPTION This module provides a simple object for logging to files under the Log::Dispatch::* system. Note that a newline will I be added automatically at the end of a message by default. To do that, pass C<< newline => 1 >>. B If you are writing to a single log file from multiple processes, the log output may become interleaved and garbled. Use the L output instead, which allows multiple processes to safely share a single file. =for Pod::Coverage new log_message =head1 CONSTRUCTOR The constructor takes the following parameters in addition to the standard parameters documented in L: =over 4 =item * filename ($) The filename to be opened for writing. =item * mode ($) The mode the file should be opened with. Valid options are 'write', '>', 'append', '>>', or the relevant constants from Fcntl. The default is 'write'. =item * binmode ($) A layer name to be passed to binmode, like ":encoding(UTF-8)" or ":raw". =item * close_after_write ($) Whether or not the file should be closed after each write. This defaults to false. If this is true, then the mode will always be append, so that the file is not re-written for each new message. =item * lazy_open ($) Whether or not the file should be opened only on first write. This defaults to false. =item * autoflush ($) Whether or not the file should be autoflushed. This defaults to true. =item * syswrite ($) Whether or not to perform the write using L(), as opposed to L(). This defaults to false. The usual caveats and warnings as documented in L apply. =item * permissions ($) If the file does not already exist, the permissions that it should be created with. Optional. The argument passed must be a valid octal value, such as 0600 or the constants available from Fcntl, like S_IRUSR|S_IWUSR. See L for more on potential traps when passing octal values around. Most importantly, remember that if you pass a string that looks like an octal value, like this: my $mode = '0644'; Then the resulting file will end up with permissions like this: --w----r-T which is probably not what you want. =back =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/Handle.pm0000644000175000017500000000435513162076057020363 0ustar autarchautarchpackage Log::Dispatch::Handle; use strict; use warnings; our $VERSION = '2.67'; use Log::Dispatch::Types; use Params::ValidationCompiler qw( validation_for ); use base qw( Log::Dispatch::Output ); { my $validator = validation_for( params => { handle => { type => t('CanPrint') } }, slurpy => 1, ); sub new { my $class = shift; my %p = $validator->(@_); my $self = bless { handle => delete $p{handle} }, $class; $self->_basic_init(%p); return $self; } } sub log_message { my $self = shift; my %p = @_; $self->{handle}->print( $p{message} ) or die "Cannot write to handle: $!"; } 1; # ABSTRACT: Object for logging to IO::Handle classes __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::Handle - Object for logging to IO::Handle classes =head1 VERSION version 2.67 =head1 SYNOPSIS use Log::Dispatch; my $log = Log::Dispatch->new( outputs => [ [ 'Handle', min_level => 'emerg', handle => $io_socket_object, ], ] ); $log->emerg('I am the Lizard King!'); =head1 DESCRIPTION This module supplies a very simple object for logging to some sort of handle object. Basically, anything that implements a C method can be passed the object constructor and it should work. =for Pod::Coverage new log_message =head1 CONSTRUCTOR The constructor takes the following parameters in addition to the standard parameters documented in L: =over 4 =item * handle ($) The handle object. This object must implement a C method. =back =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/Base.pm0000644000175000017500000000373613162076057020044 0ustar autarchautarchpackage Log::Dispatch::Base; use strict; use warnings; use Scalar::Util qw( refaddr ); our $VERSION = '2.67'; ## no critic (Subroutines::ProhibitUnusedPrivateSubroutines) sub _apply_callbacks { my $self = shift; my %p = @_; my $msg = delete $p{message}; foreach my $cb ( @{ $self->{callbacks} } ) { $msg = $cb->( message => $msg, %p ); } return $msg; } sub add_callback { my $self = shift; my $value = shift; Carp::carp("given value $value is not a valid callback") unless ref $value eq 'CODE'; $self->{callbacks} ||= []; push @{ $self->{callbacks} }, $value; return; } sub remove_callback { my $self = shift; my $cb = shift; Carp::carp("given value $cb is not a valid callback") unless ref $cb eq 'CODE'; my $cb_id = refaddr $cb; $self->{callbacks} = [ grep { refaddr $_ ne $cb_id } @{ $self->{callbacks} } ]; return; } 1; # ABSTRACT: Code shared by dispatch and output objects. __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::Base - Code shared by dispatch and output objects. =head1 VERSION version 2.67 =head1 SYNOPSIS use Log::Dispatch::Base; ... @ISA = qw(Log::Dispatch::Base); =head1 DESCRIPTION Unless you are me, you probably don't need to know what this class does. =for Pod::Coverage add_callback =for Pod::Coverage remove_callback =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/File/0000775000175000017500000000000013162076057017504 5ustar autarchautarchLog-Dispatch-2.67/lib/Log/Dispatch/File/Locked.pm0000644000175000017500000000513613162076057021246 0ustar autarchautarchpackage Log::Dispatch::File::Locked; use strict; use warnings; our $VERSION = '2.67'; use Fcntl qw(:DEFAULT :flock); use base qw( Log::Dispatch::File ); sub log_message { my $self = shift; my %p = @_; if ( $self->{close_after_write} ) { $self->_open_file; } my $fh = $self->{fh}; flock( $fh, LOCK_EX ) or die "Cannot lock '$self->{filename}' for writing: $!"; # just in case there was an append while we waited for the lock seek( $fh, 0, 2 ) or die "Cannot seek to end of '$self->{filename}': $!"; if ( $self->{syswrite} ) { defined syswrite( $fh, $p{message} ) or die "Cannot write to '$self->{filename}': $!"; } else { print $fh $p{message} or die "Cannot write to '$self->{filename}': $!"; } flock( $fh, LOCK_UN ) or die "Cannot unlock '$self->{filename}'"; if ( $self->{close_after_write} ) { close $fh or die "Cannot close '$self->{filename}': $!"; delete $self->{fh}; } } 1; # ABSTRACT: Subclass of Log::Dispatch::File to facilitate locking __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::File::Locked - Subclass of Log::Dispatch::File to facilitate locking =head1 VERSION version 2.67 =head1 SYNOPSIS use Log::Dispatch; my $log = Log::Dispatch->new( outputs => [ [ 'File::Locked', min_level => 'info', filename => 'Somefile.log', mode => '>>', newline => 1 ] ], ); $log->emerg("I've fallen and I can't get up"); =head1 DESCRIPTION This module acts exactly like L except that it obtains an exclusive lock on the file while opening it. Note that if you are using this output because you want to write to a file from multiple processes, you should open the file with the append C (C<<< >> >>>), or else it's quite likely that one process will overwrite another. =head1 SEE ALSO L =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/Null.pm0000644000175000017500000000262613162076057020101 0ustar autarchautarchpackage Log::Dispatch::Null; use strict; use warnings; our $VERSION = '2.67'; use base qw( Log::Dispatch::Output ); sub new { my $class = shift; my $self = bless {}, $class; $self->_basic_init(@_); return $self; } sub log_message { } 1; # ABSTRACT: Object that accepts messages and does nothing __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::Null - Object that accepts messages and does nothing =head1 VERSION version 2.67 =head1 SYNOPSIS use Log::Dispatch; my $null = Log::Dispatch->new( outputs => [ [ 'Null', min_level => 'debug' ] ] ); $null->emerg( "I've fallen and I can't get up" ); =head1 DESCRIPTION This class provides a null logging object. Messages can be sent to the object but it does nothing with them. =for Pod::Coverage new log_message =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/lib/Log/Dispatch/Email.pm0000644000175000017500000001136613162076057020217 0ustar autarchautarchpackage Log::Dispatch::Email; use strict; use warnings; our $VERSION = '2.67'; use Devel::GlobalDestruction qw( in_global_destruction ); use Log::Dispatch::Types; use Params::ValidationCompiler qw( validation_for ); use base qw( Log::Dispatch::Output ); { # need to untaint this value my ($program) = $0 =~ /(.+)/; my $validator = validation_for( params => { subject => { type => t('Str'), default => "$program: log email", }, to => { type => t('ArrayOfAddresses') }, from => { type => t('SimpleStr'), optional => 1, }, buffered => { type => t('Bool'), default => 1, }, }, slurpy => 1, ); sub new { my $class = shift; my %p = $validator->(@_); my $self = bless { subject => delete $p{subject}, to => delete $p{to}, from => delete $p{from}, buffered => delete $p{buffered}, }, $class; $self->{buffer} = [] if $self->{buffered}; $self->_basic_init(%p); return $self; } } sub log_message { my $self = shift; my %p = @_; if ( $self->{buffered} ) { push @{ $self->{buffer} }, $p{message}; } else { $self->send_email(@_); } } sub send_email { my $self = shift; my $class = ref $self; die "The send_email method must be overridden in the $class subclass"; } sub flush { my $self = shift; if ( $self->{buffered} && @{ $self->{buffer} } ) { my $message = join q{}, @{ $self->{buffer} }; $self->send_email( message => $message ); $self->{buffer} = []; } } sub DESTROY { my $self = shift; if ( in_global_destruction() && $self->{buffered} && @{ $self->{buffer} } ) { my $name = $self->name(); my $class = ref $self; my $message = "Log messages for the $name output (a $class object) remain unsent but the program is terminating.\n"; $message .= "The messages are:\n"; $message .= " $_\n" for @{ $self->{buffer} }; } else { $self->flush(); } } 1; # ABSTRACT: Base class for objects that send log messages via email __END__ =pod =encoding UTF-8 =head1 NAME Log::Dispatch::Email - Base class for objects that send log messages via email =head1 VERSION version 2.67 =head1 SYNOPSIS package Log::Dispatch::Email::MySender; use Log::Dispatch::Email; use base qw( Log::Dispatch::Email ); sub send_email { my $self = shift; my %p = @_; # Send email somehow. Message is in $p{message} } =head1 DESCRIPTION This module should be used as a base class to implement Log::Dispatch::* objects that send their log messages via email. Implementing a subclass simply requires the code shown in the L with a real implementation of the C method. =for Pod::Coverage new log_message =head1 CONSTRUCTOR The constructor takes the following parameters in addition to the standard parameters documented in L: =over 4 =item * subject ($) The subject of the email messages which are sent. Defaults to "$0: log email" =item * to ($ or \@) Either a string or a list reference of strings containing email addresses. Required. =item * from ($) A string containing an email address. This is optional and may not work with all mail sending methods. =item * buffered (0 or 1) This determines whether the object sends one email per message it is given or whether it stores them up and sends them all at once. The default is to buffer messages. =back =head1 METHODS This class provides the following methods: =head2 $email->send_email(%p) This is the method that must be subclassed. For now the only parameter in the hash is 'message'. =head2 $email->flush If the object is buffered, then this method will call the C method to send the contents of the buffer and then clear the buffer. =head2 $email->DESTROY On destruction, the object will call C to send any pending email. =head1 SUPPORT Bugs may be submitted at L. I am also usually active on IRC as 'autarch' on C. =head1 SOURCE The source code repository for Log-Dispatch can be found at L. =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2017 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) The full text of the license can be found in the F file included with this distribution. =cut Log-Dispatch-2.67/perlcriticrc0000644000175000017500000000346413162076057016214 0ustar autarchautarchseverity = 3 verbose = 11 theme = core + pbp + bugs + maintenance + cosmetic + complexity + security + tests + moose program-extensions = pl t exclude = Subroutines::ProhibitCallsToUndeclaredSubs [BuiltinFunctions::ProhibitStringySplit] severity = 3 [CodeLayout::RequireTrailingCommas] severity = 3 [ControlStructures::ProhibitCStyleForLoops] severity = 3 [InputOutput::RequireCheckedSyscalls] functions = :builtins exclude_functions = sleep severity = 3 [RegularExpressions::ProhibitComplexRegexes] max_characters = 200 [RegularExpressions::ProhibitUnusualDelimiters] severity = 3 [Subroutines::ProhibitUnusedPrivateSubroutines] private_name_regex = _(?!build)\w+ [TestingAndDebugging::ProhibitNoWarnings] allow = redefine [ValuesAndExpressions::ProhibitEmptyQuotes] severity = 3 [ValuesAndExpressions::ProhibitInterpolationOfLiterals] severity = 3 [ValuesAndExpressions::RequireUpperCaseHeredocTerminator] severity = 3 [Variables::ProhibitPackageVars] add_packages = Carp Test::Builder [-Subroutines::RequireFinalReturn] # This incorrectly thinks signatures are prototypes. [-Subroutines::ProhibitSubroutinePrototypes] [-ErrorHandling::RequireCarping] # No need for /xsm everywhere [-RegularExpressions::RequireDotMatchAnything] [-RegularExpressions::RequireExtendedFormatting] [-RegularExpressions::RequireLineBoundaryMatching] # http://stackoverflow.com/questions/2275317/why-does-perlcritic-dislike-using-shift-to-populate-subroutine-variables [-Subroutines::RequireArgUnpacking] # "use v5.14" is more readable than "use 5.014" [-ValuesAndExpressions::ProhibitVersionStrings] # Explicitly returning undef is a _good_ thing in many cases, since it # prevents very common errors when using a sub in list context to construct a # hash and ending up with a missing value or key. [-Subroutines::ProhibitExplicitReturnUndef] Log-Dispatch-2.67/Makefile.PL0000644000175000017500000000722313162076057015553 0ustar autarchautarch# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.010. use strict; use warnings; use 5.006; use ExtUtils::MakeMaker; check_conflicts(); my %WriteMakefileArgs = ( "ABSTRACT" => "Dispatches messages to one or more outputs", "AUTHOR" => "Dave Rolsky ", "CONFIGURE_REQUIRES" => { "Dist::CheckConflicts" => "0.02", "ExtUtils::MakeMaker" => 0 }, "DISTNAME" => "Log-Dispatch", "LICENSE" => "artistic_2", "MIN_PERL_VERSION" => "5.006", "NAME" => "Log::Dispatch", "PREREQ_PM" => { "Carp" => 0, "Devel::GlobalDestruction" => 0, "Dist::CheckConflicts" => "0.02", "Encode" => 0, "Exporter" => 0, "Fcntl" => 0, "IO::Handle" => 0, "Module::Runtime" => 0, "Params::ValidationCompiler" => 0, "Scalar::Util" => 0, "Specio" => "0.32", "Specio::Declare" => 0, "Specio::Exporter" => 0, "Specio::Library::Builtins" => 0, "Specio::Library::Numeric" => 0, "Specio::Library::String" => 0, "Sys::Syslog" => "0.28", "Try::Tiny" => 0, "base" => 0, "namespace::autoclean" => 0, "parent" => 0, "strict" => 0, "warnings" => 0 }, "TEST_REQUIRES" => { "Data::Dumper" => 0, "ExtUtils::MakeMaker" => 0, "File::Spec" => 0, "File::Temp" => 0, "FindBin" => 0, "Getopt::Long" => 0, "IO::File" => 0, "IPC::Run3" => 0, "POSIX" => 0, "PerlIO" => 0, "Test::Fatal" => 0, "Test::More" => "0.96", "Test::Needs" => 0, "lib" => 0, "utf8" => 0 }, "VERSION" => "2.67", "test" => { "TESTS" => "t/*.t" } ); my %FallbackPrereqs = ( "Carp" => 0, "Data::Dumper" => 0, "Devel::GlobalDestruction" => 0, "Dist::CheckConflicts" => "0.02", "Encode" => 0, "Exporter" => 0, "ExtUtils::MakeMaker" => 0, "Fcntl" => 0, "File::Spec" => 0, "File::Temp" => 0, "FindBin" => 0, "Getopt::Long" => 0, "IO::File" => 0, "IO::Handle" => 0, "IPC::Run3" => 0, "Module::Runtime" => 0, "POSIX" => 0, "Params::ValidationCompiler" => 0, "PerlIO" => 0, "Scalar::Util" => 0, "Specio" => "0.32", "Specio::Declare" => 0, "Specio::Exporter" => 0, "Specio::Library::Builtins" => 0, "Specio::Library::Numeric" => 0, "Specio::Library::String" => 0, "Sys::Syslog" => "0.28", "Test::Fatal" => 0, "Test::More" => "0.96", "Test::Needs" => 0, "Try::Tiny" => 0, "base" => 0, "lib" => 0, "namespace::autoclean" => 0, "parent" => 0, "strict" => 0, "utf8" => 0, "warnings" => 0 ); unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { delete $WriteMakefileArgs{TEST_REQUIRES}; delete $WriteMakefileArgs{BUILD_REQUIRES}; $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; } delete $WriteMakefileArgs{CONFIGURE_REQUIRES} unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; WriteMakefile(%WriteMakefileArgs); sub check_conflicts { if ( eval { require './lib/Log/Dispatch/Conflicts.pm'; 1; } ) { if ( eval { Log::Dispatch::Conflicts->check_conflicts; 1 } ) { return; } else { my $err = $@; $err =~ s/^/ /mg; warn "***\n$err***\n"; } } else { print <<'EOF'; *** Your toolchain doesn't support configure_requires, so Dist::CheckConflicts hasn't been installed yet. You should check for conflicting modules manually by examining the list of conflicts in Log::Dispatch::Conflicts once the installation finishes. *** EOF } return if $ENV{AUTOMATED_TESTING} || $ENV{NONINTERACTIVE_TESTING}; # More or less copied from Module::Build return if $ENV{PERL_MM_USE_DEFAULT}; return unless -t STDIN && ( -t STDOUT || !( -f STDOUT || -c STDOUT ) ); sleep 4; }