using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
namespace VCommon.Diagnostics
{
public static class StackTraceExtensionMethod
{
/// 将堆栈跟踪信息格式化成每一帧都带程序集的详情文本, 可指定一个type来忽略之上的调用堆栈帧
public static string GetFormattedDetailStackTraceText(this StackTrace me, Type skipUpper = null, bool hasSourceStackFrameOnly = false)
{
var rawFrames = me.GetFrames();
if (null == rawFrames) return null;
var upperFrames = rawFrames;
if (null != skipUpper)
{
var lst = new List(rawFrames.Length);
for (var i = rawFrames.Length - 1; i >= 0; i--)
{
if (rawFrames[i].GetMethod().DeclaringType == skipUpper) break;
lst.Insert(0, rawFrames[i]);
}
upperFrames = lst.ToArray();
}
var sb = new StringBuilder();
var filteredFrames = upperFrames;
if (hasSourceStackFrameOnly)
{
filteredFrames = upperFrames.Where(p => p.HasSource()).ToArray();
}
foreach (var frame in filteredFrames)
{
var method = frame.GetMethod();
var type = method.DeclaringType;
var asm = type?.Assembly;
var filename = frame.GetFileName();
if (null != asm) sb.Append($"[{asm.GetName().Name}] ");
if (null != type) sb.Append($"{type.FullName}::");
sb.Append($"{method}");
if (null != filename) sb.Append($" @ {filename}:{frame.GetFileLineNumber()},{frame.GetFileColumnNumber()}");
sb.AppendLine();
}
return sb.ToString();
}
}
}