>

내 서버 호출과 외부 웹 서비스에 대한 호출 간의 링크를 설정하기 위해 스레드에서 CorrelationID를 설정하려고합니다. 상관 관계 ID는 NLog의 논리적 컨텍스트 구조에 저장하는 GUID입니다 (논리적 컨텍스트는 스레드에서 잘 작동합니다).

아이디어는 내 서버에 대한 요청과이 요청으로 인해 다양한 웹 서비스에 대해 발행 한 해당 요청간에 공유되는 GUID를 갖도록하는 것입니다. MDLC와 NDLC를 모두 사용해 보았습니다.

문제는 첫 번째 요청에 대해서만 값이 올바르게 저장되고 서버에 대한 새 요청마다 GUID가 올바르게 생성 되더라도 이후의 모든 값에 대해 빈 값을 저장한다는 것입니다.

데이터베이스 나 파일에 로깅을 시도했습니다. 코드 내에 중단 점을 추가하거나 로깅 방법 주위에 System.Threading.Sleep을 추가하면 문제가 자체적으로 해결되는 것 같습니다. 이상한 점은 논리적 컨텍스트에서 값을 설정하는 메소드 전후에 Sleep을 추가 할 수 있으며 여전히 어느 쪽이든 작동한다는 것입니다. 슬립/브레이크 포인트를 제거하면 다시 끊어 질 수 있습니다.

NLog v4.5.2를 사용하고 있습니다.

로깅 모듈 :

using System;
using System.Web;
using NLog;
namespace Shift.Stardust.Engine.Modules
{
    public class LoggingHttpModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.BeginRequest += HandleBeginRequest;
        }
        public void Dispose()
        {
        }
        private void HandleBeginRequest(object sender, EventArgs e)
        {
            System.Threading.Thread.Sleep(500);
            var guid = Guid.NewGuid().ToString();
            NestedDiagnosticsLogicalContext.Push(guid);
        }
    }
}


HandleBeginRequest의 어느 곳에 나 중단 점을 배치하면 올바른 출력이 생성됩니다. 마찬가지로 System.Threading.Thread.Sleep (500)을 추가합니다. 당연히이 문제를 해결하기 위해 코드에 이러한 줄을 추가하고 싶지 않습니다.

NLog 설정 :

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" internalLogFile="c:\temp\nlog-internal.txt" internalLogLevel="Trace">
  <variable name="logDirectory" value="${basedir}/logs"/>
  <targets>
    <target name="asyncdatabase"
            xsi:type="AsyncWrapper"
            queueLimit="5000"
            overflowAction="Block">
        <target xsi:type="Database"
                connectionStringName="ConnectionStringHere"
                keepConnection="true">
            <commandText>[db].[P_Log_Insert] @CreateDate, @ApplicationName, @MachineName, @LoggerName, @LogLevel, @Message, @Exception, NULL, @EngineSessionId, @CorrelationId</commandText>
            <parameter name="@CreateDate" layout="${date}"/>
            <parameter name="@ApplicationName" layout="${appsetting:name=Shift.Stardust.ApplicationName}"/>
            <parameter name="@MachineName" layout="${machinename}"/>
            <parameter name="@LoggerName" layout="${logger}"/>
            <parameter name="@LogLevel" layout="${level}"/>
            <parameter name="@Message" layout="${message}"/>
            <parameter name="@Exception" layout="${exception:format=tostring}"/>
            <parameter name="@EngineSessionId" layout="${aspnet-sessionid}"/>
            <parameter name="@CorrelationId" layout="${ndlc}"/>
        </target>
    </target>
  </targets>
  <rules>
    <logger name="Http.*" minlevel="Info" writeTo="asyncdatabase" final="true" />
  </rules>
</nlog>

수신 요청마다 서로 다른 CorrelationID를 가질 것으로 예상되지만 이는 첫 번째 요청에만 해당됩니다. 이후의 모든 문자열에는 값으로 빈 문자열이 있습니다.


  • 답변 # 1

    이 경우에는 HTTP 컨텍스트에 작성하는 것이 좋습니다.

    예 :

    HttpContext.Current.Items["myvariable"] = 123;
    
    

    및 사용법 :

    ${aspnet-item:variable=myvariable} - produces "123"
    
    

    문서 참조

    NLog.Web 패키지 (ASP.NET 비 코어)가 필요합니다.

    참고 : ASP.NET Core를 사용하려면 NLog.Web 대신 NLog.Web.AspNetCore를 사용해야합니다

  • 이전 PHP 키로 텍스트를 어떻게 인코딩/디코딩합니까?
  • 다음 objective c - iOS 8 베타 5 투데이 뷰 확장 (위젯)이 연결 대기 중에서 멈춤