2016-02-22 2 views
1

Я пытаюсь назначить глобальный запрос/идентификатор трассировки ко всем входящим запросам в ServiceStack api. Я решил эту проблему, добавив следующий запрос предварительного фильтра:Доступ к запросу ServiceStack за пределами контекста SS

PreRequestFilters.Add((request, response) => 
{ 
    var requestId = Guid.NewGuid(); 
    request.Items["RequestId"] = requestId; 
}); 

Что все работает прекрасно - я могу видеть идентификатор запроса в моей службы бегуна на заказ ServiceStack и все.

Проблема возникает, когда я хочу записать этот идентификатор запроса в мои журналы. Я использую NLog и создали следующий пользовательский визуализатор макета:

public class RequestIdLayoutRenderer : LayoutRenderer 
{ 
    protected override void Append(StringBuilder builder, LogEventInfo logEvent) 
    { 
     if (ServiceStackHost.Instance == null) return; 
     var request = ServiceStackHost.Instance.TryGetCurrentRequest(); 
     if (request == null) return; 

     object requestId; 
     if (!request.Items.TryGetValue("RequestId", out requestId)) return; 

     builder.Append(requestId); 
    } 
} 

Проблема: когда request возвращается, то Items коллекция, содержащая только ServiceStack элемент AspSessionIDManagerInitializeRequestCalled по умолчанию.

Мой вопрос: Является ли это предполагаемым поведением, и если да, то как я могу получить сбор Items «снаружи» в области ServiceStack? Есть ли лучший способ поделиться этим идентификатором запроса, чтобы NLog мог его забрать? Я уже пробовал MappedDiagnosticsContext в Nlog, но по странным причинам некоторые записи журнала не имеют RequestId, поэтому это попытка избежать использования контекста.

версия ServiceStack является 4.0.52 и .net версии 4.6 на Windows 10 Update 1. Nlog версии 4.

ответ

2

ServiceStack ASP.NET IRequest сохраняет локальную копию словаря Items, который первоначально, источником, но отсоединен от базовый запрос ASP.NET. Если вы хотите обмениваться данными за пределами контекста запроса ServiceStack, но в рамках одного и того же запроса ASP.NET, вы можете использовать однотонный HttpContext.Current, например:

PreRequestFilters.Add((request, response) => 
{ 
    var requestId = Guid.NewGuid(); 
    HttpContext.Current.Items["RequestId"] = requestId; 

    //Alternative API: 
    //var aspReq = (HttpRequestBase)request.OriginalRequest; 
    //aspReq.Items["RequestId"] = requestId; 
}); 

 Смежные вопросы

  • Нет связанных вопросов^_^