2011-01-17 16 views
8

मैं क्रम में अपने प्रवेश के प्रबंध मॉड्यूल है, लेकिन सब कुछ एक अखंड कॉन्फ़िग फ़ाइल की चर्चा करते हुए बिना करना चाहते हैं। विभिन्न अनुमतियों के तहत चल रही प्रक्रियाओं से निपटने पर, मैं वास्तव में सिस्टम पर हर लॉग तक पहुंचने में सक्षम होने के लिए प्रत्येक प्रक्रिया से निपटना नहीं चाहता हूं, जब वे केवल उनके उप-समूह में लिख रहे हों।Log4perl: मैं रनटाइम पर गतिशील रूप से परिशिष्ट कैसे लोड करूं?

हालांकि, मुझे लॉग 4perl मैन्युअल में अतिरिक्त दस्तावेज़ों को रनटाइम पर कॉन्फ़िगरेशन फ़ाइल से प्रारंभ करने के तरीके पर अधिक प्रलेखन नहीं मिल रहा है। http://metacpan.org/pod/Log::Log4perl::Appender एक add_appender विधि का संदर्भ देता है, लेकिन यह फ़ाइलों को कॉन्फ़िगर करने के बजाय तत्काल एपेंडर ऑब्जेक्ट्स पर काम करता है। यह लॉगर ऑब्जेक्ट्स और लॉगर-> एपेंडर रिलेशनशिप को भी परिभाषित नहीं करता है।

मैंने प्रत्येक पैकेज को अपने स्वयं के confit से रखने की कोशिश की, लेकिन यह हर बार जब यह initalized मौजूदा कॉन्फ़िगरेशन clobbers।

my $foo = Foo->new() ## Checks Log::Log4perl::initialized(), sees that it 
        ## hasn't been initalized yet, inits Log4perl from foo.conf 
my $bar = Bar->new() ## Checks Log::Log4perl::initialized(), sees that it 
        ## has been initalized. Adds appenders and loggers defined 
        ## in bar.conf into the initialized configuration 

मैं कैसे पार्स और वर्तमान config में विन्यास जोड़ सकते हैं: की तर्ज पर कुछ मुझे क्या करना चाहते हैं?

संपादित करें: एक पैकेज वैरिएबल का उपयोग करने के साथ प्रोबेलम यह है कि यह विभिन्न वर्गों द्वारा खाया जाने वाला एक मूस भूमिका है, जो कि सिर्फ एक मूसएक्स :: भूमिका :: Making self-logging modules with Log::Log4perl में ईथर के उत्तर का पैरामीटर संस्करण है। इस प्रकार, मेरा लॉगर इसे उपभोग करने वाली लाइब्रेरी में बना रहा है, और मेरे पास वैश्विक वैरिएबल नहीं है जिसे मैं हर बार उपयोग करने पर काम कर सकता हूं।

हालांकि ..

अगर मैं MooseX :: भूमिका के बाहर एक वैश्विक चर घोषित :: Parameterized भूमिका ब्लॉक, प्रत्येक और हर वर्ग उस भूमिका की खपत है कि एक ही conf चर का उपयोग कर सकता है?

+0

कोई भी? मैंने Log4perl के लिए स्रोत पर थोड़ा सा देखा है लेकिन मैं ऐसा पहला व्यक्ति नहीं बन सकता जो कभी ऐसा करना चाहता था। मैं एक मूस भूमिका मैं वर्गों है कि मुझे भूमिका के लिए एक कॉन्फ़िग फ़ाइल पारित करने के लिए अनुमति देने के लिए आवेदन कर सकते हैं paramererized बनाने के लिए कोशिश कर रहा हूँ, और यह सिर्फ या तो conf फ़ाइल initing या वर्तमान प्रारंभ करने के लिए conf फ़ाइल config जोड़कर सही काम करता है Log4perl। – Oesor

+0

@ ओसर: मूस भूमिका में घोषित होने पर भी पैकेज वैश्विक वैश्विक है। भूमिकाओं का उपयोग करने के लिए नीचे दिए गए समाधान को संशोधित करना आसान होना चाहिए ('बिल्ड' तंत्र के बजाय आप 'इसी तरह के कोड के साथ' BUILDARGS' के आसपास 'उपयोग कर सकते हैं)। – bvr

+0

@ ओसर: प्रति पिछली टिप्पणी के नीचे अद्यतन कोड। – bvr

उत्तर

5

आप याद कर सकते हैं कि कौन सी कॉन्फ़िगरेशन फ़ाइलों को पहले ही लोड किया गया था (नीचे दिए गए कोड में %log_configs हैश)। जब नया वर्ग आता है, आप सभी कॉन्फ़िगरेशन पुन: पढ़ने, यह एक साथ मर्ज और Log::Log4perl init फिर init को स्ट्रिंग संदर्भ पैरामीटर का उपयोग कर सकते हैं।

मैं आमतौर पर आसान रखरखाव और पुनः लोड करने की क्षमता के कारण प्रति एप्लिकेशन एक लॉग कॉन्फ़िगरेशन पसंद करता हूं।

package Logger; 
use Moose::Role; 
use Log::Log4perl; 

our %log_configs =(); 

around BUILDARGS => sub { 
    my $orig = shift; 
    my $class = shift; 

    my $config_name = lc($class) . '.conf'; 

    # if the config is not integrated yet 
    if(! defined $log_configs{$config_name}) { 
     $log_configs{$config_name} = 1; 

     # reload all configs including new one 
     my $config_text = ''; 
     for my $file (sort keys %log_configs) { 
      $config_text .= "\n" . do { 
       local $/; # slurp 
       unless(open my $fh, "<", $file) { 
        warn "$file could not be open\n"; 
        ''; 
       } 
       else { 
        <$fh> 
       } 
      }; 
     } 

     # refresh config 
     Log::Log4perl::init(\$config_text); 
    } 

    return $class->$orig(@_); 
}; 


package Foo; 
use Moose; 
with 'Logger'; 
use Log::Log4perl ':easy'; 

sub BUILD { 
    ERROR 'Foo reporting'; 
} 


package Bar; 
use Moose; 
with 'Logger'; 
use Log::Log4perl ':easy'; 

sub BUILD { 
    INFO 'Bar reporting'; 
} 


package main; 

my $foo = Foo->new; 
my $bar = Bar->new; 
+1

यह उतना ही कम है कि मैं इसे कैसे करूंगा। शायद एक eval में init लपेटने के लिए एक अच्छा विचार है और अगर यह init में मर जाता है तो सबसे हालिया कॉन्फ़िगरेशन फ़ाइल ड्रॉप। खराब लॉगिंग कॉन्फ़िगरेशन फ़ाइल से कुछ भी बदतर नहीं है जो असंबद्ध अनुप्रयोगों को क्रैश कर रहा है। खराब कॉन्फ़िगरेशन फ़ाइल को इंगित करने के लिए% log_configs हैश में फ़्लैग मान जोड़ना मुश्किल नहीं होगा। –

+1

@ मार्क टोज़ी - वास्तविक आवेदन में इस तरह के दृष्टिकोण का उपयोग करने के लिए निश्चित रूप से उचित त्रुटि प्रबंधन जोड़ा जाना चाहिए। स्निपेट को सबूत-अवधारणा के रूप में देखें। एक और उपयोगी जोड़ा लॉग कॉन्फ़िगरेशन का नाम निर्दिष्ट करने के लिए एक संपत्ति हो सकती है, जो क्लास नाम के लिए डिफ़ॉल्ट है, बल्कि यह हार्ड-कोडेड नमूना (जो बीटीडब्ल्यू 'फू :: बार' जैसे नामांकित कक्षाओं के लिए काम नहीं करता है)। – bvr

5

हालांकि मैं यह से बचने के लिए, अगर मैं पार्स config अपने आप फ़ाइलें मैं तो http://search.cpan.org/perldoc?Log::Log4perl में प्रलेखित एपीआई के माध्यम से पर्ल में विन्यास का उपयोग कर सकते उम्मीद कर रही थी। है बस अपना स्वाद के लिए भी आश्चर्य की बात यह - अर्थात्,

######################## 
    # Initialization section 
    ######################## 
    use Log::Log4perl; 
    use Log::Log4perl::Layout; 
    use Log::Log4perl::Level; 

    # Define a category logger 
    my $log = Log::Log4perl->get_logger("Foo::Bar"); 

    # Define a layout 
    my $layout = Log::Log4perl::Layout::PatternLayout->new("[%r] %F %L %m%n"); 

    # Define a file appender 
    my $file_appender = Log::Log4perl::Appender->new(
          "Log::Log4perl::Appender::File", 
          name  => "filelog", 
          filename => "/tmp/my.log"); 

    # Define a stdout appender 
    my $stdout_appender = Log::Log4perl::Appender->new(
          "Log::Log4perl::Appender::Screen", 
          name  => "screenlog", 
          stderr => 0); 

    # Have both appenders use the same layout (could be different) 
    $stdout_appender->layout($layout); 
    $file_appender->layout($layout); 

    $log->add_appender($stdout_appender); 
    $log->add_appender($file_appender); 
    $log->level($INFO); 

अन्य विधि काम करता है, वहाँ भी कई चेतावनियां मेरे लिए इसे प्रयोग सहज हो गया है (जी मैं इस पुस्तकालय का इस्तेमाल किया, क्यों मेरी प्रवेश को रोकने के?) ।

इसके बजाय, मुझे लगता है कि मैं यह देखने जा रहा हूं कि क्या मैं कॉन्फ़िगरेशन फ़ाइल से लॉग इन नहीं कर सकता हूं लॉग इन करें: लॉग 4perl स्थिति Log::Log4perl::Config::PropertyConfigurator का उपयोग कैसे करें, जिसे कॉन्फ़िगरेशन फ़ाइल को पार्स करते समय -> init जरूरत है। यदि मैं लौटने वाली डेटा संरचना पर जाता हूं, तो मैं लॉगर-बाय-लॉगर और एपेंडर-बाय-एपेंडर आधार पर प्रारंभिक परिवर्तनों की तुलना कर सकता हूं और प्रारंभिक स्थिति को उचित रूप से संशोधित कर सकता हूं, नामस्थान टकरावों को सही तरीके से संभाल सकता हूं।

संबंधित मुद्दे

 संबंधित मुद्दे