我是否可以应用特定的模式来收集多个操作的数据?
我正在尝试找出一种优雅的方法来收集跨多个类的多个操作/方法调用的信息以用于审计/历史目的。有人对如何收集这些数据有任何想法/意见吗?
对于我的具体示例,我需要与 Web 服务交互以同步两个系统之间的数据。这涉及几种不同的操作,这些操作可能会提供需要记录的有用信息。
为了下载数据,我需要;
- 与Web服务通信以获取数据。
- 要收集的数据;
- 网络服务查询的摘要信息(记录 ID、类型、上次更新时间等)
- 有关 Web 服务调用期间引发的任何异常的信息。
- 从网络服务检索数据(或异常)所需的时间(以秒为单位)
- 要收集的数据;
- 通过本地验证规则验证接收到的数据
- 要收集的数据;
- 验证错误。
- 如果有效,则接收到的数据的 XML 表示形式和同一对象的本地表示形式。
- 要收集的数据;
- 将验证后的数据保存到本地数据库
- 要收集的数据;
- 数据库调用期间的任何异常
- 要收集的数据;
- 保存审计/历史记录,详细说明上面收集的所有信息。
类似类型的数据在将信息上传到 Web 服务期间存储,我们在其中收集 Web 服务/数据库通信期间的异常、通过FaultException 从 Web 服务接收到的验证错误、Web 服务通信所花费的时间等。
对于我当前的解决方案,我目前创建了一个AuditHistory 对象带有占位符来存储各种信息,并将其传递给各种类方法并在每个方法调用期间填充它。最后,我只是保存这个审计历史对象。
它确实有效,但感觉又丑又笨重。
任何想法表示赞赏。
I am trying to work out an elegant way to collect information for audit/history purposes over multiple operations/method calls spanning multiple classes. Does anyone have any ideas/opinions on how this data should be collected?
For my specific example, I need to interact with a webservice to synchronise data between two systems. This involves several different operations that can potentially provide useful information that will need to be logged.
For downloading of data, I need to;
- Communicate with the webservice to obtain the data.
- Data to collect;
- Summary info on webservice query (record id, type, last update time etc)
- information on any exceptions that are thrown during the webservice call.
- time in seconds taken to retrieve the data (or exception) from the webservice
- Data to collect;
- Validate the received data through local validation rules
- Data to collect;
- Validation errors.
- If valid, then XML representation of the received data and the local representation of the same object.
- Data to collect;
- Save the validated data to a local database
- Data to collect;
- Any exceptions during database calls
- Data to collect;
- Save audit/history record detailing all of the information collected above.
Similar type of data is stored during upload of information to the webservice where we collect Exceptions during webservice/DB communications, validation errors received from the webservice via a FaultException, time taken for webservice comms etc.
For my current solution, I have currently created an AuditHistory object with placeholders to store the various information, and am passing that around to the various classes methods and having populating it during each method call. At the end, I am simply saving this audit history object.
It works, but it feels ugly and clunky.
Any ideas are appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不完全是一种模式(更完整的范式转变),但对于您所描述的内容,您可能需要考虑 面向方面的编程。
或者,如果您希望坚持使用 OO 范式,您可以尝试合并 Observer,使所有您需要跟踪可观察的事物并让审计数据收集器观察它们。
Not exactly a pattern (more a complete paradigm shift), but for what you're describing you might want to think about Aspect-Oriented Programming.
Alternatively, if you wish to stick with the OO paradigm, you might try incorporating Observer, making all the things you need to track observable and having the audit data collector observe them.
我认为你的方法有效,但我会使用不同的方法;我会将每个请求与一个 GUID 相关联,并传递该 GUID。然后,您可以在日志记录中使用该 GUID,最终您可以运行一些程序,根据 GUID 将各种审核历史记录条目“缝合”在一起,以了解系统中的流程。将各种日志/报告“缝合”在一起需要更多的后端工作,但它将每个组件与彼此的依赖关系解耦;他们每个人都必须在日志记录中使用一个字符串。
另一个好处是,只有当您实际需要数据时,您才需要根据请求的 GUID 来构建审计跟踪。因此,如果仅对 2% 的调用需要完整的审计跟踪,那么其他 98% 的调用就会消耗不必要的资源来传递 AuditHistory 对象。这些资源可能相对较小,但是当 AuditHistory 对象发生更改以及所需的重新构建等时,会出现所有相关的相互依赖性问题。
I think your approach works, but I'd use a different method; I'd associate every request with a GUID, and pass that GUID around. Then you can use that GUID in logging, and eventually you can run something that will "stitch" the various audit history entries together based upon the GUID to give an idea of the flow through the system. It's more work on the back end to "stitch" the various logs / reports back together, but it decouples each of the components from any dependencies on each other; there's just a string that they each must use in logging.
The other benefit is that you only take the hit of dealing with the construction of the audit trail based upon the GUID of the request when you actually need the data. So if the full audit trail is only necessary on, say, 2% of the calls, the other 98% are expending resources passing around an AuditHistory object that won't be necessary. Those resources may be relatively small, but there's all the associated issues of interdependencies when the AuditHistory object changes, and the required rebuids, etc.
您可以实施的一个相当快速的解决方法是为每个组件定义审核接口。例如,在 C# 中,您可以创建以下 3 个接口:
现在,您可以让 AuditHistory 对象实现所有 3 个接口。然而,将来如果您想立即记录每个接口的信息,您可以简单地提供每个接口的实现,然后立即将其存储(可能带有用于交叉引用的 GUID,如 Paul Sonier 提到的)到数据库。
我将在 C# 中使用接口的显式实现,因为这将迫使您为每个字段添加别名,从而允许 AuditHistory 对象独立于使用它的组件进行更改。通过仅让您的业务组件依赖于包含它们所需字段的接口,如果您的 AuditHistory 对象实现发生更改,您无需重新编译它们。
One rather quick fix you could implement is to define the auditing interface for each of your components. For instance, in c#, you could create the following 3 interfaces:
For now, you can have your AuditHistory object implement all 3 interfaces. However, in the future if you want to log the information for each one immediately, you can simply provide an implementation of each interface that is then stored (potentially with a GUID for cross reference, as mentioned by Paul Sonier) to the database immediately.
I would use an explicit implementation of the interfaces in c#, since this will force you to alias each of the fields, allowing the AuditHistory object to change independent of the components that use it. By only having your business components dependent on an interface containing the fields they need, you don't have to re-compile them if your AuditHistory object implementation changes.