2012-10-16 6 views
1

로그가 생성 된 parallel.for 루프의 파일에 대해 일부 작업을 수행합니다. 하지만 어떤 작업이 특정 로그 항목을 만들 었는지 알아야합니다. 내 nlog-config에서 {ThreadID}를 사용하려고했지만 threadID가 parallel.for 루프에 의해 재사용되어 고유 식별자가없는 것으로 보입니다. 제안 사항 모든 파일에 고유 한 로그 식별자를 부여하는 방법 제안?Parellel 루프 및 Nlog

Basic 코드 :

Private Sub DoParallel 
Private Logger As NLog.Logger = NLog.LogManager.GetCurrentClassLogger 
Dim ListOfFolder as New List(of String) 
ListOfFolder.add("C:\Test.txt") 

Parallel.ForEach(listOfFolders, Sub(elem As String) 
    logger.warn("Doing stuff, need to know on which elem it is done") 
    End Sub) 
End Sub 

Nlog 구성은 :

layout="${threadid} | ${time} | ${level:uppercase=true} | ${logger} | ${message} | ${exception}" 

답변

1

당신은 Trace.CorrelationManager.ActivityId를 사용하여 시도 할 수 있습니다. 값을 설정 한 다음 사용자 지정 NLog LayoutRenderer를 사용하여 해당 값을 출력 로그에 렌더링 할 수 있습니다. this here on SO을 수행하는 LayoutRenderer의 예를 찾을 수 있습니다. 최고 대답 중간에보세요.

다음은 해당 게시물의 LayoutRender 코드입니다 (NLog 1.0이 아닌 NLog 2.0을 대상으로 작성되었으므로 업데이트하기가 어렵지 않음).

[LayoutRenderer("ActivityId")] 
class ActivityIdLayoutRenderer : LayoutRenderer 
{ 
    int estimatedSize = Guid.Empty.ToString().Length; 

    protected override void Append(StringBuilder builder, LogEventInfo logEvent) 
    { 
    builder.Append(Trace.CorrelationManager.ActivityId); 
    } 

    protected override int GetEstimatedBufferSize(LogEventInfo logEvent) 
    { 
    return estimatedSize; 
    } 
} 

귀하의 NLog.config는 다음과 같이 보일 것입니다 :

당신의 NLog 확장이 있습니다 NLog주기 : 원래 샘플 코드를 사용

<extensions> 
    <add assembly="MyNLogExtensions"/> 
</extensions> 

layout="${threadid} | ${ActivityId} | ${time} | ${level:uppercase=true} | ${logger} | ${message} | ${exception}" 

를,이 같은 로그 수 :

Private Sub DoParallel 
Private Logger As NLog.Logger = NLog.LogManager.GetCurrentClassLogger 
Dim ListOfFolder as New List(of String) 
ListOfFolder.add("C:\Test.txt") 

Trace.CorrelationManager.ActivityId = Guid.Empty; 
Parallel.ForEach(listOfFolders, Sub(elem As String) 
    Trace.CorrelationManager.ActivityId = Guid.NewGuid(); 
    logger.warn("Doing stuff, need to know on which elem it is done") 
    Trace.CorrelationManager.ActivityId = Guid.Empty; 
    End Sub) 
End Sub 

각 로깅 문을 고유하게 식별해야하며, 사용자 작업의 코드 라인을 표시하면 해당 액션 실행의 모든 ​​로깅 문은 동일한 GUID로 태그가 지정됩니다.

이 방법을 사용하면 쉽게 IDisposable 클래스에 ActivityId 설정/설정을 래핑하고 using 문을 사용하여 프로세스를 자동화 할 수 있습니다.

Parallel.ForEach(listOfFolders,() => 
{ 
    using(new ActivityIdContext()) 
    { 
    logger.Warn("Hello! I hope the ActivityId helps!"); 
    } 
}); 
+0

는 와우 멋지다는 (C#으로, 다시) 이런 일을 할 수있는 Parallel.ForEach 동작의 몸을 둘러싸 수있는, 그런

public class ActivityIdContext : IDisposable { Guid oldActivityId; public ActivityIdContext(Guid id) { oldActivityId = Trace.CorrelationManager.ActivityId; Trace.CorrelationManager.ActivityId = Guid.NewGuid(); } public ActivityIdContext() : this(Guid.NewGuid()) { } public Dispose() { Trace.CorrelationManager.ActivityId = oldActivityId; } } 

:

는 C#을 용서하십시오 ! 제 일은 오늘 끝났지 만, 내일 아침에 당신의 접근 방식을 시도 할 것입니다. 나는 당신의 일에 완전히 감명 받았으며, 대단히 감사합니다! –

+0

매력처럼 작동했습니다. 고마워요! –