我一直在努力寻找在我们的应用程序中强制执行唯一错误消息的方法。也就是说,我想确切地知道哪行代码产生了错误,因此当用户联系支持时,我们会从记录的消息中知道错误的来源。
我发现this question给了我一个机制(使用guid来强制执行唯一性),但仍然存在一个问题:如何防止复制/粘贴重复? - 具体来说,开发人员复制记录行本身:
Log(<guid>, errorMessage);
在这种情况下,guid将被复制,不再有助于识别产生错误的唯一行。
我所拥有的一个实际工作的想法是编写一个由我们的构建服务器运行的工具,它将解析错误消息guid的代码,保留一个列表,并使构建复制失败。我想知道是否有更清洁的解决方案。
我考虑过的其他事情:
使用某种错误消息的中央列表有各种各样的想法,但我找不到解决复制/粘贴问题的方法。
还有许多方案需要以某种方式保留手动清单。我不想追求这样的事情,因为它会产生列表与列表之间存在差异的可能性。生产代码。
我也看到了使用堆栈跟踪的建议,但是我对安全性和安全性有点犹豫不决。表现原因。
答案 0 :(得分:1)
我不知道这是否真的是您正在寻找的,但您可以在日志消息中包含文件,方法,行号(以及其他内容),而无需您稍后搜索的唯一编号。如果您使用public void UpdateUser(UserList user, int timeoutMins)
{
using (var ctx = GetCodingContext())
{
try
{
ctx.Entry(user).State = System.Data.Entity.EntityState.Modified;
CR_USER_PROFILE timeoutProfile = GetTimeoutUserProfile(user.UserGUID);
if (timeoutProfile != null && !timeoutProfile.PROFILE_VALUE.Equals(timeoutMins.ToString()))
{
timeoutProfile.PROFILE_VALUE = timeoutMins.ToString();
UpdateUserProfile(timeoutProfile,ctx);
}
else if(timeoutProfile == null && timeoutMins > 0)
{
var timeoutKey = FFCEnumerations.Profiles.Keys.Timeout.GetStringValue();
AddUserProfile(user, timeoutKey, timeoutMins.ToString(), ctx);
}
ctx.SaveChanges();
}
catch (Exception ex)
{
throw new Exception("Error occurred updating user " + ex);
}
}
}
public void UpdateUserProfile(CR_USER_PROFILE profile, CodingContext ctx)
{
try
{
ctx.Entry(profile).State = System.Data.Entity.EntityState.Modified;
}
catch (Exception)
{
throw new Exception("Error occurred updating User Profile");
}
}
public CR_USER_PROFILE GetTimeoutUserProfile(Guid userGuid)
{
using (var ctx = GetCodingContext())
{
var timeoutKey = FFCEnumerations.Profiles.Keys.Timeout.GetStringValue();
var profileList = ctx.CR_USER_PROFILE.Where(p => p.UserGUID == userGuid && p.PROFILE_TYPE_CD == timeoutKey);
return profileList.SingleOrDefault();
}
}
类的源代码。这样,即使存在复制/粘贴违规,您仍然可以确切地知道System.Diagnostics.StackTrace
的来电来自哪里。
这是一个简单的示例,它返回堆栈跟踪项的文件名,方法签名和行号。请注意,此代码查找对“Log”方法的调用的堆栈跟踪项,并返回下一个。不久之后会更清楚:
Log
这是强制添加到日志中的堆栈跟踪信息的using System.Diagnostics; // Needed for the StackTrace class
private static string GetStackTraceInfo()
{
var stackTrace = new StackTrace(true).GetFrames();
// Find the item just after the call to teh 'Log' method:
var item = stackTrace?
.SkipWhile(st => !st.GetMethod().Name.Equals("Log"))
.Skip(1)
.FirstOrDefault();
return item == null
? string.Empty
: string.Format("{0} => {1}, line #{2}", Path.GetFileName(item.GetFileName()),
item.GetMethod(), item.GetFileLineNumber());
}
方法(这是我们在上面的代码中搜索的方法名称):
Log
一个示例用法:
private static void Log(int id, string message)
{
Console.WriteLine($"Error #{id}: {message} ({GetStackTraceInfo()})");
}
<强>输出强>