我正在使用 ServiceStack JsonApiClient 发出服务请求。
当 JsonApiClient 遇到不成功的状态代码(即 500)时,它会自动(正确)以错误级别记录到我的控制台或使用标准 ILoggerFactory 记录到日志,如下所示:
fail: ServiceStack.JsonApiClient[0]
SendAsync: InternalServerError
500 InternalServerError
Code: InternalServerError, Message: InternalServerError
我的问题是,当遇到 400 系列错误时,似乎会发生同样的事情(就我而言 - 这些通常是客户端问题,而不是服务器端问题)。
fail: ServiceStack.JsonApiClient[0]
SendAsync: NotFound
404 NotFound
Code: NotFound, Message: NotFound
因此,如果处理 GET 请求,但未找到结果,我预计对 API 使用者的有效响应将是 404。我真的不希望/需要将此记录为错误,因为它是预期的行为。
这是我在标准 ServiceStack 服务中用于重新创建此错误的代码(问题的最小可行重现) - 如果跨服务发生这种情况,则会发生相同的行为,并且错误由第一个服务方法中的 JsonApiClient 记录。请求和响应都没有实现 - 请求实现
IReturn<TResponse>
,响应实现 IHasResponseStatus
和 IHasStatusCode
public async Task<TestGetResponse> Get(TestGetRequest request)
{
JsonApiClient client = new JsonApiClient("http://localhost:8080");
Task<TestGetRequest2> response = client.SendAsync<TestGetRequest2>(new TestGetRequest2());
return new TestGetResponse { StatusCode = 200 };
}
public async Task<TestGetResponse2> Get(TestGetRequest2 request)
{
return new TestGetResponse2 { StatusCode = 404 };
}
我的问题是 - 如何阻止 JsonApiClient 以错误级别记录 400 系列响应代码?理想情况下,我仍然想记录这些,但在不同的级别(可能是信息或警告)。
我尝试通过向此方法添加委托来挂钩
ExceptionFilter
,但我似乎无法影响日志记录(除非我做错了什么!)。
我的日志在繁忙的生产系统中充斥着大量噪音,并且“真实”错误(500 系列错误)变得模糊不清。
任何帮助或指示将非常感激。
JsonApiClient中的所有异常都记录为异常错误,如果您使用 ASP .NET Core,它将使用 ASP .NET Core 的 ILoggerFactory
,其异常日志记录在概念上类似于:
var log = loggerFactory.CreateLogger(typeof(JsonApiClient));
log.LogError(default(EventId), exception, message);
这将允许您使用 ASP .NET 的 Core 日志记录过滤系统来过滤针对 JsonApiClient
类型记录的日志记录。此外,您可以使用装饰器模式让
JsonApiClient
使用自定义记录器,您可以控制
AppHost
中的日志内容,例如:
public override void Configure()
{
LogManager.LogFactory = new MyLoggingFactory(LogManager.LogFactory);
}
其中 MyLoggingFactory
仅返回
JsonApiClient
的自定义记录器,例如:
public class MyLoggingFactory(ILogFactory source) : ILogFactory
{
public ILog GetLogger(Type type)
{
var log = source.GetLogger(type);
return type == typeof(JsonApiClient)
? new MyLogger(log)
: log;
}
public ILog GetLogger(string typeName) => source.GetLogger(typeName);
}
您的自定义记录器可以检查异常和错误消息以忽略日志记录,否则调用底层日志记录提供程序,例如:
public class MyLogger(ILog log) : ServiceStack.Logging.ILog
{
public void Error(object message, Exception exception)
{
if (IgnoreException(message,exception)) return;
log.Error(message, exception);
}
public void Error(object message) => log.Error(message);
public void ErrorFormat(string format, params object[] args) => log.ErrorFormat(format, args);
public void Debug(object message) => log.Debug(message);
public void Debug(object message, Exception exception) => log.Debug(message, exception);
public void DebugFormat(string format, params object[] args) => log.DebugFormat(format, args);
public void Fatal(object message) => log.Fatal(message);
public void Fatal(object message, Exception exception) => log.Fatal(message);
public void FatalFormat(string format, params object[] args) => log.FatalFormat(format, args);
public void Info(object message) => log.Info(message);
public void Info(object message, Exception exception) => log.Info(message, exception);
public void InfoFormat(string format, params object[] args) => log.InfoFormat(format, args);
public void Warn(object message) => log.Warn(message);
public void Warn(object message, Exception exception) => log.Warn(message, exception);
public void WarnFormat(string format, params object[] args) => log.WarnFormat(format, args);
public bool IsDebugEnabled => log.IsDebugEnabled;
}