你可以嘗試使用Trace.CorrelationManager.ActivityId。您可以設置一個值,然後使用自定義NLog LayoutRenderer將該值呈現給輸出日誌。你可以找到一個this here on SO的LayoutRenderer的例子。在最佳答案的中間看看。
下面是從該職位的LayoutRender的代碼(注意,這是書面反對NLOG 1.0,而不是2.0 NLOG它不應該是很難更新)。
[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
這應該唯一標識每個記錄的語句,如果你爲m你的動作中的代碼行,所有來自給定執行動作的日誌語句都會被標記爲相同的guid。
如果這種方法對你的作品,你可以很容易地包裹ActivityId設置/在IDisposable接口類和解封使用using語句的過程自動化。
請原諒C#:
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;
}
}
然後,你可以附上Parallel.ForEach動作做這樣的事情的身體(同樣,在C#)
Parallel.ForEach(listOfFolders,() =>
{
using(new ActivityIdContext())
{
logger.Warn("Hello! I hope the ActivityId helps!");
}
});
哇,看起來很大!我的工作日今天結束,但明天早上我會嘗試你的方法。 我對你的工作印象深刻,非常感謝! –
像魅力一樣工作。非常感謝你! –