我使用PostSharp LogAttribute和log4net为所有被调用的方法生成跟踪。
输出很好,但我想在每一行上摆脱重复的标签Entering:
:
17:48:34,694 [Main ] Entering: LoginPopUp.LoginClick()
17:48:34,695 [Main ] Entering: UserRepository.GetUser()
17:48:34,695 [Main ] Entering: UserRepository.IsAdmin()
17:48:34,696 [Main ] Entering: SecurityManager.Encrypt()
从this answer开始,PostSharp团队显然不会添加消息格式自定义。
还有一个自定义TraceAttribute derived from OnMethodBoundaryAspect的示例 而且定制似乎更灵活。但问题是,在这种情况下,我会丢失显示嵌套级别的缩进(这对我来说比在每一行上输入单词更重要)。
最好的解决方案是扩展LogAttribute只是为了自定义前缀,但我不知道是否可能。
那么如何删除Entering:
前缀?
基于彼得答案的工作代码
static readonly Dictionary<Thread, int> DepthDictionary = new Dictionary<Thread, int>();
// Invoked at runtime before that target method is invoked.
public override void OnEntry(MethodExecutionArgs args)
{
int depth;
DepthDictionary.TryGetValue(Thread.CurrentThread, out depth);
Trace.WriteLine(getIndent(depth) + this.enteringMessage, this.category);
DepthDictionary[Thread.CurrentThread] = depth+1;
}
// Invoked at runtime after the target method is invoked (in a finally block).
public override void OnExit(MethodExecutionArgs args)
{
var depth = --DepthDictionary[Thread.CurrentThread];
Trace.WriteLine(getIndent(depth) + this.exitingMessage, this.category);
}
private string getIndent(int depth)
{
string result = "";
for (int i = 0; i < depth; i++) result += " ";
return result;
}
答案 0 :(得分:1)
当您的解决方案不是多线程时,您只需添加自己的身份:
// Invoked only once at runtime from the static constructor of type declaring the target method.
public override void RuntimeInitialize(MethodBase method)
{
string methodName = method.DeclaringType.FullName + method.Name;
this.enteringMessage = methodName;
this.exitingMessage = methodName;
}
static int depth = 0;
// Invoked at runtime before that target method is invoked.
public override void OnEntry(MethodExecutionArgs args)
{
Trace.WriteLine(getIndent()+this.enteringMessage, this.category);
depth++;
}
// Invoked at runtime after the target method is invoked (in a finally block).
public override void OnExit(MethodExecutionArgs args)
{
depth--;
Trace.WriteLine(getIndent()+this.exitingMessage, this.category);
}
private string getIndent(){
string result = "";
for (int i = 0; i < depth;i++) result += " ";
return result;
}
答案 1 :(得分:0)
可以在log4net自定义PatternLayoutConverter中使用string.Replace删除它,但它似乎不是最好的解决方案。
基于自定义TraceAttribute提供解决方案会很棒。