2012-10-15 2 views
6

WCF 서비스 (NLog 및 PostSharp와 같은 기술 포함) 로깅을보고 있었지만 아직 해결하지 못한 것이 있습니다 ... 누락 된 부분이 있는지 모르겠습니다. 명백한 무언가 또는 그것은 단지 불가능합니다.WCF 서비스, 수직 로깅

100 개 이상의 웹 서비스 호출 진입 점이있는 WCF 서비스 계층이 있다고 가정 해 보겠습니다. 그 중 하나가 문제의 원인입니다. 이 계층 아래에는 비즈니스 로직 계층과 데이터베이스 계층이 있습니다. 내가하고 싶은 것은 서비스 호출 (상관 관계에 대한 활동 ID 포함)에 대한 로깅을 켜서 해당 서비스에 대한 모든 호출을 기록하고 하위 계층의 모든 로그 메시지도 기록하도록하는 것입니다. 하위 계층의 어셈블리 수준에서 로깅을 켜기를 정말로 원하지는 않습니다. 왜냐하면 하위 계층은 웹 서비스 메서드에서 공유되기 때문입니다.

기존 프레임 워크를 통해 또는 창조적 방식으로 CorrelationManager와 같은 것을 사용하여이 작업을 수행 할 수 있습니까?

답변

1

log4net에서 스레드에 대한 모든 로깅 이벤트에 포함될 등록 정보를 설정할 수 있습니다.

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... 

     } 
    } 
} 

그런 다음 필터가 적용되는 create a custom appender.

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. 
    } 
} 

매우 단순하지만 명확한 예입니다. 당신이 설명대로 정말 큰 규모로 서비스를이 구축 된 경우

, 내가 것 : 모든 호출에 대한

  1. 는 메소드 이름을 잡고와 log4net 컨텍스트 값을 설정하는 IOperationInvoker 엔드 포인트 동작을 만들기는 에 적용됨.

  2. (선택 사항) appender가 app.config에서 기록해야하는 모든 서비스 메소드 이름의 필터 목록을 읽도록합니다. (당신이 적용되는 어떤 메소드 OperationInvoker 동작을에 선택적 경우, 펜더는 이러한 복잡성을 필요로하지 않습니다.)

을 동작을함으로써 당신은 혼자가 구성을 통해 생산 서비스에 대한 로깅을 제어하기위한 몇 가지 옵션이 있습니다 서비스 코드를 건드리지 않아도됩니다.

+0

감사! 그게 정확히 제가 찾는 유형입니다. 이상적으로 Log4net보다 NLog를 사용하고 싶습니다. 좀 더 활성화 된 것 같습니다.하지만 이것은 내 마음을 바꿀 수있는 유형입니다. 분노에서 이와 같은 코드를 사용 했습니까? 멀티 스레드 서비스는 어떻게 처리할까요? –

+0

log4net.ThreadContext는 스레드 로컬 저장소를 사용합니다. 서비스 호출이 스레드를 건너 뛰지 않는 한 (읽기 사용 asych)이 기능은 다중 스레드 환경에서 훌륭하게 작동합니다. 예 저는 실제 프로덕션 엔터프라이즈 서비스에 대해이 중 몇 가지를 수행했습니다. 마지막으로 모든 로그 엔트리에 상관 ID를 두는 것이 었습니다 (ThreadContext에 푸시 된 모든 것이 appender의 변환 패턴에 포함될 수 있습니다). log4net은 매우 적게 누락되어 확장 성이 매우 잘 문서화되어 있기 때문에 매우 활성화되지 않았습니다. 당신이 위장 할 수 있다면 그것이 제네릭보다 먼저 쓰여졌다는 것을 잘 알고 있습니다. – ErnieL

+0

어니 감사합니다. 그게 정확히 제가 찾고있는 유형이었습니다! –

0

특정 서비스 호출에 대한 새 로깅 소스를 만든 다음 진단을 사용하여 해당 서비스 호출을 필터링 할 수 있습니다.

<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

하위 계층의 로깅 프레임 워크 호출도 소스 이름을 알아야한다는 의미는 아니겠습니까? –

+0

Chris - btw, 입력 해 주셔서 감사합니다; 대단히 감사합니다! –