Basic use of the log system (Logging Facility) in ACE [1]

Source: Internet
Author: User

Describes the basic use of the log system (logging facility) in Ace.

I. Introduction
I have previously introduced an open-source log system log4cplus, and ACE also has its own logging facility, similar to log4cplus. Ace Log System
It also features thread security, flexibility, and hierarchical display. It can be used for program debugging, running, testing, and maintenance throughout the entire life cycle.
Information is output to screens, files, system logs (such as Event Logs in Windows), and even remote servers. In addition, the ace Log System
Supports callback functions and runtime configuration. This article mainly references the ace programmer's guide,
The: Practical Design Patterns for network and systems programming.

Ii. basic use of the ACE Log System
First, we will introduce how to call ace log macro through an example:
#include < ace/Log_Msg.h >
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  ACE_DEBUG ((LM_INFO, ACE_TEXT ("Hi ACE Logging Facility!/n")));
  return 0;
}
The program must contain the header file log_msg.h, which defines various useful log Output Macros. The macro ace_tmain is defined by Ace.
Wide-character-enabled entry point, Ace log system outputs to stderr by default, so for applications of the console type,
Will be directly output to the screen. When the program is running, the screen displays:
Hi ace logging facility!
It can be seen that the macro call of the ACE log system is very simple:
Ace_xxx (severity, formatting-ARGs ));
Ace_xxx indicates the log output macro (ACE logging macros), including:
Ace_error (Level, String ,...))
ACE_DEBUG (level, string ,...))
ACE_TRACE (string)
ACE_ASSERT (test)
ACE_HEX_DUMP (level, buffer, size [, text])
ACE_RETURN (value)
ACE_ERROR_RETURN (level, string,...), value)
ACE_ERROR_INIT (value, flags)
ACE_ERROR_BREAK (level, string ,...))
Severity is the output Severity Level, including:
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 shocould be corrected immediately, such as a temporary upted database
LM_EMERGENCY A panic condition, normally broadcast to all usersLM_TRACE Messages indicating
Function-calling sequence
Formatting-args is the content to be output. The format is similar to the output format of the printf function:
Code        Argument Type   Displays
A ACE_timer_t floating point number
A-causes program termination (Abort)
C char Single Character
C char * string (narrow characters)
I, d int, 10-digit integer
I-indent
E, E, f, F, g, G double-precision floating point number
L-row number
M-severity level name
M-error code (errorno)
N-file name
N-ace_log_msg: program name specified by open ()
O int octal integer
P-current process ID
P ace_tchar * string followed by the error code, which is the same as perror.
Q ace_uint64 64-bit unsigned decimal integer
R void (*) () function call
R int decimal integer
Signal name corresponding to the s int number
S ace_tchar * ace_tchar string
T-current time (hour: minute: sec. USEC)
D-timestamp (month/day/year/hour: minute: sec. usec)
T-ID of the current thread
Uint unsigned decimal integer
W wchar_t Single wide character
W wchar_t * Wide-character string
X, X int hexadecimal number
@ Void * pointer (hexadecimal)
% N/A %
We can use some examples to further understand how to use these macros, Severity levels, and formats. Before getting started, first clarify a concept:
Some log systems (such as log4cplus) rely on macro names to differentiate log information types, such:
LOG4CPLUS_DEBUG (Logger: getRoot (), "some text")/* DEDUG type */
LOG4CPLUS_ERROR (Logger: getRoot (), "some text")/* ERROR Type */

ACE's log system does not rely on the macro name itself, but on the first macro parameter, that is, Severity Level, to distinguish log information types:
ACE_DEBUG (LM_DEBUG, ACE_TEXT ("some text/n");/* DEDUG type */
ACE_ERROR (LM_DEBUG, ACE_TEXT ("some text/n");/* DEDUG type */
ACE_DEBUG (LM_ERROR, ACE_TEXT ("some text/n");/* ERROR Type */
ACE_ERROR (LM_ERROR, ACE_TEXT ("some text/n");/* ERROR Type */
From this perspective, there is no difference between macro ACE_DEBUG and ACE_ERROR, and they can be mixed. The differences between these two macros are mainly reflected in the following two aspects:
A) semantic differences
B) after the statement is executed, op_status is different, for example:
ACE_Log_Msg * lm = ACE_LOG_MSG;
ACE_DEBUG (LM_ERROR, ACE_TEXT ("some text/n ")));
ACE_ASSERT (0 = lm-> op_status ();/* after ACE_DEBUG is executed, op_status is 0 */
ACE_ERROR (LM_ERROR, ACE_TEXT ("some text/n ")));
ACE_ASSERT (-1 = lm-> op_status ();/* after ACE_ERROR is executed, op_status is-1 */

The following are some typical examples:
Use-case1: How to Enabling or Disabling Logging Macros at compile time
You can define some Macros before # include <ace/Log_Msg.h> to Enable/Disable logging Macros during compilation.
/* disable ACE_DEBUG and ACE_ERROR */
#define ACE_NLOGGING
/* Enable ACE_DEBUG and ACE_ERROR (default )*/
# Undef ACE_NLOGGING
/* Enable ACE_ASSERT (default )*/
# Undef ACE_NDEBUG
/* disable ACE_ASSERT */
#define ACE_NDEBUG
/* enable ACE_TRACE */
#define ACE_NTRACE 0
/* Disable ACE_TRACE (default )*/
# Define ACE_NTRACE 1

[Use-case2] format use
A) terminate after the result is printed (Abort)
    ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("begin %a end /n")));
After the following information is output, the system prompts "Abort:
Begin Aborting... end
B) indent
int ACE_TMAIN (int, ACE_TCHAR *[])
{
    ACE_TRACE("main");
    ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%Itext/n")));
    return 0;
}
Output:
(700) calling main in file 'd:/aceprj/testlog/main. cpp 'on line 24
Text
(700) leaving main
(700 is the ID of the current thread that ACE_TRACE controls output)
C) HEX Dump (useful during debugging)
Char szBuf [128] = "hello world! ";
ACE_HEX_DUMP (LM_DEBUG, szBuf, 128, "szBuf :"));
Output:
szBuf:  - HEXDUMP 128 bytes
68 65 6c 6c 6f 20 77 6f  72 6c 64 21 00 00 00 00   hello world!....
00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
D) function call
void foo(void)
{
    ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("in func foo/n")));
}
int ACE_TMAIN (int, ACE_TCHAR *[])
{
    ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("call function %r/n"),foo));
    return 0;
}
Output:
In func foo
Call Function
E) hexadecimal conversion
Ace_uint64 uint64a = 210113198510308319;
Int Hexa = 0xbeee3f;
Int Octa = 9;
Ace_timer_t tminterval = 0.000001;

Ace_debug (lm_debug, ace_text ("uint64: % Q/N"), uint64a ));
Ace_debug (lm_debug, ace_text ("HEX: % x, HEX: % x/N"), Hexa, hexa ));
Ace_debug (lm_debug, ace_text ("PTR in HEX: % @/N"), & hexa ));
Ace_debug (lm_debug, ace_text ("octal number of 9: % O/N"), Octa ));
Ace_debug (lm_debug, ace_text ("timer's interval: % A/N"), tminterval ));
Output:
Uint64: 210113198510308319
HEX: beee3f, HEX: beee3f
PTR in HEX: 0012fe30
Octal number of 9: 11
Timer's interval: 0.000001
F) Comprehensive use
Ace_debug (lm_debug, ace_text ("% d, % m, [% T], line: % L/N ")));
Ace_debug (lm_error, ace_text ("% d, % m, [% T], line: % L/N ")));

Output:
Mon Mar 20 2005 20:02:16. 912000, lm_debug, [3296], line: 24
Mon Mar 20 2006 20:02:16. 912000, lm_error, [3296], line: 25


[Use-case3] macro use
a) ACE_RETURN
int foo(void)
{
    ACE_RETURN(3);
}
int ACE_TMAIN (int, ACE_TCHAR *[])
{
    foo();
    ACE_ASSERT( 3 == ACE_LOG_MSG->op_status() );
    return 0;
}
Output: (no output)
b) ACE_ERROR_RETURN
int foo(void)
{
    ACE_ERROR_RETURN((LM_DEBUG,"Return error/n"), 3);
}
int ACE_TMAIN (int, ACE_TCHAR *[])
{
    foo();
    ACE_ASSERT( 3 == ACE_LOG_MSG->op_status() );
    return 0;
}
Output:
Return Error

c) ACE_ERROR_BREAK
    int i = 0;
    while(1)
    {
        if( i > 10 )
        {
            ACE_ERROR_BREAK((LM_DEBUG,"break from while/n"));
        }
        i++;
    }
    ACE_DEBUG((LM_DEBUG, "i = %d/n", i));
Output:
Break from while
I = 11

Use-case4: How to Enabling or Disabling Logging Severities at runtime
By default, all logging severities in the process range are output. Therefore, you must use priority_mask,
ACE_Log_Msg: enable_debug_messages, ACE_Log_Msg: disable_debug_messages to filter the output.
The usage of priority_mask is as follows:
    /* Get the current ACE_Log_Priority mask. */
    u_long priority_mask (MASK_TYPE = THREAD);
    /* Set the ACE_Log_Priority mask, returns original mask. */
    u_long priority_mask (u_long, MASK_TYPE = THREAD);
Here, MASK_TYPE can be selected: ACE_Log_Msg: PROCESS (PROCESS scope) or ACE_Log_Msg: THREAD (THREAD scope)

The usage of enable_debug_messages/disable_debug_messages is as follows:
    static void disable_debug_messages
    (ACE_Log_Priority priority = LM_DEBUG);
    static void enable_debug_messages
    (ACE_Log_Priority priority = LM_DEBUG);
Here, you can select any logging severity that needs to be enabled or blocked. Unlike the function name, you can only control LM_DEBUG.
In addition, because it is a static function, enable_debug_messages/disable_debug_messages settings are valid for the entire process.
Note the differences between priority_mask and enable_debug_messages/disable_debug_messages:
Priority_mask replaces the logging severitys of a process (or thread) with its first parameter to clear the previous settings.
Enable_debug_messages accumulates the logging severitys of the process using its parameters without clearing the previous settings.
Disable_debug_messages blocks the process's logging severitys using its parameters without clearing the previous settings.

A) The entire process only allows the output of LM_ERROR and LM_WARNING.
ACE_DEBUG (LM_DEBUG, "Debug Text1/n "));
ACE_DEBUG (LM_ERROR, "Error Text1/n "));

ACE_LOG_MSG-> priority_mask (LM_ERROR | LM_WARNING, ACE_Log_Msg: PROCESS );

ACE_DEBUG (LM_DEBUG, "Debug Text2/n "));
ACE_DEBUG (LM_ERROR, "Error Text2/n "));

Or:
ACE_DEBUG (LM_DEBUG, "Debug Text1/n "));
ACE_DEBUG (LM_ERROR, "Error Text1/n "));
/* All logging severitys of the process are disabled */
ACE_LOG_MSG-> priority_mask (0, ACE_Log_Msg: PROCESS );
ACE_Log_Msg: enable_debug_messages (LM_ERROR );
ACE_Log_Msg: enable_debug_messages (LM_WARNING );
ACE_DEBUG (LM_DEBUG, "Debug Text2/n "));
ACE_DEBUG (LM_ERROR, "Error Text2/n "));


Output:
Debug Text1
Error Text1
Error Text2
B) Each thread controls its own logging severity
#include < ace/Task.h >    /* for ACE_Thread_Manager */
#include < ace/Log_Msg.h >
void service(void)
{
ACE_LOG_MSG->priority_mask (LM_INFO, ACE_Log_Msg::THREAD);
ACE_DEBUG((LM_DEBUG, "in service, MsgType:%M,  ThreadID: %t/n"));
ACE_DEBUG((LM_INFO,  "in service, MsgType:%M,  ThreadID: %t/n"));
}
void worker(void)
{
 ACE_LOG_MSG->priority_mask (LM_DEBUG, ACE_Log_Msg::THREAD);
ACE_DEBUG((LM_DEBUG, "in worker,  MsgType:%M, ThreadID: %t/n"));
ACE_DEBUG((LM_INFO,  "in worker,  MsgType:%M, ThreadID: %t/n"));
}
int ACE_TMAIN (int, ACE_TCHAR *[])
{
  ACE_LOG_MSG->priority_mask (0, ACE_Log_Msg::PROCESS);
 ACE_Thread_Manager::instance ()->spawn ((ACE_THR_FUNC)service);
ACE_Thread_Manager::instance ()->spawn_n (3, (ACE_THR_FUNC)worker);
ACE_Thread_Manager::instance ()->wait();
 return 0;
}
Output:
In service, MsgType: LM_INFO, ThreadID: 3428
In worker, MsgType: LM_DEBUG, ThreadID: 2064
In worker, MsgType: LM_DEBUG, ThreadID: 1240
In worker, MsgType: LM_DEBUG, ThreadID: 1800

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.