服务堆栈 - 如何禁用默认异常日志记录

本文关键字:异常 日志 记录 默认 何禁用 堆栈 服务 | 更新日期: 2023-09-27 18:31:50

根据ServiceStack文档,我们有一个全局服务异常处理程序。文档说这个处理程序应该记录异常然后调用DtoUtils.HandleException,就像这样:

private object LogServiceException(object request, Exception exception)
{
    var message = string.Format("Here we make a custom message...");
    _logger.Error(message, exception);
    return DtoUtils.HandleException(this, request, exception);
 }

这会导致错误被记录两次,因为DTOUtils.HandleException也以不太自定义的格式记录它。是的,我更喜欢这个而不是 DTOUtils 日志记录,并且不想只使用它。

我们如何在保留其余功能的同时关闭DTOUtils日志记录?没有人喜欢收到两倍的错误电子邮件。

服务堆栈 - 如何禁用默认异常日志记录

我希望

以下代码可以解决您的问题。

基于文档 New API, Custom Hooks, ServiceRunner

以及使用新 API 的 ServiceRunner 进行细粒度错误处理

in AppHost.configure

   LogManager.LogFactory = new ServiceStack.Logging.Support.Logging.ConsoleLogFactory();   

然后在应用主机类中

         public override IServiceRunner<TRequest> CreateServiceRunner<TRequest>(ActionContext      actionContext)
          {
               return new MyServiceRunner<TRequest>(this, actionContext);
            }  

在 ServiceRunner 类

       public class MyServiceRunner<T> : ServiceRunner<T>
       {
            public override object HandleException(IRequestContext requestContext, T request, Exception ex)
              {
                  if ( isYourCondition ) 
                  {
                        ResponseStatus rs = new ResponseStatus("error1", "your_message");
                        // optionally you can add custom response errors
                             rs.Errors = new List<ResponseError>();
                             rs.Errors.Add(new ResponseError());
                             rs.Errors[0].ErrorCode = "more details 2";
                            // create an ErrorResponse with the ResponseStatus as parameter
                            var errorResponse = DtoUtils.CreateErrorResponse(request, ex, rs);
                             // log the error
                             Log.Error("your_message", ex);
                             return errorResponse;
                   }
                   else
                        return base.HandleException(requestContext, request, ex);
               }
            }

如果您归还底座。HandleException,它在内部调用DtoUtils.HandleException。您将在控制台中看到,只有一个日志错误。

在客户端中,如果处理自定义错误的 Web 服务异常。

            catch (WebServiceException err)
            {
                if ( err.ResponseStatus.Errors != null)
               { // do something with err.ResponseStatus.Errors[0].ErrorCode; 
               }
            }

不要调用DtoUtils.HandleException,因为它会记录错误。也不要叫ServiceRunner.HandleException,它叫DtoUtils.HandleException.

调用 DtoUtils.CreateErrorResponse 进行响应(由 DtoUtils.HandleException 使用)。ToResponseStatus助手也在DtoUtils

我的AppServiceRunner现在如下所示:

public class AppServiceRunner<T> : ServiceRunner<T>
{
    public AppServiceRunner(AppHost appHost, ActionContext actionContext)
        : base(appHost, actionContext)
    {
    }
    public override object HandleException(IRequestContext requestContext,
        T request, Exception ex)
    {   
        LogException(requestContext, request, ex);
        var responseStatus = ex.ToResponseStatus();
        return DtoUtils.CreateErrorResponse(request, ex, responseStatus);
    }
    private void LogException(IRequestContext requestContext, T request, Exception ex)
    {
        // since AppHost.CreateServiceRunner can be called before AppHost.Configure
        // don't get the logger in the constructor, only make it when it is needed
        var logger = MakeLogger();
        var requestType = typeof(T);
        var message = string.Format("Exception at URI:'{0}' on service {1} : {2}",
            requestContext.AbsoluteUri, requestType.Name, request.ToJson());
        logger.Error(message, ex);
    }
    private static ILog MakeLogger()
    {
        return LogManager.GetLogger(typeof(AppServiceRunner<T>));
    }
}

现在我得到的唯一服务错误是这段代码生成的错误。