2012-07-24 14 views
5

Sto creando una pagina di amministrazione che ha un paio di proprietà di logback che voglio impostare al volo, una delle quali è l'email di amministrazione a cui invio gli avvisi di sistema. L'api per lo SMTPAppender ha i metodi da aggiungere all'elenco di indirizzi "a" o li ottiene come un elenco, ma non ho trovato nulla da cancellare, rimuovere o aggiornare. Come dovrei farlo?Come aggiornare gli indirizzi "a" su un SMTPAppender in Logback?

vedo due opzioni attualmente:

  1. Una possibilità è di rimuovere l'appender e crearne uno nuovo con le nuove proprietà (sigh).
  2. Capire come configurare direttamente tramite Joran (forse lo schifo?).

Sto andando avanti con (2), ma si prega di postare se c'è un modo migliore. più

risposta

4

Forse hai finito con questo, ma ho solo bisogno di trovare un modo per impostare dinamico "a "Indirizzi, e questo argomento mi ha portato al modo (grazie all'idea di @gresdiplitude sulle proprietà di sistema e sui valori MDC), quindi sto condividendo la mia soluzione.

Sto utilizzando SMTPAppender per inviare piccoli report di esecuzione, ma questi devono essere inviati a caselle di posta diverse. La soluzione sembra senza parole, o almeno mi ha fatto molto piacere con il risultato.

mio logback.xml:

<!-- this is the trick: a converter to use on the "to" field pattern --> 
<conversionRule conversionWord="smtpTo" converterClass="com.example.logback.MyConverter" /> 
<appender name="SMTP" class="ch.qos.logback.classic.net.SMTPAppender"> 
    <!-- a filter to select just the log entries that will be sent by mail --> 
    <filter class="com.example.logback.MyFilter" /> 
    <!-- an evaluator, mine is like CounterBasedEvaluator from the manual: 
     http://logback.qos.ch/xref/chapters/appenders/mail/CounterBasedEvaluator.html 
    --> 
    <evaluator class="com.example.logback.MyEvaluator"> 
     <limit>25</limit> 
    </evaluator> 
    <!-- a discriminator to create a cyclic buffer for each mailing group I need --> 
    <discriminator class="com.example.logback.MyDiscriminator" /> 
    <!-- just matching buffer size to evaluator limit --> 
    <cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTrackerImpl"> 
     <bufferSize>25</bufferSize> 
    </cyclicBufferTracker> 
    <smtpHost>${smtp.host}</smtpHost> 
    <smtpPort>${smtp.port}</smtpPort> 
    <SSL>${smtp.ssl}</SSL> 
    <username>${smtp.username}</username> 
    <password>${smtp.password}</password> 
    <from>${smtp.from}</from> 

    <!-- here you use the converter: in this case will get data 
     from marker containing the destination addresses 
    --> 
    <to>%smtpTo</to> 
    <subject>my subject</subject> 
    <layout class="ch.qos.logback.classic.PatternLayout"> 
     <pattern>%date: %message%n%xThrowable{full}</pattern> 
    </layout> 
</appender> 

MyFilter.java:

public FilterReply decide(ILoggingEvent event) { 
    return event.getMarker() != null 
      && event.getMarker().contains("REPORT") ? FilterReply.ACCEPT 
      : FilterReply.DENY; 
} 

MyDiscriminator.java:

public String getDiscriminatingValue(ILoggingEvent e) { 
    Marker marker = e.getMarker(); 
    if (marker == null || !(marker instanceof MyMarker)) { 
     return null; 
    } 
    return ((MyMarker) marker).getDiscriminatingValue(); 
} 

MyConverter.java:

public class MyConverter extends ClassicConverter { 

    @Override 
    public String convert(ILoggingEvent event) { 
     Marker marker = event.getMarker(); 
     if (marker == null || !(marker instanceof MyMarker)) { 
      return null; 
     } 
     return ((MyMarker) marker).getSmtpTo(); 
    } 
} 

MyMarker.java:

public interface MyMarker extends Marker { 
    // a list of destination addresses, like "[email protected], [email protected]" 
    String getSmtpTo(); 
    // an "id" to tell the buffers apart, could be "smtpTo" itself 
    // but in my case it would mix different reports that goes to the same addresses 
    String getDiscriminatingValue(); 
} 

Ho appena creato un'implementazione per MyMarker, e utilizzato più istanze di esso su ogni dichiarazione di registrazione che devono essere segnalati:

// suggestion: make the marker immutable, then you can store and reuse them instead of recreating them every time 
Marker marker1 = new MyMarkerImpl(
    "REPORT", // marker name 
    "[email protected], [email protected]", // smtpTo 
    "alertGroup"); // discriminatingValue 
logger.warn(marker1, "SNAFU"); 
Marker marker2 = new MyMarkerImpl(
    "REPORT", "[email protected], [email protected]", "phbGroup"); 
logger.info(marker2, "Everything is fine"); 
// here we have same smtpTo as above but different discriminatingValues, so this will be sent in another email/report 
Marker marker3 = new MyMarkerImpl(
    "REPORT", "[email protected], [email protected]", "bugFixingGroup"); 
logger.error(marker3, "Why things gone bad", exception); 

spero che possa essere utile.

+1

Questo è grande.L'implementazione di questa funzione era stata sospinta, pensando che alla fine sarebbe stato implementato un modo migliore per farlo, o un lavoro in giro pubblicato. Per ora, penso che questo sia l'approccio migliore. Tuttavia, ho un enum che uso con tutti i marcatori "vivi" nell'applicazione memorizzata in essi. Renderò i marker mutabili, ma avrò solo un'istanza. – Noremac

+0

@Noremac Questo è un approccio semplice, tuttavia non mi piacciono le enfasi mutevoli di alcun tipo. Potrebbe anche portare a problemi di condizioni di gara se l'applicazione è multithread, un'applicazione Web che attiva la registrazione SMTP su richiesta dell'utente o un ambiente cluster. La mia strada è solitamente la creazione di marker immutabili che avvolgono marker semplici distaccati e li memorizzano per tutto il tempo necessario. Buono a sapersi potrebbe essere utile per te =) – mdrg

4

due opzioni mi viene in mente:

1/Imposta indirizzo aggiornato come una proprietà di sistema, e configurare il SMTPAppender di valutare l'indirizzo smtpTo utilizzando la proprietà di sistema in questo modo

<to>%property{smtpTo}</to> 

O 2/Impostare l'indirizzo aggiornato da qualche parte nel database/proprietà di sistema. Inserire l'indirizzo smtpTo nella MDC per ogni thread, e configurare il SMTPAppender di ottenere da MDC in questo modo

<to>%X{smtpTo}</to> 
4

lo faccio come questo:

smtpappender.getToList().clear(); 
+0

Grazie, stavo cercando di cancellare getToAsListOfString e non funzionava. – Hiro2k

Problemi correlati