审计日志
一个简单的更改日志,旨在易于编写且非侵入性。
2004 年 3 月 7 日
这是我在 2000 年代中期进行的 进一步企业应用程序架构开发 编写的一部分。不幸的是,此后太多其他事情吸引了我的注意力,因此我没有时间进一步处理它们,而且在可预见的未来我也没有看到太多时间。因此,这些材料非常草稿形式,在我能够抽出时间再次处理它们之前,我不会进行任何更正或更新。
工作原理
审计日志是最简单,也是最有效的跟踪时间信息形式之一。其理念是,每当发生任何重要事件时,您都会写入一些记录,指示发生了什么以及何时发生。
审计日志可以采用多种物理形式。最常见的形式是文件。但是,数据库表也可以成为一个很好的审计日志。如果您使用文件,则需要一种格式。ASCII 形式有助于在没有特殊软件的情况下使其对人类可读。如果它是一个简单的表格结构,那么制表符分隔的文本既简单又有效。更复杂的结构可以通过 XML 很好地处理。
审计日志 易于编写,但难以阅读,尤其是在它变得很大时。偶尔的临时读取可以通过肉眼和简单的文本处理工具完成。更复杂或重复的任务可以通过脚本自动化。许多脚本语言非常适合处理文本文件。如果您使用数据库表,则可以保存 SQL 脚本以获取信息。
当您使用 审计日志 时,您应该始终考虑写出实际日期和记录日期。它们很容易生成,即使它们在 99% 的时间里可能相同,但 1% 的时间可以拯救您的生命。当您这样做时,请记住记录日期始终是当前处理日期。
何时使用它
审计日志 的魅力在于它的简单性。当您将 审计日志 与其他模式(例如 时间属性 和 时间对象)进行比较时,您会很快意识到这些替代方案为对象模型增加了许多复杂性,尽管这两种方法通常都比在所有地方使用 有效性 更擅长隐藏这种复杂性。
但正是处理 审计日志 的难度限制了它的使用。如果您每周根据历史数据的组合生成账单,那么所有用于处理日志的代码都将很慢且难以维护。因此,这一切都取决于时间信息的访问与您的常规软件流程的集成程度。集成越紧密,审计日志 的用处就越小。
请记住,您可以在模型的某些部分使用 审计日志,而在其他地方使用其他模式。您还可以使用 审计日志 来处理一个时间维度,而使用其他模式来处理另一个时间维度。因此,您可以使用 时间属性 处理属性的实际时间历史,并使用 审计日志 处理记录历史。
示例(Java)
一个简单的 审计日志 可以非常简单。
class Customer...
private String phone; public String getPhone() { return (phone == null) ? "none" : phone;} public void setPhone(String arg, MfDate changeDate) { log (changeDate, this, "change of phone", phone, arg); phone = arg; } public void setPhone(String arg) { setPhone(arg, MfDate.today()); } private static void log (MfDate validDate, Customer customer, String description, Object oldValue, Object newValue) { try { logfile().write(validDate.toString() + customer.name() + "\t" + description + "\t" + oldValue + "\t" + newValue + "\t" + MfDate.today() + "\n"); logfile().flush(); } catch (IOException e) {throw new ApplicationException ("Unable to write to log");} }
请注意,即使设置方法只使用实际时间,我也将记录日期 (MfDate.today
) 添加到日志中。我认为始终添加两个日期都是明智的,因为这样做很容易,而且如果您不添加它,您以后就无法重建它。
我将把在某个任意日期查找我的电话号码的脚本留作读者的练习。(显然,它太简单了,我无法在这里写出来……)