Domanda

Vorrei filtrare gli eventi di registro provenienti da un componente specifico di una libreria di terze parti, in base al contenuto del messaggio di registro. Voglio che questo filtro venga applicato solo quando l'evento di registro viene generato da un logger specifico: " org.restlet.Component.LogService " ;. Il filtro stesso è solo una corrispondenza di base rispetto al messaggio dell'evento registro.

Ho un AsyncAppender centrale che accede a più appendici. Nel caso in cui gli eventi provenienti da LogService non vengano filtrati, mi piacerebbe che venissero trattati allo stesso modo in cui sono ora, ovvero inviati ad AsyncAppender. Non voglio aggiungere un filtro ad AsyncAppender, perché questo sembra terribilmente inefficiente (non ho bisogno di filtrare TUTTI gli eventi, ma solo quelli provenienti dal logger LogService).

Quindi quello che ho provato a fare è associare il logger LogService a un Appender personalizzato, che a sua volta è associato a un filtro personalizzato:

    <appender name="filtered" class="mystuff.FilteredAppender">
            <filter class="mystuff.EventFilter"/>
            <appender-ref ref="ASYNC"/>
    </appender>

    <logger name="org.restlet.Component.LogService">
            <appender-ref ref="filtered"/>
    </logger>

L'errore che ottengo attualmente ...

  

log4j: ERRORE Nessun layout impostato per l'appender chiamato [filtrato].

... mi dice che c'è qualcosa che non va nel mio design: non credo che il mio appender personalizzato dovrebbe preoccuparsi del layout, dal momento che in realtà deve solo passare o non passare l'evento di registro. Inoltre, questo approccio richiede due classi personalizzate e una di esse (mystuff.FilteredAppender) non aggiunge alcun valore: è lì solo per contenere il filtro personalizzato.

Mi piacerebbe fare qualcosa di molto più pulito come ...

    <logger name="org.restlet.Component.LogService">
            <filter class="mystuff.EventFilter"/>
    </logger>

... ma apparentemente non è supportato dal framework log4j.

Esiste un buon modo pulito per filtrare gli eventi nel modo in cui voglio farlo?

È stato utile?

Soluzione

Questa voce della bacheca descrive una soluzione che sono riuscito a far funzionare. Sembra un peccato dover usare un AsyncAppender come portafiltri, ma sembra che sia l'opzione migliore senza creare un nuovo Appender personalizzato. Quindi finisco con:

    <appender name="filtered" class="org.apache.log4j.AsyncAppender">
            <filter class="mystuff.EventFilter"/>
            <appender-ref ref="ASYNC"/>
    </appender>

    <logger name="org.restlet.Component.LogService" additivity="false">
            <appender-ref ref="filtered"/>
    </logger>

Ma sarei sicuramente interessato se qualcuno fosse a conoscenza di un approccio ancora migliore. : -)

Altri suggerimenti

Log4J ha una Extras Library ( JavaDoc) che fornisce LoggerMatchFilter , per filtrare i nomi dei logger. È possibile impostare il nome del logger e se accettare o rifiutare (l'impostazione predefinita è accettare).

Nel metodo decide del filtro, confronta il nome del logger con LoggingEvent object.getLoggerName () per uguaglianza. È un filtro sorprendentemente semplice e ovvio e sono abbastanza sorpreso che non venga di default con Log4j.

In alternativa, se vuoi semplicemente mettere a tacere le librerie di terze parti, ho trovato utile quanto segue:

<!-- LOGGER NEUTER -->
<logger name="org.apache"><level value="WARN"/></logger>
<logger name="org.springframework"><level value="WARN"/></logger>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top