TL; DR - 跳到最后一段
背景
我正在执行一些数据驱动测试,并使用日志文件作为测试输出之一。它的工作原理是这样的 -
我的日志文件反映了这一点:
INFO - Start RunAllFilesInFolder
INFO - File1:
INFO - Some info
INFO - Executing Test 1
INFO - Validation A result
INFO - ...
INFO - ...
INFO - File2:
...
目前我使用/调用Log 4 net这样 -
static class LogHelper
{
internal static readonly log4net.ILog Log = log4net.LogManager.GetLogger
(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
}
// another file
using static Some.Namespace.LogHelper;
class SomeClass
{
Log.Info($"\t\tExecuting {t.Number}-{t.Name}");
}
其中indent =“\ t”,“\ t \ t”或“\ t \ t \ t”取决于测试所在的级别。
有没有办法重构对LogHelper.Log的调用,以便它考虑到一个静态的“缩进”,当我进入不同的测试级别而不明确指定每个调用中的缩进时,可以增加/减少? / p>
即。 能够在适用的地方打电话,如
Log.Indent.Increase();
或者
Log.Indent.Decrease();
将上述调用替换为仅使用 -
进行日志记录Log.Info($"Executing {t.Number}-{t.Name}");
答案 0 :(得分:1)
您可以使用stack trace长度,计算新行数:
int someSensibleMinimum = 3; //something that works for you
int count = Environment.StackTrace.Count(a => a=='\n');
var indent = new string('\t', Math.Max(0, count - someSensibleMinimum));
请注意,在Release中,它可能表现不同:
但是,由于优化期间发生的代码转换,StackTrace属性可能无法报告与预期一样多的方法调用。
或者,您可以使用此方法自动计算长度(伪代码):
int count = Environment.StackTrace.Count(a => a=='\n');
Look for stack length in dictionary<int,string> (length to indent string)
If found use it.
If not found, find the largest entry in dictionary where key < count
add new entry to dictionary one tab char longer
在代码中:
public sealed class IndentTracker
{
private readonly ThreadLocal<Dictionary<int, string>> _dictionaryLocal =
new ThreadLocal<Dictionary<int, string>>(() => new Dictionary<int, string>());
public string GetIndent()
{
Dictionary<int, string> dictionary = _dictionaryLocal.Value;
int count = Environment.StackTrace.Count(a => a == '\n');
if (!dictionary.Any())
{
string initialIndent = string.Empty;
dictionary.Add(count, initialIndent);
return initialIndent;
}
string indent;
if (dictionary.TryGetValue(count, out indent))
return indent;
string last = dictionary.OrderByDescending(k => k.Key).First(k => k.Key < count).Value;
string newIndent = last + '\t';
dictionary.Add(count, newIndent);
return newIndent;
}
}
登录增加深度顺序时,此方法有效。例如,如果您记录堆栈深度10,然后是5(之前没有记录堆栈深度5然后记录10),则会失败。