2012-04-16 2 views
1

현재 이벤트 인터셉터를 사용하여 aspect로 구현하고있는 이벤트/활동 로깅 시스템에서 작업 중입니다. 현재 시스템/프레임 워크는 각 메소드가 하나의 액티비티라고 가정하지만 액티비티가 여러 메소드 호출을 확장 할 수 있도록이 메소드를 확장하려고합니다. 이를 수행하기 위해, 염두에 두어야 할 첫 번째 접근법은 모든 관련 메소드 호출에 일부 컨텍스트를 제공하는 것입니다. 그러나 모든 메소드 호출이 Log4J의 MDC/NDC와 같은 단일 스레드의 컨텍스트 내에있는 경우에만이를 수행하는 방법을 알고 있습니다. 다중 스레드에 대한 컨텍스트를 제공 할 수있는 방법이 있습니까 (코드가 멀티 스레딩을 인식하지 않고있을 수 있음)?자바 - 여러 스레드에 대한 로깅 컨텍스트 만들기

답변

1

나는 내 코드에서 작동한다고 생각하는 InheritableThreadLocal을 발견했습니다. 이것은 모든 관련 스레드가 일부 상위/루트 스레드에서 생성된다고 가정합니다 (이는 안전한 가정이라고 생각합니다).

+1

그것으로 간단하지 않습니다. 한 가지 잠재적 인 문제는 다음과 같습니다. http://stackoverflow.com/questions/7296623/inheritablethreadlocal-and-thread-pools. 그래서 나는 항상 그런 맥락이 명시적인 방식으로 설정 될 필요가 있음을 강조한다. –

+0

지금 제안하고있는 유일한 문제는 현재 작업하고있는 응용 프로그램에 스레드가 명시 적으로 생성되어 있지 않다는 것입니다. 일부 제 3 자 API는 백그라운드에서 수행 할 수도 있지만 지금까지 내가 알고있는 API는 없습니다. 지금은 InheritableThreadLocal이 제공하는 다중 스레드 컨텍스트에 대한 제한된 지원이 무엇이든간에 상당히 만족합니다. 나는 당신의 제안에주의를 기울일 것이고 그래서 나는 미래에 그러한 문제들을 만날 때 나는 그것을 사용할 수있다. 감사. –

1

클래스 ThreadLocal? 이 sems는 실제로 이미 존재하는 코드에 cotext를 추가하는 TLS에 대해 유효하고 resonable 한 사용 일 수 있습니다.

+0

실제로 그게 내가 사용할 계획입니다. 멀티 스레딩을 계속 사용할 지 확실하지 않습니다. –

+0

ThreadLocal은 멀티 스레딩에서 특정 문제를 해결하는 것입니다. (그리고 내 답변에서 ContextManager는 일반적으로 ThreadLocal 내부에서 구현됩니다.) 생각해야 할 주요 문제는 컨텍스트 컨텐트를 다른 스레드로 전달하는 방법입니다. 앱을 멀티 스레드로 만드는 방법이 많이 있다는 것을 기억하십시오. 매번 새 스레드를 생성하는 것이 일반적으로 최악의 방법입니다. 멀티 스레딩을 수행하는 방법은 반드시 컨텍스트를 전파하는 방식에 영향을 미칩니다. –

4

"로깅"에 대해 생각하지 마십시오. 좀 더 근본적인 것으로 나아갑니다. 동일한 문맥에서 처리되는 여러 스레드에 의해 수행되는 작업을 원할 경우, 각 스레드가 어떤 컨텍스트에 있는지를 알 수 있도록 전파하는 것은 무엇입니까?

이 질문에 답할 수 있다면이 컨텍스트는 로깅을 위해 MDC/NDC에 넣어야하는 컨텍스트입니다 (컨텍스트 전체는 아니지만 그 컨텍스트의 핵심 정보 일 수 있음).

응용 프로그램에서 이러한 정보를 전달하지 않으면 누구나 사용자가 확인할 수있는 방법이 없습니다.


편집 : U 당신이 설정을 수행 할 수 방법에 대한 몇 가지 아이디어를 줄 수

. 그것은 그것을 더 강화하기 위해 AOP를 사용하는 것이 적절한 지 여부, 즉, 귀하의 추가 연구입니다 :)

// Assume I have a ContextManager which Context is stored in thread local: 

abstract class ContextAwaredJob implements Runnable { 
    public ContextAwaredJob() { 
    this.context = ContextManager.getCurrentContext(); 
    } 
    public void run() { 
    ContextManager.setCurrentContext(this.context); 
    doRun(); 
    } 
    protected abstract void doRun(); 
} 

당신은 새로운 "작업"이 부모 클래스를 확장하는 것입니다, 당신은 이것을 실행하는 경우 컨텍스트가 자동으로 설치됩니다 다른 스레드. (물론 디자인을 많이 다듬을 수는 있지만 무슨 일이 일어나는지에 대한 기본 아이디어를 제공합니다.)

+0

+1, 절대적으로. 그 맥락은 어쨌든 설정되어야합니다. –

+0

정확하게 이해할 수 있을지 모르겠습니다. 어쨌든,이 방식은 aspect 지향적이기 때문에 배경에 ContextManager, 즉 ContextManager를 추적하는 구성 요소가있을 것입니다. 그 같은 구조로하고 싶습니다, 아무리 어떤 메소드가 실행 되더라도, 원래의 실행 스택과 동일하거나 다른 스레드 내에서든 컨텍스트는 동일하게 유지됩니다. 나는 여기서 내가 이해할 수 있을지 확신하지 못한다. 멀티 스레딩에 대한 경험이별로 없습니다 (적어도 직접적으로는 그렇지 않습니다). –

+0

문제는 "원래 스택과 동일한 스레드 또는 다른 스레드 내에서 실행 중인지 여부"입니다. 일반적으로, 같은 스택 내의 메소드 호출 스택은 합리적으로 같은 맥락하에 있다고 여겨 질 수있다. 그러나 수행 할 다른 스레드가있을 때 u를 제외하면 올바른 컨텍스트를 알 수 없습니다. 예를 들어, 스레드 풀에 대한 작업을 실행하는 작업 디스패처가 있습니다."컨텍스트"를 사용자 세션으로 사용하려면 새 스레드의 컨텍스트를 설정해야합니다. 나는 특정 특정 fw 설치 특정 컨텍스트 그런 경우에 있지만 당신이 정말로 원하는 것을 알고 믿습니다 –

관련 문제