У меня есть приложение для микросервиса, в котором я хочу записывать журналы качества обслуживания (QoS) - по одной строке журнала на вызов службы, независимо от того, какой вызов службы.Я также хочу, чтобы в каждом вызове были подробные вызовы с некоторым идентификатором, одинаковым в журналах QoS и подробных журналах.
Я не хочу изменять сигнатуру методов обслуживания для получения большего количества параметров.Скорее, я бы хотел как-то изменить стек удаленного взаимодействия, чтобы охватить все текущие и будущие вызовы службы.
Я следовал этому ответу и написал IServiceRemotingClient
, который использует AsyncLocal
длясохранить контекстную информацию.Это не позволяет мне проверять тип ответа и регистрировать трассировки стека исключений, например.
Мой вопрос заключается в том, есть ли способ обернуть вызов SF в мой собственный метод ближе к моему методу обслуживаниягде я могу регистрировать исключения и результаты, а не на уровне удаленного взаимодействия, где все уже упаковано в черный ящик
public class LoggingServiceRemotingClient: IServiceRemotingClient
{
IServiceRemotingClient standardClient;
...
public async Task<IServiceRemotingResponseMessage> RequestResponseAsync(IServiceRemotingRequestMessage requestMessage)
{
var callId = Guid.NewGuid();
try{
SetCallIdInAsyncLocal(callId); // trimmed down pseudo code
var response = await this.standardClient.RequestResponseAsync(requestMessage);
Log.Ok(callId); // trimmed down pseudo code
} catch (Exception x){
// this will never be hit because the response body was already created with an exception serialized in it.
// how do I catch such exceptions across all calls?
// also some calls a due to client errors, others are internal - a single place to differentiate would be nice.
Log.Fail(callId, x);
}
}
}
Сам сервис также будет использовать callId
для регистрации своего собственного процесса:
public class MyService: StatelessService, IMyService
{
public async Task<string> GetMeAString(string prefix)
{
Debug.Assert(prefix!=null); // this exception is a caller fault
Guid callId = GetFromAsyncLocal();
Log(callId, "Got a call here")
string result = prefix+": "+Guid.NewGuid().ToString();
Log(callId, "returning "+result);
return result;
}
}
Я не понимаю, почему AsyncLocal
работает здесь, но, видимо, работает.