六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 35|回复: 0

ACE TAO Programming [005] 简单介绍日志功能的实现

[复制链接]

升级  13.33%

72

主题

72

主题

72

主题

举人

Rank: 3Rank: 3

积分
240
 楼主| 发表于 2013-1-26 14:32:32 | 显示全部楼层 |阅读模式

3.1 Basic Logging and Tracing

通常,用ACE_DEBUG, ACE_ERROR, and ACE_TRACE这三个宏来输出诊断信息
Three macros are commonly used to display diagnostic output from your code: ACE_DEBUG, ACE_ERROR, and ACE_TRACE.

头两个的参数和实现的操作基本相同
The arguments to the first two are the same; their operation is nearly identical, so for our purposes now, we'll treat them the same. They both take a severity indicator as one of the arguments, so you can display any message using either;

然而,ACE_DEBUG通常用来输出自己的调试信息;ACE_ERROR用来输出警告和错误
however, the convention is to use ACE_DEBUG for your own debugging statements and ACE_ERROR for warnings and errors. The use of these macros is the same:

ACE_DEBUG ((severity, formatting-args));ACE_ERROR ((severity, formatting-args));The severity parameter specifies the severity level of your message.

最常用的就是LM_DEBUG和LM_ERROR
The most common levels are LM_DEBUG and LM_ERROR. All the valid severity values are listed in Table 3.1.
The formatting-args parameter is a printf()-like set of format conversion operators and formatting arguments for insertion into the output. The complete set of formatting directives is described in Table 3.2. One might wonder why printf()-like formatting was chosen instead of the more natural—to C++ coders—C++ iostream-style formatting. In some cases, it would have been easier to correctly log certain types of information with type-safe insertion operators. However, an important factor in the logging facility's design is the ability to effectively "no-op" the logging statements at compile time. Note that the ACE_DEBUG and ACE_ERROR invocations require two sets of parentheses. The outer set delimits the single macro argument. This single argument comprises all the arguments, and their enclosing parentheses, needed for a method call. If the preprocessor macro ACE_NDEBUG is defined, the ACE_DEBUG macro will expand to a blank line, ignoring the content of the inner set of parentheses. Achieving this same optimization with insertion operators would have resulted in a rather odd usage:
ACE_DEBUG ((debug_info << "Hi Mom" << endl));
[table=98%]Table 3.1. ACE_Log_Msg Logging Severity Levels

[tr]Severity Level
Meaning
[/tr]
LM_TRACE
Messages indicating function-calling sequence
LM_DEBUG
Debugging information
LM_INFO
Messages that contain information normally of use only when debugging a program
LM_NOTICE
Conditions that are not error conditions but that may require special handling
LM_WARNING
Warning messages
LM_ERROR
Error messages
LM_CRITICAL
Critical conditions, such as hard device errors
LM_ALERT
A condition that should be corrected immediately, such as a corrupted system database
LM_EMERGENCY
A panic condition, normally broadcast to all users
Similarly, many of the formatting tokens, such as %I, would have been awkward to implement and overly verbose to use:
ACE_DEBUG((debug_info<<ACE_Log_Msg::nested_indent<<"Hi Mom"<<endl));One could argue away the compile-time optimization by causing ACE_NDEBUG to put the debug output stream object into a no-op mode. That may be sufficient for some platforms, but for others, such as embedded real-time systems, you really do want the code to simply not exist.
Unlike ACE_DEBUG and ACE_ERROR, which cause output where the macro is placed, ACE_TRACE causes one line of debug information to be printed at the point of the ACE_TRACE statement and another when its enclosing scope is exited. Therefore, placing an ACE_TRACE statement at the beginning of a function or method provides a trace of when that function or method is entered and exited. The ACE_TRACE macro accepts a single character string rather than a set of formatting directives. Because C++ doesn't have a handy way to dump a stack trace, this can be very useful indeed.
Let's take a look at a simple application:
#include "ace/Log_Msg.h"void foo (void);int ACE_TMAIN (int, ACE_TCHAR *[]){  ACE_TRACE(ACE_TEXT ("main"));  ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHi Mom\n")));  foo();  ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n")));  return 0;}void foo (void){  ACE_TRACE (ACE_TEXT ("foo"));  ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHowdy Pardner\n")));}Our first step is always to include the Log_Msg.h header file. It defines many helpful macros, including ACE_DEBUG and ACE_ERROR, to make your life easier. The full set of output-producing macros is listed in Table 3.3.
You can use ACE_DEBUG to print just about any arbitrary string you want, and the many format directives listed in Table 3.2 can also be modified with printf()-style modifiers for length, precision, and fill adjustments. (See a printf() reference for details on the modifiers.) In the preceding example, we've used %I so that the ACE_DEBUG messages are nicely indented along with the ACE_TRACE messages.
If you compile and execute the preceding code, you should get something like this:
(1024) calling main in file `Simple1.cpp' on line 7   Hi Mom   (1024) calling foo in file `Simple1.cpp' on line 18      Howdy Pardner   (1024) leaving foo   Goodnight(1024) leaving main
[table=98%]Table 3.2. ACE Logging Format Directives

[tr]Code
Argument Type
Displays
[/tr][tr][td]A
[/td][td]ACE_timer_t
[/td][td]Floating-point number; long decimal number if platform doesn't support floating point
[/td][/tr][tr][td]a
[/td][td]
[/td][td]Aborts the program after displaying output
[/td][/tr][tr][td]c
[/td][td]char
[/td][td]Single character
[/td][/tr][tr][td]C
[/td][td]char*
[/td][td]Character string (narrow characters)
[/td][/tr][tr][td]i,d
[/td][td]int
[/td][td]Decimal number
[/td][/tr][tr][td]I
[/td][td]
[/td][td]Indents output according to the nesting depth, obtained from ACE_Trace::get_nesting_indent()
[/td][/tr][tr][td]e,E,f,F,g,G
[/td][td]double
[/td][td]Double-precision floating-point number
[/td][/tr][tr][td]l
[/td][td]
[/td][td]Line number where logging macro appears
[/td][/tr][tr][td]M
[/td][td]
[/td][td]Text form of the message severity level
[/td][/tr][tr][td]m
[/td][td]
[/td][td]Message corresponding to errno value, as done by strerror(), for example
[/td][/tr][tr][td]N
[/td][td]
[/td][td]File name where logging macro appears
[/td][/tr][tr][td]n
[/td][td]
[/td][td]Program name given to ACE_Log_Msg::open()
[/td][/tr][tr][td]o
[/td][td]int
[/td][td]Octal number
[/td][/tr][tr][td]P
[/td][td]
[/td][td]Current process ID
[/td][/tr][tr][td]p
[/td][td]ACE_TCHAR*
[/td][td]Specified character string, followed by the appropriate errno message, that is, as done by perror()
[/td][/tr][tr][td]Q
[/td][td]ACE_UINT64
[/td][td]Decimal number
[/td][/tr][tr][td]r
[/td][td]void (*)()
[/td][td]Nothing; calls the specified function
[/td][/tr][tr][td]R
[/td][td]int
[/td][td]Decimal number
[/td][/tr][tr][td]S
[/td][td]int
[/td][td]Signal name of the numbered signal
[/td][/tr][tr][td]s
[/td][td]ACE_TCHAR*
[/td][td]Character string: narrow or wide, according to ACE_TCHAR type
[/td][/tr][tr][td]T
[/td][td]
[/td][td]Current time as hour:minute:sec.usec
[/td][/tr][tr][td]D
[/td][td]
[/td][td]Timestamp as month/day/year hour:minute:sec.usec
[/td][/tr][tr][td]t
[/td][td]
[/td][td]Calling thread's ID (1 if single threaded)
[/td][/tr][tr][td]u
[/td][td]int
[/td][td]Unsigned decimal number
[/td][/tr][tr][td]w
[/td][td]
<span style="font-size: x-small;"><span style="font-family: arial,helvetica,sans-serif;"><span style="font-size: x-small;"><span style="">font-family: times new ro
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表