Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# wcf上的详细异常日志记录_C#_Wcf_Design Patterns_Exception Handling - Fatal编程技术网

C# wcf上的详细异常日志记录

C# wcf上的详细异常日志记录,c#,wcf,design-patterns,exception-handling,C#,Wcf,Design Patterns,Exception Handling,最近我正在开发一个WCF服务的异常日志模块。不幸的是,该服务还没有引入单元测试,因此出现了许多意外的异常。到目前为止,我已经实现了使用拦截器aproach获取异常,实现了IErrorHandler接口,并使用IServiceBehaviour将其绑定到服务接口。实际上我非常喜欢这个功能。但这让我进入了下一步,希望了解异常的细节。比如,异常发生在哪一行 我可以通过两种方式满足这个愿望: 通过使用一个变量来跟踪我成功通过的行,并将其包含在抛出的异常中 通过分别捕获所有行中的异常 但这两种方法在我看来

最近我正在开发一个WCF服务的异常日志模块。不幸的是,该服务还没有引入单元测试,因此出现了许多意外的异常。到目前为止,我已经实现了使用拦截器aproach获取异常,实现了
IErrorHandler
接口,并使用
IServiceBehaviour
将其绑定到服务接口。实际上我非常喜欢这个功能。但这让我进入了下一步,希望了解异常的细节。比如,异常发生在哪一行

我可以通过两种方式满足这个愿望:

  • 通过使用一个变量来跟踪我成功通过的行,并将其包含在抛出的异常中
  • 通过分别捕获所有行中的异常
    但这两种方法在我看来都很糟糕。我想知道是否有一个已知的设计模式或工具来实现这个目标

    在我看来,您可以尝试使用日志记录,例如log4net。然后你就可以知道他在哪里,发生了什么事。由于优化等过程中出现的“内联”,异常对象并不总是包含堆栈信息。

    包括服务的PDB文件,行号将包含在
    Exception.ToString()中。我们解决此问题的方法有两个方面:

  • 我们的服务是围绕命令的愚蠢包装。因此,当输入服务方法时,它会将其工作委托给命令
  • 我们将每个命令调用包装在一个日志代理中,该代理负责记录输入、输出和错误,并执行命令
  • 例如:

    public FooServiceModel GetFoo(int fooId)
    {
       return new ILogged<GetFooCommand>().Target.Execute(fooId);
    }
    
    调用本身由自定义log4net对象呈现器呈现:

    public class InvocationRenderer : IObjectRenderer
    {
        public void RenderObject(RendererMap rendererMap, object obj, TextWriter writer)
        {
            var invocation = (IInvocation)obj;
            var builder = new StringBuilder();
            builder.AppendFormat(
                "Invoking Method: {0} --> '{1}' with parameters (", 
                invocation.Method.DeclaringType != null 
                   ? invocation.Method.DeclaringType.FullName : "{Unknown Type}",
                invocation.Method);
    
            var parameters = invocation.Method
                .GetParameters()
                .Zip(invocation.Arguments, (p, a) => new { Parameter = p, Argument = a })
                .ToArray();
            var index = 0;
            foreach (var parameter in parameters)
            {
                builder.AppendFormat(
                    "{0}: {1}", 
                    parameter.Parameter.Name, 
                    rendererMap.FindAndRender(parameter.Argument));
    
                if (++index < parameters.Length)
                {
                    builder.Append(", ");
                }
            }
    
            builder.Append(")");
    
            writer.Write(builder.ToString());
        }
    }
    
    公共类调用渲染器:IObjectRenderer
    {
    公共void RenderObject(RenderMap RenderMap、对象对象对象、TextWriter)
    {
    变量调用=(IInvocation)obj;
    var builder=新的StringBuilder();
    builder.AppendFormat(
    调用方法:{0}-->'{1}'和参数(“,
    invocation.Method.DeclaringType!=null
    ?invocation.Method.DeclaringType.FullName:“{Unknown Type}”,
    调用方法);
    var参数=invocation.Method
    .GetParameters()
    .Zip(invocation.Arguments,(p,a)=>new{Parameter=p,Argument=a})
    .ToArray();
    var指数=0;
    foreach(参数中的var参数)
    {
    builder.AppendFormat(
    "{0}: {1}", 
    parameter.parameter.Name,
    FindAndRender(parameter.Argument));
    if(++索引

    希望这能给你一些解决这个问题的方法。

    谢谢,先生,我会检查一下这个工具。还有一个提示,为了使用它,你必须在web.config中定义一个配置部分,并在AssemblyInfo.cs[assembly:log4net.config.xmlconfigulator(Watch=true)]中附加以下行。在配置好log4net并准备好使用之后。我没有任何使用log4net工具的经验,所以我会研究它,然后我可能会根据您的建议找到解决方案。让我先了解一下log4net。
    public class InvocationRenderer : IObjectRenderer
    {
        public void RenderObject(RendererMap rendererMap, object obj, TextWriter writer)
        {
            var invocation = (IInvocation)obj;
            var builder = new StringBuilder();
            builder.AppendFormat(
                "Invoking Method: {0} --> '{1}' with parameters (", 
                invocation.Method.DeclaringType != null 
                   ? invocation.Method.DeclaringType.FullName : "{Unknown Type}",
                invocation.Method);
    
            var parameters = invocation.Method
                .GetParameters()
                .Zip(invocation.Arguments, (p, a) => new { Parameter = p, Argument = a })
                .ToArray();
            var index = 0;
            foreach (var parameter in parameters)
            {
                builder.AppendFormat(
                    "{0}: {1}", 
                    parameter.Parameter.Name, 
                    rendererMap.FindAndRender(parameter.Argument));
    
                if (++index < parameters.Length)
                {
                    builder.Append(", ");
                }
            }
    
            builder.Append(")");
    
            writer.Write(builder.ToString());
        }
    }