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