2012-10-15 17 views
6

Szukałem na rejestrowanie usług WCF (w tym technologii, takich jak NLog i PostSharp), ale mam coś jeszcze nie rozwiązany ... Nie wiem, czy jestem brakuje coś oczywistego lub po prostu niemożliwe.usług WCF, rejestrowanie pionowo

Powiedzmy mam Poziom usług WCF z usługi połączeń internetowych 100+ punktów wejścia. Jeden z nich powoduje problem. Pod tym poziomem znajduje się warstwa logiki biznesowej i warstwa bazy danych. To, co chcę zrobić (jak sądzę), to włączyć rejestrowanie dla tego zgłoszenia serwisowego (które zawierałoby identyfikator działania dla korelacji), aby wszystkie połączenia z tą usługą były rejestrowane, a wszelkie komunikaty dziennika w niższych warstwach również były rejestrowane. Naprawdę nie chcę włączać rejestrowania na poziomie zespołu dla niższych poziomów, ponieważ będą one udostępniane przez wiele metod usług sieciowych.

Czy to w ogóle możliwe, za pośrednictwem istniejących ram lub przy użyciu coś jak CorrelationManager w twórczy sposób?

Odpowiedz

1

W log4net można ustawić właściwość w kontekście wątku, który będzie uwzględniony we wszystkich zdarzeniach rejestrowania dla wątku.

public class WcfServiceClass 
{ 
    public void ProblemServiceMethod() 
    { 
     using (log4net.ThreadContext.Stacks["logThisMethod"].Push("ProblemServiceMethod")) 
     { 
      // can also add the correlationId to the logs using this method. 
      // call business logic... 

     } 
    } 
} 

Następnie create a custom appender że filtry przez nią.

public class IfContextSetFilterAppender : log4net.Appender.AppenderSkeleton 
{ 
    protected override void Append(LoggingEvent loggingEvent) 
    { 
     bool logThisEntry = false; 
     string serviceMethodBeingLogged; 

     foreach (object p in loggingEvent.GetProperties()) 
     { 
      System.Collections.DictionaryEntry dEntry = (System.Collections.DictionaryEntry)p; 
      if (dEntry.Key == "logThisMethod") 
      { 
       logThisEntry = true; 
       serviceMethodBeingLogged = dEntry.Value.ToString(); 
      } 
     } 

     if (!logThisEntry) 
      return; // don't log it. 

     // log it. 
    } 
} 

To bardzo uproszczony (ale jasny) przykład tego pomysłu.

Gdybym był naprawdę buduje to na jak dużą skalę usługi jak opisujesz, to ja:

  1. Tworzenie zachowanie IOperationInvoker końcowego, który chwyta nazwę metody i ustawia wartość kontekstowe log4net za wszystkie połączenia jej zastosowany do.

  2. (Opcjonalnie) mają appender odczytu z app.config listę filtrów z wszystkich nazw metody usługi, które powinny być rejestrowane. (Jeśli są selektywne w jakich metod zachowania OperationInvoker są stosowane, appender nie potrzebuje tej złożoności.)

Robiąc zachowanie masz kilka opcji do kontrolowania rejestrowania na usługi produkcyjnej poprzez konfigurację sam nigdy nie dotykając kodu serwisowego.

+0

Dzięki! Dokładnie tego rodzaju rzeczy szukam. Idealnie chciałbym użyć NLog przez log4net, ponieważ wydaje się trochę bardziej aktywny, ale to jest dokładnie ten typ rzeczy, który zmusiłby mnie do zmiany zdania ... Czy używałeś takiego kodu w złości? Jak poradziłaby sobie z usługą wielowątkową? –

+0

log4net.ThreadContext używa lokalnej pamięci wątku. Dopóki wywołanie usługi nie przeskakuje wątków (read use asych), działa to znakomicie w środowisku wielowątkowym. Tak, zrobiłem kilka z nich dla prawdziwych produkcyjnych usług dla przedsiębiorstw. Ostatnim z nich było umieszczenie identyfikatora korelacji we wszystkich wpisach dziennika (wszystko, co zostało narysowane w wątku, może być uwzględnione we wzorcu konwersji aplikacji). Log4net nie jest bardzo aktywny, ponieważ brakuje go bardzo niewiele, a jego rozszerzenie jest bardzo dobrze udokumentowane. Jeśli możesz znieść, że został napisany przed lekami generycznymi, traktuje cię to dobrze. – ErnieL

+0

Dzięki Ernie. To było dokładnie to, czego szukałem! –

0

Można by stworzyć nowe źródło logowania dla danego zgłoszenia serwisowego, a następnie włączyć go do diagnostyki filtrować.

<system.diagnostics> 
    <sources> 
     <source name="Your.Source.Here" switchValue="Verbose"> 
     <listeners> 
      <add name="xml" /> 
     </listeners> 
     </source> 
    </sources> 
    <sharedListeners> 
     <add name="xml" type="System.Diagnostics.XmlWriterTraceListener" traceOutputOptions="LogicalOperationStack" initializeData="l:\logs\N4S.MSO.ADC.Host.svclog" /> 
    </sharedListeners> 
    </system.diagnostics> 
+0

Czy to nie oznacza, że ​​połączenia do ram rejestrowania w niższych warstwach będzie również wiedzieć, nazwę źródła? –

+0

Chris - btw, dzięki za dane wejściowe; mile widziane! –

Powiązane problemy