2014-04-22 2 views
1

나는 많은 웹 페이지와 일부 WCF 서비스가 포함 된 웹 사이트를 운영하고 있습니다.log4net과 IHttpModule을 WCF 서비스와 함께 사용

MDC.Set("path", HttpContext.Current.Request.Path); 
string ip = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; 
if(string.IsNullOrWhiteSpace(ip)) 
    ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; 
MDC.Set("ip", ip); 

이 모듈은 내 영문 페이지에 잘 작동 :

나는 PreRequestHandlerExecute에 가입하고 다음과 같은 log4net MDC 변수의 수를 설정 로깅 IHttpModule 있습니다.

모듈을 WCF와 함께 사용하려면 web.config에서 aspNetCompatibilityEnabled = "true"를 설정하고 RequirementsMode = AspNetCompatibilityRequirementsMode를 서비스에 설정하십시오.

그러나 서비스 메소드가 호출 될 때 MDC는 더 이상 설정된 값을 포함하지 않습니다. PreRequestHandlerExecute에 로깅 메서드를 추가하여 설정 중인지 확인했습니다.

로그에서 PreRequestHandlerExecute 핸들러 메서드를 볼 수 있고 서비스 메서드 호출이 별도의 스레드에 있기 때문에 MDC가 값을 잃어 버리고 있다고 생각합니다.

게시물이 log4net using ThreadContext.Properties in wcf PerSession service 인 경우 log4net.GlobalContext를 사용하는 것이 좋지만 두 사용자가 동시에 모든 응용 프로그램에서 GlobalContext를 공유하는 경우 문제가 발생한다고 생각합니다.

이 방법을 사용할 수 있습니까?

답변

1

HttpContext에서 값을 가져 와서 log4net의 컨텍스트 개체 중 하나에 저장하는 대신 HttpContext에서 직접 값을 기록하지 않는 이유는 무엇입니까? 당신에게 도움이 될 몇 가지 기술에 대한 링크 된 질문에 대한 내 대답을 참조하십시오.

Capture username with log4net

당신이 내 대답의 맨 아래로 이동하는 경우, 당신은 최고의 솔루션이 될 수있는 것을 찾을 수 있습니다. log4net의 GlobalDiagnosticContext에 넣을 수있는 HttpContext 값 공급자 객체를 작성합니다. 우리가 처리하는 특별히 그렇지 않은 경우

예를 들어, 당신이, 내가 이름을 가정합니다 default 절에서

public class HttpContextValueProvider 
{ 
    private string name; 
    public HttpContextValueProvider(string name) 
    { 
    this.name = name.ToLower(); 
    } 

    public override string ToString() 
    { 
    if (HttpContext.Current == null) return ""; 

    var context = HttpContext.Current; 

    switch (name) 
    { 
     case "path": 
     return context.Request.Path; 
     case "user" 
     if (context.User != null && context.User.Identity.IsAuthenticated) 
      return context.User.Identity.Name; 
     case "ip": 
     string ip = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; 
     if(string.IsNullOrWhiteSpace(ip)) 
      ip = context.Request.ServerVariables["REMOTE_ADDR"]; 
     return ip; 
     default: 
     return context.Items[name]; 
    } 

    return ""; 
    } 
} 

(테스트되지 않은) 같은 것을 할 수는의 값을 나타냅니다 HttpContext.Current.Items 사전. Request.ServerVariables 및/또는 HttpContext 정보에 액세스 할 수있는 기능을 추가하여보다 일반적으로 만들 수 있습니다.

은 당신과 같이이 개체를 사용합니다 : 프로그램/웹 사이트/서비스 어딘가에

는 log4net의 글로벌 사전에 개체의 일부 인스턴스를 추가합니다. log4net이 사전의 값을 해석하면 값을 기록하기 전에 ToString을 호출합니다.

GDC.Set("path", new HttpContextValueProvider("path")); 
GDC.Set("ip", new HttpContextValueProvider("ip")); 

주, 당신은 log4net의 글로벌 사전을 사용하고 있지만, 사전에두고있는 개체는 기본적으로있는 HttpContext.Current 개체 주위에 래퍼, 그래서 당신은 항상 한 경우에도, 현재 요청에 대한 정보를 얻는 것 동시 요청을 처리하고 있습니다. 행운을 빈다!

+0

당신의 솔루션은 훌륭하게 작동했습니다. 감사합니다. Global.asax의 Application_Start 핸들러에 모든 GlobalContext 속성을 설정했습니다. – Aaron0

관련 문제