记录,何时记录以及记录什么?
我目前正在开发一个相当大的多层应用程序,该应用程序将部署在海外。 虽然我希望它在解聚后不会倒塌或爆炸,但我不能 100% 确定这一点。 因此,如果我知道我可以请求日志文件,以准确找出问题所在和原因,那就太好了。
所以基本上正如标题所示,我想知道何时记录以及记录什么内容? 我想知道这一点,以确保我拥有全面的日志文件,可以轻松检查这些文件以确定我的应用程序崩溃时发生了什么。
I am currently working on a rather large multi tiered app that will be deployed overseas. Although I hope it won't fall over or blow up once depolyed I can't be 100% sure of this. Therefore it would be nice to know that I could request the log file, to work out exactly what went wrong and why.
So basically as the title suggests I would like to know when and what to log? I would like to know this to ensure I have comprehensive log files that can be examined easily to determine what has happened if my app falls over.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
1 - 使用标准化格式制作单个日志。 它是什么并不重要,但要确保每个条目都具有相同的基本字段。 仅调用“printf”可能不会削减它(替换 System.err.println 或适当的任何内容)
2 - 允许至少一个字段是任意字符串...开发人员会比您更了解需要什么那里。
3 - 在每个条目上包含高分辨率时间戳。 你最终会需要它,相信我。
4 - 如果可能,请包含错误来源的文件和行号。 这在 C 语言中很容易,但在 Java 语言中有点痛苦。 但它在以后非常有用,尤其是当人们开始剪切+粘贴代码(包括错误消息)时。
5 - 确保日志位于任何级别的代码都可以使用它的位置。
6 - 我经常使用“主要”和“次要”错误标签,其中“主要”意味着“我是检测到存在问题的人”,“次要”意味着“我调用了一个报告错误的函数” ”。 这样可以轻松找到问题的根源(“主要:找不到文件”)并仍然报告错误的含义(“次要:无法加载校准表”)。
7 - 包括一些记录非错误和错误的功能。
我发现最难的部分是错误不一定是错误。 如果您使用文件调用函数,并且该文件不存在,那么是否应该记录该错误? 有时这是严重的失败,有时则是意料之中的。 这很大程度上取决于函数的 API; 如果函数有办法返回错误,我通常会让它在不记录日志的情况下执行此操作; 那么高层代码的工作就是决定是否需要报告该错误或者是否需要报告该错误。
1 - Make a single log, with a standardized format. Doesn't matter much what it is, but ensure that ever entry has the same basic fields. Just calling "printf" probably won't cut it ( substitute System.err.println or whatever as appropriate )
2 - Allow for at least one field to be an arbitrary string... the developer will know better then you what needs to be there.
3 - Include a high resolution time-stamp on each entry. You will need it eventually, trust me.
4 - If possible, include the file and line number of the origin of the error. That's easy in C, and a bit of a pain in Java. But it's incredibly useful later on, especially when people start to cut+paste code, including the error messages.
5 - Ensure the log is at a place that any level of the code can use it.
6 - I've often used "Primary" and "Secondary" error tags, where "Primary" means "I'm the guy who detected there is a problem", and "Secondary" means "I called a function which reported an error". That makes it easy to find the source of the problem ( "Primary: file not found" ) and still report the meaning of the error ( "Secondary: can't load calibration table" ).
7 - Include some capability to log non-errors as well as errors.
The hardest part I find is when an error isn't necessarily an error. If you call a function with a file, and the file doesn't exists, is that an error that should be logged or not? Sometimes it's a critical failure, and sometimes it's expected. It's pretty much up to the API of the function; if the function has a way to return an error, I will usually have it do that without logging; then it's the job of the higher level code to decide if it needs to report that error or if it is expected.
首先,为自己准备一个日志框架 - 您没有提到任何特定语言,但任何基于 Apache log4j 的框架都是一个安全的选择。 最重要的是该框架支持不同级别的详细信息(调试消息、警告、错误消息)。 您可以在运行时配置记录器,了解它将实际写入哪些消息以及写入何处 - 没有必要重新发明轮子来处理日志记录。
在源代码中实现日志框架。 至少,您应该记录应用程序中可能发生的异常,然后为它们“添加价值”。 将堆栈跟踪写入日志文件固然很好,但很少足以诊断问题 - 考虑记录诸如 catch {} 中方法参数的值之类的内容。
在更高的级别上,您可以利用不同级别的详细程度来记录应用程序中发生的情况。 如果错误仅发生在无法附加远程调试器的生产系统上,这尤其有用 - 您只需增加日志框架配置文件中的详细级别,并观察所有调试(“使用参数调用方法 X” Y") 消息出现在日志中。
First off, grab yourself a logging framework - you haven't mentioned any specific language, but any of the frameworks based around the Apache log4j would be a safe bet. The most important thing is that the framework supports different levels of verbosity (debug messages, warnings, error messages). You can configure the logger at run time as to which messages it will actually write, and to where - there's no point re-inventing the wheel to work with logging.
Implement your logging framework in your source. As a minimum, you should be looking to record and then "add value" to exceptions that can occur in your application. Writing a stack trace to a log file is all well and good, but it's very rarely enough to be able to diagnose the problem - consider logging things like the value of method parameters in a catch {}.
At a higher level, you can utilise the power of the different levels of verbosity to record what it happening in your application. This is especially useful if errors are only occurring on production systems where you can't attach a remote debugger - you can just increase the level of verbosity in the log framework config file, and watch as all your debug("Calling method X with parameter Y") messages appear in the log.
我只想补充一点,对于大型任务关键型应用程序,只有在部署后才能通过客户端发送的日志的帮助来调查问题,随着时间的推移,对记录时间和地点的良好认识会随着时间的推移而增加。应用程序成熟度(成熟度与应用程序在一个地方部署和使用的时间以及[在不同客户端/位置]不同部署的数量直接相关)。
I would only like to add the small bit that for a large mission-critical application where problems can only be investigated, once deployed, through the help of logs sent through clients, a good sense of when and where to log comes with time as the application matures (where maturity is directly related to the amount of time the application spends deployed and being used at one place, and the number of different deployments of it [at different clients/locations]).
只要您不需要为性能付出太多代价,日志记录就很重要。
根据我的经验,你想要记录的最重要的事情是那些警告、哎呀、健全性检查失败、雨天场景等,人们在编写晴天场景时往往会忽略这些内容,有时会用一个打印“我们不应该到达这里”等。这些东西往往不会在测试期间出现,而是在部署期间开始弹出,当然它们不会被捕获。
如果您记录并打算通过远程读取结果,请确保捕获准确的时间戳、位置和某种会话 ID(以防有多个实例同时运行并写入日志文件)。 您越容易确定哪些消息是一次执行的一部分,您就越好。
错误级别和类型也很重要。 进行搜索以确保您没有从多个位置写入相同的消息也很重要,否则追踪将很困难。
最后,如果您的用户运行 Mac OS X,请格外小心日志记录错误:由于某些奇怪的原因,即使在 Leopard 中,默认日志记录机制的处理成本也很高,并且会占用大量 CPU。
As long as you don't have to pay much for the performance, logging is important.
In my experience the most important things you want to log are those sort of warnings, Oops's, sanity check failures, rainy-day scenarios, etc., that one tends to neglect while coding the sunny-day scenarios and sometimes waives them off with a print "We shouldn't get here", etc. These things have a tendency to not appear during testing but to start popping up during deployment, where they're of course not captured.
If you log and intend to read the results by remote, make sure to capture the exact timestamp, location, and some sort of session ID (in case there are multiple instances running at the same time and writing into the log file). The easier it is for you to determine what messages are part of one execution, the better you are.
Error levels and types are also important. It is also important to do a search to make sure you are not writing the same message from multiple locations or tracing will be difficult.
Finally, be extremely careful about logging errors if your users run Mac OS X: for some strange reason, even in Leopard, the default logging mechanism gets processed expensively and can hog tons of CPU.
我们开发了一个在世界各地使用的大型基于电话的系统,并且多年来一直使用我们自己的日志系统进行应用。 调试级别非常重要,我们的应用程序附带的调试设置为“仅错误”,除了对时间最敏感的应用程序外,所有应用程序都启用日志到文件。 我们还支持将输出转移到调试跟踪系统(这是 Windows,因此只需调用 OutputDebugString,我们的工程师就可以访问名为 DBWIN32 的调试捕获器)。 这很重要,因为某些类别的错误要求您能够查看多个应用程序的序列化输出。 通过应用这种技术,我解决了一些非常棘手的多应用程序交互错误。 应用程序通常会在输出中添加一个人类可读的标签,这样我们就可以在这种情况下知道哪一行来自哪个应用程序。
我们使用的级别通常是:关闭、仅错误、基本、详细、“详细”(其中详细是一个占位符,表示投票结果、用户操作、消息内容等多种内容 - 无论作者认为重要的是什么)。
哦,应用程序写入其日志文件的第一件事是提供其版本资源的标头,因此我们可以知道我们正在处理什么版本 - 不要相信用户或本地工程师知道:-)
We develop a large telephony-based system which is used all over the world, and have used our own logging system for applications for years. Levels of debug are very important, and our apps ship with the debug set to "errors only", with log to file enabled on all but the most time-sensitive. We also support diverting our output to the debug trace system (this is Windows, so it's a simple call to OutputDebugString, and our engineers have access to a debug catcher called DBWIN32). This is important, because some classes of bugs require you to be able to see the output from multiple apps, serialised. I have solved some seriously tricky multi-app interaction bugs by the application of this technique. Apps usually add a human-readable tag to the output so we can tell which line came from which app, for this scenario.
The levels we use are typically: Off, Errors only, basic, detailed, "verbose" (where verbose is a placeholder implying multiple things like poll results, user operations, message contents etc - whatever the author thinks is important).
Oh, and the first thing an app writes into its log file is a header giving its version resource, so we can tell what build we're dealing with - don't trust the user or the local engineer to know :-)
AOP 对于非侵入式日志记录确实很有用。 例如,您可以使用 AOP 记录每个方法调用的参数值和返回值,而无需实际向每个方法添加日志记录语句。
如何执行此操作的具体细节显然取决于您的目标语言和平台(您没有指定)。 有关如何将此类记录器添加到基于 Java Spring 的应用程序的示例,请参阅 此处。
AOP is really useful for non-intrusive logging. For example, you can use AOP to log the parameter values and return value of every method call without actually adding the logging statements to each method.
The specific details of how to do this obviously depend on your target language and platform (which you didn't specify). For an example of how to add such a logger to a Java Spring-based application, see here.