问题描述
我想知道记录代码应该去哪里.例如,我的存储库日志应该是自己的错误吗?还是我应该从UI/控制器记录所有错误?是否有有关此的一般性原则,或者有人链接到一篇好的文章或各种各样的链接.
推荐答案
记录和跟踪是(IMO)是一种美术,知道要记录什么以及在哪里进行体验.
我发现,最好(最坏的?)学习伐木艺术的方法是经历试图诊断伪造的问题的痛苦!
我能为您提供的所有建议是一些建议:
考虑如何使用日志消息.
键良好的记录是考虑一下日志消息将如何使用使用,如果有问题,相反,关于可怜的记录的最糟糕的事情是您将只有当您有问题并且没有足够的信息时才意识到这一点!
始终考虑日志消息对正在阅读的人的看法,例如:
- Windows API调用失败了?如果这样
- 找不到集合中的条目?没有未发现的条目的名称,真的没有什么人可以推断出来 - 知道该系列的数量也很方便,以便您可以判断该系列是否为空.
一个常见的错误是不要考虑日志记录时需要什么信息,但是,当将记录消息时,您还应该仔细考虑 - 如果在正常操作下经常记录消息,然后在最好的有用性是值得怀疑的,而日志消息可能会产生误导.
另外,请确保您可以识别记录的消息.如果您在日志中看到的只是一个字符串,该字符串多次出现在您的代码库中(或者一点更糟糕的是!),那么您将需要扣除和狡猾,以弄清楚该日志消息来自何处(并且没有知道消息来自何处,您对了解消息几乎没有希望)
- 在多线程/多处理器应用程序中,始终记录线程ID和过程ID.
- 如果您有任何类型的请求ID,也要记录.
- 如果您认为您将花费任何合理的时间查看日志文件,那么您应该强烈考虑运送任何PDB等...为了查看源文件和行号,都需要文件.
记录仅在有问题时使用
不要将记录与错误处理.错误处理是响应和解决该错误的行为(例如,向用户显示消息),日志(通常)仅在出现问题并且原因尚不清楚时才使用.
.例如:如果A使用尝试打开不存在的文件,则如果正确处理错误(通过告诉用户找不到文件),则无需登录该错误.
(可能的例外可能是您想要有关该错误发生频率的统计信息或某些事情 - 这又回到了如何使用日志记录.)
一般而言,正确处理错误比记录更可取,但是良好的错误处理比良好的记录更加困难 - 这些是需要日志中提供的额外信息的情况.
您也不应将记录与审计(尽管在许多系统中,这两个重叠).
更多!
您可以登录太多的唯一方法是:
- 您用尽了存储空间.
- 您会严重影响应用程序的性能.
- 您会被错误的日志所淹没.
-
您记录针对老板的亵渎.
记录纯粹是为了诊断出问题的原因(不要与审计混淆) - 如果您没有任何问题,那么没有人会查看您的日志,也不会造成伤害!在您遇到问题之前,在这种情况下,您需要尽可能多的信息.
如果您是否对是否记录某物有疑问,请记录它.
仅log异常一次.
说明了上述内容,我觉得有必要澄清例外的记录.
通常,您应该只记录一次异常(在处理时).不要试图记录一个例外,稍后您将呼叫者扔给呼叫者,以防万一呼叫者未正确记录异常 - 所有发生的事情是您最终会在通过时记录相同的例外从层到层(我已经看到它发生了,很难看到实际发生了多少个错误).
记录错误是呼叫者的责任 - 唯一可能的例外可能是在系统边界(例如Web服务)之间传递,在此不可能在所有错误细节上运输.
记录与记录的任何相关的内容.
例如,如果您正在编写基于服务器的应用程序,则您的日志文件需要在服务器上,sysadmins可以读取它们 - 但是,如果有可能在客户端上发生错误(例如,在JavaScript中),然后,您的记录代码需要在JavaScript中.解决方案?您的JavaScript记录需要提交到服务器(ala log4js )
不用担心您的应该在哪里和不应该 放记录 - 只要将其放在需要的任何地方即可.
其他推荐答案
通常,最好在拥有所有必要信息的地方记录事物.为了使您的应用更简单,最好不要传递数据,以便您可以将其记录在其他地方. (例外似乎是个例外 - 对不起,双关语:-) - 但它们的主要目的不是记录,这只是可能的副作用.)
无需将记录限制在体系结构的特定模块/层中(除某些特殊情况外,例如不应该记录任何内容的设备驱动程序,或者必须对环境进行假设的应用程序库).<<<<<<<<<<<<<<<<<<<<<<<<<
请注意,即使在同一应用程序中,不同的日志消息也可能具有不同的目的:
- 提供有关应用程序中事件(即批处理处理应用程序的启动和完成的批处理应用程序)的信息,可能是处理等的简短结果等).这样的消息最好是相对较少的限制信息,因为它们通常是为了让人类阅读(例如,sysadmin在早晨成功运行的sysadmin).由于这些是"正常"消息,因此它们的优先级处于规模的中间,例如信息.
- 警报特殊事件(例如错误,崩溃,缺少文件,...).这些消息应该很少(在普通应用中),但可能包含大量信息(例如堆栈跟踪,核心转储等),这可能有助于识别基础错误.但是,当它们发生时,我们几乎总是想看到它们,因此它们具有很高的优先级,例如错误或致命.
- 提供有关应用程序特定部分中发生的情况(通常用于调试目的).这些消息通常是真正的猪,通常会生成日志数据的千兆字节.因此,我们只想在特定情况下看到它们,因此很容易将其水平设置为低水平,例如调试.
现代记录框架(例如Log4J家族)可以非常灵活地处理来自应用程序不同部分的不同类型(级别).尽管如此,最好在向代码添加大量日志消息之前计划您的记录方案. IE.您打算登录应用程序哪些部分的哪些类型的消息,以及您将如何使用这些消息?您需要多少个和哪种日志目标(控制台,文件,DB)?
其他推荐答案
我找到了Microsoft Architecture指南的读物. http://msdn.microsoft.com/en-us/en-us/library/fff650706. aspx
记录是所有层的交叉切割问题
问题描述
I'm wondering where logging code should go. For example, should my repository log it's own errors? Or should I log all errors from the UI/controller? Are there any general deisgn principles about this, or does anyone have link to a good article or somesuch.
推荐答案
Logging and tracing is (IMO) a fine art, knowing what to log and where takes experience.
I've found that the best (worst?) way of learning the art of logging is by experiencing the pain of attempting to diagnose issues with shoddy logging!
All I can offer you is some points of advice:
Think about how the log message will be used.
The key to good logging is to think about how the log message will be used if there is a problem, conversely the worst thing about poor logging is that you will only ever realise it when you have a problem and you don't have enough information!
Always think about what the log message says to the person who is reading it, for example:
- Has a windows API call failed? If so then you probably need to log the HRESULT and the GetLastError result (if there is one) for it to be of much use.
- Couldn't find an entry in a collection? Without the name of the entry that wasn't found there really isn't much anyone can deduce - it would also be handy to know the count of the collection so that you can tell if the collection is empty.
A common mistake is to not think about what information is required when logging, however you should also think carefully about when a message will be logged - if a message is logged frequently under normal operation then at best it's usefulness is questionable and at worst that log message can be misleading.
Also, make sure you can identify what logged a message. If all you can see in a log is a string which appears in your code base many times (or worse still not at all!) then you are going to need to deduction and cunning to figuring out where that log message came from (and without knowing where a message comes from, you have little hope in understanding it)
- In multi threaded / multi processor applications always log the thread id and the process id.
- If you have a request id of any sort, log that too.
- If you believe that you are going to spend any reasonable length of time looking at log files then you should strongly consider shipping whatever pdb etc... files are needed in order to see source files and line numbers.
Logging is only used when there is a problem
Don't confuse logging with error handling. Error handling is the act of responding to and resolving that error, (e.g. displaying a message to the user), logs are (generally) only used when something has gone wrong and the reason is unclear.
For example: If a use attempts to open a file that doe not exist then if the error is correctly handled (by telling the user that the file couldn't be found) then there should be no need to log that error.
(The possible exception might be if you wanted statistics on how frequently that error happened or something - this comes back to thinking about how the logging will be used.)
In general correctly handling an error is preferable to logging, however good error handling is even more difficult than good logging - these are the cases where the extra information offered in logs is needed.
You also shouldn't confuse logging with auditing (although in many systems the two overlap).
More is better!
The only way you can log too much is if:
- You run out of storage space.
- You significantly affect the performance of your app.
- You get swamped with logs that you can't easily process in the case of an error.
You log profanities directed at your boss.
Logging exists purely to diagnose the cause of problems (don't confuse logging with auditing) - if you don't have any problems then nobody is going to look at your logs, and no harm is done! Until you have a problem that is, in which case you need as much information as you can get.
If you are in doubt on whether or not to log something, then log it.
Only log exceptions once.
Having stated the above, I feel the need to clarify the logging of exceptions.
In general you should only log an exception once (at the point where it is handled). Don't be tempted to log an exception that you later throw to the caller "just in case" the caller doesn't log the exception properly - all that happens is that you end up with the same exception being logged many times as it passed from tier to tier (I've seen it happen and it makes it difficult to see how many errors actually occurred).
It is the callers responsibility to log an error - the only possible exception might be passing between system boundaries (e.g. web services), where it's not possible to transport across all of the error detail.
Log whatever is relevant, wherever it is relevant to log it.
For example, if you are writing a server based application then your log files need to be on the server, where the sysadmins can read them - if however there is potential for errors to occur on the client (e.g. in JavaScript), then your logging code needs to be in JavaScript. The solution? Your JavaScript logging needs to submit itself to the server (ala log4js)
Don't worry about where you should and shouldn't put logging - just put it wherever it is needed.
其他推荐答案
In general, it is best to log things at the place you have all the necessary information. And to make your app simpler, it is best not to pass around data just so that you can log it somewhere else. (Exceptions seem to be an exception - sorry for the pun :-) - but their primary purpose is not logging, it is just a possible side effect.)
There is no need to restrict logging to specific modules/layers of the architecture (except some special cases, e.g. device drivers which are not supposed to be logging anything, or application libraries which must not make assumptions about the environment).
Note that different log messages may have different purposes, even within the same application:
- To give information about the (normal) flow of events within the app (i.e. a batch processing app may log that it started and finished, possibly the brief result of the processing etc.). Such messages should preferably be relatively few containg a limited amount of information, as they are often meant for humans to read (e.g. a sysadmin to check in the morning that the app ran successfully). Since these are "normal" messages, their priority is in the middle of the scale, e.g. INFO.
- To alert to exceptional events (e.g. errors, crashes, missing files, ...). These messages should be rare (in a normal app), but may contain an excessive amount of information (such as stack traces, core dumps etc.) which may help identifying the underlying bug. However, when they happen, we almost always want to see them, therefore they have a high priority, such as ERROR or FATAL.
- To give detailed information about what happens in a specific part of the app (usually for debugging purposes). These messages are typically a real hog, often generating Gigabytes of log data. Therefore we only want to see them under specific circumstances, thus it is apt to set their level to low, e.g. DEBUG.
Modern logging frameworks such as the Log4J family allow very flexible handling of different types (levels) of messages from different parts of the application. Still, it is a good idea to plan your logging scheme before adding a plethora of log messages to the code. I.e. what types of messages you plan to log in which parts of the app, and how you are about to use these messages? How many and what kind of log targets (console, file, DB) you need?
其他推荐答案
I find the Microsoft Architecture guide a good read. http://msdn.microsoft.com/en-us/library/ff650706.aspx
Logging is a cross-cutting concern of all layers