2012-05-24 12 views
34

मैं अपने एप्लिकेशन (स्प्रिंग इंटीग्रेशन), debug.log और main.log में दो लॉग फाइलें रखना चाहता हूं। मैं एक आईएनएफओ स्तर पर main.log को चलाने और डीबीयूजीजी स्तर पर डीबग.लॉग चलाने के लिए चाहता हूं। यह परिशिष्टों पर फ़िल्टर के साथ करने योग्य है। मैं स्रोत के आधार पर परिशिष्टों को विभिन्न स्तरों को लॉग करना चाहता हूं। दूसरे शब्दों मेंलॉगबैक: दो एपेंडर, एकाधिक लॉगर्स, विभिन्न स्तर

<logger name="org.springframework" level="ERROR"> 
    <appender-ref ref="main" /> 
</logger> 
<logger name="org.springframework" level="DEBUG"> 
    <appender-ref ref="debug" /> 
</logger> 
<logger name="com.myapp" level="INFO"> 
    <appender-ref ref="main" /> 
</logger> 
<logger name="com.myapp" level="DEBUG"> 
    <appender-ref ref="debug" /> 
</logger> 

तो संक्षेप में प्रस्तुत करने के लिए:

  1. स्प्रिंग लकड़हारा
    • मुख्य -> ​​त्रुटि
    • डिबग -> डीबग
  2. com.myapp लकड़हारा
    • मुख्य - > जानकारी
    • डिबग -> डीबग
इस मैं वालों डीबग पर चल रहा है और एक appender पर एक सीमा फिल्टर होनी चाहिए, क्योंकि की

पर्याप्त ठीक छोटाबीजवाला नहीं है।

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> 
     <level>INFO</level> 
    </filter> 
    <filter class="com.myapp.ThresholdLoggerFilter"> 
     <logger>org.springframework</logger> 
     <level>ERROR</level> 
    </filter> 
    </appender> 

निम्नलिखित कोड काम करता है

package com.myapp; 

import ch.qos.logback.classic.Level; 
import ch.qos.logback.classic.spi.ILoggingEvent; 
import ch.qos.logback.core.filter.Filter; 
import ch.qos.logback.core.spi.FilterReply; 

public class ThresholdLoggerFilter extends Filter<ILoggingEvent> { 
    private Level level; 
    private String logger; 

    @Override 
    public FilterReply decide(ILoggingEvent event) { 
     if (!isStarted()) { 
      return FilterReply.NEUTRAL; 
     } 

     if (!event.getLoggerName().startsWith(logger)) 
      return FilterReply.NEUTRAL; 

     if (event.getLevel().isGreaterOrEqual(level)) { 
      return FilterReply.NEUTRAL; 
     } else { 
      return FilterReply.DENY; 
     } 
    } 

    public void setLevel(Level level) { 
     this.level = level; 
    } 

    public void setLogger(String logger) { 
     this.logger = logger; 
    } 

    public void start() { 
     if (this.level != null && this.logger != null) { 
      super.start(); 
     } 
    } 
} 

उत्तर

39

एक ThresholdLoggerFilter वर्ग जो की तरह एक appender पर डाला जा सकता बनाने के लिए

अद्यतन जोड़ा स्पष्टता यदि आप रूट लॉगर से प्राप्त करने के इच्छुक हैं, उदाहरण के लिए यह कुछ और अधिक सरलता से करें यहां हम त्रुटियों के लिए एक अतिरिक्त लॉगर जोड़ते हैं, जो stderr पर लॉग इन करता है। यह केवल विशेष लॉगर्स के लिए सक्षम है।

<configuration> 
    <appender name="CONSOLE-stdout" class="ch.qos.logback.core.ConsoleAppender"> 
     <target>System.out</target> 
     <encoder> 
      <pattern>%d %-5level [%thread] %logger{0}: %msg%n</pattern> 
     </encoder> 
    </appender> 
    <appender name="CONSOLE-stderr" class="ch.qos.logback.core.ConsoleAppender"> 
     <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> 
      <level>ERROR</level> 
     </filter> 

     <target>System.err</target> 
     <encoder> 
      <pattern>%d %-5level [%thread] %logger{0}: %msg%n</pattern> 
     </encoder> 
    </appender> 
    <root level="DEBUG"> 
     <appender-ref ref="CONSOLE-stdout" /> 
    </root> 

     <!-- We want error logging from this logger to go to an extra appender 
      It still inherits CONSOLE-stdout from the root logger --> 
    <logger name="org.springframework" level="INFO"> 
     <appender-ref ref="CONSOLE-stderr" /> 
    </logger> 
</configuration> 
+1

सरल और साफ जवाब !! यह उदाहरण मेरी ज़रूरतों के लिए बिल्कुल सही था !!! – araknoid

+4

स्वयं को लागू करने की कोई आवश्यकता नहीं है, ch.qos.logback.classic.filter का उपयोग करें।थ्रेसहोल्डफ़िल्टर –

+2

थ्रेसहोल्डफ़िल्टर बस थ्रेसहोल्ड पर फ़िल्टर करता है। मैं एक लॉगर और थ्रेसहोल्ड –

15

तुम भी कर सकते हैं: सवाल

+0

धन्यवाद @artbristol, लेकिन यह मुझे नियंत्रण की ग्रैन्युलरिटी नहीं देता है। मैंने सवाल अपडेट किया है तो क्यों दिखाएं। –

0

अलग संदेशों के लिए एकाधिक वालों का उपयोग करते हुए इस तरह होगा:

import ch.qos.logback.classic.Level; 
import ch.qos.logback.classic.Logger; 

import ch.qos.logback.classic.Level; 
import ch.qos.logback.classic.Logger; 
import ch.qos.logback.classic.LoggerContext; 
import ch.qos.logback.classic.encoder.PatternLayoutEncoder; 
import ch.qos.logback.classic.spi.ILoggingEvent; 
import ch.qos.logback.core.FileAppender; 

public class ConfigureLogBack 
{ 
    public static void programmaticConfiguration() 
    { 
     Logger camel = getLogger("MyRoute", C:\\Users\\amrut.malaji\\Desktop\\Oracle\\logback\\camel-Log.txt"); 
     Logger services = getLogger("webservices", "C:\\Users\\amrut.malaji\\Desktop\\Oracle\\logback\\services-log.txt"); 
    } 

    private static Logger getLogger(String string, String file) { 
     LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); 
    PatternLayoutEncoder ple = new PatternLayoutEncoder(); 

    ple.setPattern("%date %level [%thread] %logger{10} [%file:%line] %msg%n"); 
    ple.setContext(lc); 
    ple.start(); 
    FileAppender<ILoggingEvent> fileAppender = new FileAppender<ILoggingEvent>(); 
    fileAppender.setFile(file); 
    fileAppender.setEncoder(ple); 
    fileAppender.setContext(lc); 
    fileAppender.start(); 

    Logger logger = (Logger) LoggerFactory.getLogger(string); 
    logger.addAppender(fileAppender); 
    logger.setLevel(Level.INFO); 
    logger.setAdditive(false); /* set to true if root should log too */ 

    return logger; 
} 
1

बस logback तत्वों का उपयोग कर एक व्यावहारिक समाधान नहीं मिला ही नहीं बहुत अच्छी तरह से, अनिवार्य रूप से आप दो appenders, के साथ एक की जरूरत है काम करता है डिफ़ॉल्ट config और (मेरे उदाहरण में मैं कंसोल उपयोग कर रहा हूँ) एक फिल्टर के साथ एक दूसरे को:

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
     <encoder> 
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> 
     </encoder> 
    </appender> 

    <appender name="WARN_FILTER_STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
     <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> 
      <level>WARN</level> 
     </filter> 
     <encoder> 
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> 
     </encoder> 
    </appender> 

    <logger name="org.apache.spark" level="INFO" additivity="false"> 
     <appender-ref ref="SPARK" /><!-- this line is not necessary, just here to ilustrate the need for the filter --> 
     <appender-ref ref="WARN_FILTER_STDOUT" /> 
    </logger> 

    <root level="info"> 
     <appender-ref ref="STDOUT" /> 
    </root> 
1

एक अतिरिक्त समाधान है कि क्या उसे पहले ही है की तुलना में आसान है जोड़ा जा रहा है ई

इनमें से कोई भी समाधान मेरे लिए काम नहीं करता है, क्योंकि मैं स्पार्क या स्प्रिंग जैसे ढांचे का उपयोग नहीं कर रहा हूं। तो मैंने कुछ आसान किया जो अच्छी तरह से काम करता प्रतीत होता है। हालांकि यह समाधान ओपी के लिए काम नहीं कर सकता है, शायद यह किसी ऐसे व्यक्ति के लिए उपयोग किया जा सकता है जो इतनी भारी नहीं है।

<property name="pattern" value="%d{yyyy.MMM.dd HH:mm:ss.SSS} [ProgramName] %level - %msg%n" /> 

<appender name="FILE" class="ch.qos.logback.core.FileAppender"> 
    <file>/path/to/your/program.log</file> 
    <append>true</append> 
    <encoder> 
     <pattern>${pattern}</pattern> 
    </encoder> 
</appender> 

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
    <target>System.out</target> 
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> 
     <level>INFO</level> 
    </filter> 
    <encoder> 
     <pattern>${pattern}</pattern> 
    </encoder> 
</appender> 

<root level="debug"> 
    <appender-ref ref="FILE" /> 
    <appender-ref ref="STDOUT" /> 
</root> 

इस कॉन्फ़िगरेशन के साथ, मैं लॉग फ़ाइल में DEBUG कथन को आउटपुट करते समय कंसोल को साफ रखने में सक्षम हूं।

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