C中错误记录/通知库的设计注意事项

时间:2011-06-03 01:14:16

标签: c error-handling

我现在正在研究几个程序,并且对我调试程序和记录错误的一些随意方法感到沮丧。因此,我决定花几天时间编写一个错误库,我可以在我的所有程序中使用它。我在Windows中进行大部分开发,大量使用Windows API,但关键在于灵活性:理想情况下,此库需要保持灵活性,在Windows和类Unix环境中的控制台应用程序和GUI应用程序中提供程序员通知选项

我最初的想法是使用一个库,它根据当前环境使用预处理器条件包含windows和unix的头。例如,在win32应用程序中,不需要控制台错误消息通知(尽可能);相反,一个简单的

MessageBoxA/W(hWndParent, TEXT("Some error message that makes sense in context"), TEXT("Application Name"), MB_ICONERROR | MB_OK)

最有意义。另一方面,在linux上,事情有点复杂:

GtkWindow *w;
w = gtk_message_dialog_new(pOwner, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, TEXT("Some error message");
gtk_window_set_title(w, TEXT("Application Name"));

在任一操作中,简单的文件记录以及有关错误(函数,文件,行等)的更多信息在查明源和跟踪流时也很有用。

此外,应该可以进行日志记录:即使调用需要错误记录/通知的函数,也应该可以在程序中显示函数调用的顺序,如果该级别的日志记录被激活。

因此,我最初的考虑是拥有一个包含所有这些功能的库,并且通过预处理器条件的最小开销。我认为最好将其分解为几个结构:

  • “main”结构,传递给需要记录的主程序中的每个函数,并包含
    • 包含需要进行文件记录的状态代码的位掩码(例如,NOERROR | WARNING | CRITICALERROR或CRITICALERROR | CRASH)
    • 指向“输出”结构
    • 的指针
    • “错误信息”节点的链接列表
  • “输出”结构,用于处理打印到文件,显示消息框和打印到控制台
  • “错误信息”结构,包含有关错误的信息(函数,文件,行,消息,类型等)

这只是我对这个库的初步想法。您是否可以想到我应该包括的更多信息?对我来说另一个主要问题是错误添加的原子性:可能是另一个线程可能创建错误而不是记录错误的错误,因此我需要确保创建和添加错误节点实际上是一个原子操作。因此,互斥量很可能是我进行同步的方式。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

在不是CRITICALERROR |的情况下CRASH,应用程序将在日志记录调用后继续,将队列(线程安全的生产者 - 消费者队列)从每个日志结构排队到执行请求的操作的日志记录线程会更好。日志记录线程通常在处理后释放结构。一些优点:

1)为每个日志记录请求采取的操作将减少为mallocing结构,加载它并将其推送到队列中。如果磁盘暂时繁忙,或由于它在网络上而具有高延迟,或者实际上不可用,则调用线程将继续几乎正常运行。有了这个,因为日志已经打开而失败的应用程序集减少了。可以指示具有某些您无法重现的间歇性问题的用户打开记​​录器,几乎没有机会记录日志将影响正常操作,或者更糟糕的是,引入延迟来掩盖该错误。

2)出于与(1)相同的原因,即使在运行时,添加/更改记录器功能也要容易得多。例如,您可能希望每天限制日志文件的大小或引发新的日期/时间戳日志文件。 “正常”调用会在旧文件关闭且新文件打开时向调用线程引入长延迟。如果日志记录排队,那么您获得的只是队列日志结构数量的临时增加。

3)控制日志记录更容易。在GUI应用程序中,记录器可以有自己的表单,可以在其中修改日志记录选项。您可以拥有一个“立即创建新日志文件”按钮,当单击该按钮时,将“LOGCONTROL”结构排队到日志记录线程以及所有其他日志记录消息。当线程获取它时,它会打开一个新的日志文件。

4)转发日志消息相当容易。也许你想要观察记录的消息,以及将它们写入磁盘 - 排队一个'LOGCONTROL'结构,指示线程保存结构中传递的函数ptr,然后在将它们写入之后用后续的记录消息调用该函数。磁盘。传递的函数可以将消息排队到GUI以显示在“终端”类型窗口中(Windows上的PostMessage,Qt等具有类似的功能以允许将数据传递到GUI)。当然,在*** x上,您可以打开一个控制台窗口并“尾随f”日志文件,但这对于GUI用户来说似乎不是特别优雅,对于用户来说更难以管理,并且无论如何不能作为标准使用在Windows上,(有多少用户知道如何从控制台窗口复制粘贴并向您发送错误消息?)。

另一种可能性是可能会指示日志记录线程将日志文本流式传输到远程服务器 - 另一个“LOGCONTROL”结构可以将主机名/端口传递给记录器线程。由于排队的通信,打开与服务器的网络连接的临时延迟无关紧要。

5)“懒惰写作”和其他此类性能增强变得更容易,但是:

缺点:

1)主要的一点是当日志调用返回给请求者时,日志操作可能还没有发生。在CRITICALERROR |的情况下,这是非常坏的消息CRASH,在某些情况下甚至可以通过“普通”记录进度消息等来进行操作。在这些情况下应该有一个选项可以绕过并直接进行磁盘写入/刷新 - fOpen / CreateFile是一个单独的“Direct.log”,追加,写,冲洗,关闭。慢 - 但安全,以防万一应用程序在日志调用返回后爆炸。

2)更复杂,更多的开发,更多的条件,更大的API接口包括。

RGDS, 马丁

答案 1 :(得分:0)

您好我将它用于另一种语言,但您可以研究它并遵循其设计 http://www.gurock.com/smartinspect/

问候