Information
We are currently investigating an issue with the editor of some pages. Please save your work and avoid to create new pages until this banner is gone.
...
H16N161623L (klemen.zagar@ijs.si)
KGB, Jozef Stefan Institute
Radostina Georgieva (rgeorgie@eso.org)
ESO
Change Record
REVISION | DATE | AUTHOR |
| SECTIONS/PAGES AFFECTED |
|
---|---|---|---|---|---|
| REMARKS |
|
|
|
|
1.0 | 2000-09-10 | Klemen Zagar |
| All |
|
| Created |
|
|
|
|
1.10 | 2000-09-30 | Klemen Zagar |
| All |
|
| G. Chiozzi's comments taken into account. |
|
|
|
|
1. 20 | 2001-03-02 | Klemen Zagar |
| All |
|
| J. Knudstrup's comments taken into account. |
|
|
|
|
1.21 | 2001-03-16 | Klemen Zagar |
| 3.4, 3.4.1.4, 3.4.1.8, A |
|
| Final J. Knudstrup's comments taken into account. Redefined StackId and StackLevel, updated DTD schemas, fixed minor typos. |
|
|
|
|
1.22 | 2001-03-26 | Grega Milcinski |
| All |
|
| Applied ALMA template. Listing and Identifier styles added. |
|
|
|
|
1.23 | 2001-03-30 | Klemen Žagar |
| 3, 3.2, 3.5, 4.1.3, 4.1.4 |
|
| Gianluca Chiozzi's comments taken into account. COS_ macro prefix changed to ACS_. References to MACI and BACI removed (instrumentation of BACI is still described). Notification Channel usage defined. Archiving parameter types defined. Figure redrawn. |
|
|
|
|
1.24 | 2001-11-08 | Klemen Žagar |
| 3.4.1.6, 3.5.3 |
|
| Priority now ranges from 1 to 15. ACS_LOG example fixed. |
|
|
|
|
1.25 | 2001-12-20 | Klemen Žagar |
| All |
|
| Removed reference to "CoCoS" and "Device". The latter has been replaced with "Distributed Object". Removed XML schema diagrams. |
|
|
|
|
1.26 | 2002-01-04 | Klemen Žagar |
| 4.1.1, 4.1.5 |
|
| Archiving configuration properties made consistent with implementation. |
|
|
|
|
1.27 | 2002-11-25 | R. Georgieva |
| 3.4.1.8. |
|
| Escaping delineating characters within log messages. |
|
|
|
|
1.28 | 2002-03-03 | R.Georgieva |
|
|
|
| Java Logging API and Python Logging API added. |
|
|
|
|
1.29 | 2003-11-1 |
|
|
|
|
| Revised for ACS 3.0 |
|
|
|
|
1.30 | 2004-07-23 | G.Chiozzi |
|
|
|
| Updated XML Schema |
|
|
|
|
1.31 | 2005-03-17 | G.Chiozzi |
|
|
|
| Updated documentation on Archiving |
|
|
|
|
1.32 | 2005-05-19 | G.Chiozzi |
|
|
|
| Removed schema documentation from appendix and referenced online documentation. |
|
|
|
|
1.33 | 2006-05-11 | D. Fugate |
|
|
|
| Python section was horribly out of date. |
|
|
|
|
1.34 | 2007-02-12 | N. Barriga |
| Section 3.7 |
|
| Added documentation about type safe logs usage. |
|
|
|
|
1.35 | 2007-02-20 | N. Barriga |
| Section 3.5 |
|
| Fixed example on how to get a logger in Java. |
|
|
|
|
1.36 | 2007-07-30 | N. Barriga |
| Sections 3.4, 3.5, 3.6 |
|
| Added new API for specifying an audience, antenna and array to the logs. |
|
|
|
|
1.371.37 | 2014-12-162014-12-16 | M. MañasM. Mañas |
| AllAll |
|
| General document update and refurbishment. |
|
|
|
|
1.38 | 2016-04-19 |
| P. Colomer |
| Section 3.2 |
| Added description of auto reconnection functionality of publishers in the Centralized Logging Service |
|
|
|
|
...
Telecom log specification represents a log entry by a structure whose IDL is:
Code Block | ||
---|---|---|
| ||
typedef unsigned long long RecordId; // RecordIds are unique within the // scope of one log. typedef TimeBase::TimeT TimeT; // Timestamp, as defined by the CORBA // TimeService. struct NVPair // Name-Value pair { string name; any value; }; typedef sequence<NVPair> NVList; // A set of name-value mappings struct LogRecord { RecordId id; // Unique number assigned by the log TimeT time; // Time when the event is logged (CORBA Time Service) NVList attr_list; // List of user defined name/value pairs. Not part of // the event received by the log. Optional. any info; // Event content }; |
...
A generic log entry representation in XML looks like this:
Code Block | ||||
---|---|---|---|---|
| ||||
<LogEntryType TimeStamp="yyyy-MM-ddThh:mm:ss.fff" File="filename" Line="lineno" Routine="routine" Host="hostname" Process="procname" Thread="threadname" Context="context" SourceObject="source" StackId="stackid" StackLevel="stacklevel" LogId="id" Uri="uri" Priority="p"> <Data Name="name">value</Data> log entry message </LogEntryType> |
...
Code Block | ||
---|---|---|
| ||
<Error TimeStamp="2000-08-23T13:18:27.432" File="FileOpener.cpp" Line="131" Routine="FileOpener::Open" Host="Hurricane" Process={_}"{_}Activator" Thread="EventLoop" SourceObject="GeneralLogger" \[...\]> </Error> |
...
Every log entry can contain arbitrary number of <Data> sub-elements. These sub-elements are useful for reporting values of individual variables to report the state of the object that submitted the log entry.
The Name attribute is mandatory as well as the content of the element.
Code Block | ||
---|---|---|
| ||
<Error TimeStamp="2000-08-23T13:18:27.432" |
...
File="FileOpener.cpp" Line="131" Routine="FileOpener::Open" |
...
Host="Hurricane" Process="Activator" Thread="EventLoop" |
...
LogID="err_File_Not_Found" Priority="8"> |
...
<Data Name="FullPath">/home/someuser/file.txt</Data> |
...
</Error> |
Anchor | ||||
---|---|---|---|---|
|
...
The optional log entry message is a string of characters. The message can be either an XML formatted string, or a CDATA section. The only rule it must obey is not to contain a sub-string \]\]> or characters such as '<', '>' or '&', since it terminates a CDATA section.
Code Block | ||
---|---|---|
| ||
<Error TimeStamp="2000-08-23T13:18:27.432" File="FileOpener.cpp" Line="131" Routine="FileOpener::Open" Host="Hurricane" Process={_}"{_}Activator" Thread="EventLoop" LogID="err_File_Not_Found" Priority="8"> <Data Name="FullPath">/home/someuser/file.txt</Data> *<!\[CDATA\[Message\]\]>* </Error> \\ \\ |
Anchor | ||||
---|---|---|---|---|
|
Anchor | ||||
---|---|---|---|---|
|
The ACS log levels are equivalently defined for all ACS programming languages, as defined in §3.4 (for C++), §3.5 (for java) and §3.6 (for python). This section introduces the different log levels defined and its utilization rules. The following is the list of logging levels from lowest to highest level.
ACS logs are filtered out (as described in Figure 1) according to a filtering logic. ACS defines a default system logging level than can be reconfigured at will. This information is detailed in §3.4.
...
Anchor | ||||
---|---|---|---|---|
|
Anchor | ||||
---|---|---|---|---|
|
Trace logs are generated whenever a function is entered. And are used to report calls to a function. They are used to build call trees during very critical debugging situations. The amount of TRACE logs can be huge and will very likely affect very substantially the performance of the system TRACE logging should be Trace logs are generated whenever a function is entered. And are used to report calls to a function. They are used to build call trees during very critical debugging situations. The amount of TRACE logs can be huge and will very likely affect very substantially the performance of the system TRACE logging should be switched on only in very particular situations and for a short time.
A trace log entry (<Trace>) corresponds to submitting a log entry of type LM_TRACE to the ACE logging system. The default priority of such an entry is 21.
With trace log entries, the Routine attributes are mandatory. There can also be several <Data> sub-elements, whose purpose is to dump the function's parameters.
The log entry message is a mandatory fully-qualified name of the function that was entered, for example MyNamespace::MyClass::MyFunction.
Anchor | ||||
---|---|---|---|---|
|
Anchor | ||||
---|---|---|---|---|
|
Delouse logs are generated only for low level debug purposes. Those logs are of interest for software engineers. Activation of Delouse logs should take place only while investigating low level problems and can put a substantial amount of load on the system.
A delouse log entry (<Delouse>) has no direct match according to according to the ACE logging system, and can be considered a convenient split of LM_DEBUG ACE logs. The default priority of such an entry is 2.
With delouse log entries, the File and Line attributes are mandatory. There can also be several <Data> sub-elements, whose purpose is to dump the object's state.
The log entry message is optional.
...
Local Control UnitACE loggingmacrosACS loggingmacrosACE Logging System:ACE_Log_Msg(thread-wide singleton)MACI logging callback object,implements ACE_Log_Msg_Callback(thread-safe process-wide singleton)Local cache(XML file)log(...)log(...)log(...)Trashcanlog(...)write_records(...)Filtering logic*Logs Publisher*
Figure 2: Architecture of the ACE Logging framework.
The figure gives an overview of ACE Logging framework. The ACE Logging System gets log entries that can be generic or specific (using ACS logging macros). It submits them to an object implementing ACE_Log_Msg_Callback that provides the filtering and the caching capabilities of the framework. The shadowed objects are out of the scope of this document.
The ACE's mechanism is flexible and high-performing and allows the implementation of objects that are specific to the ACS Logging requirements.
Important with respect to the formatting is that fact that the default logging macros of ACE (ACE_DEBUG, ACE_ERROR, etc.) already provide the logging system with the file name and the line number attributes. Additionally, the logging system outputs the runtime context along with all log entry types except for info log entry which has to be taken care of by requesting it explicitly through LoggingProxy's LM_RUNTIME_CONTEXT flag. Though these last attributes are optional according to the XML Schema, their appearance in the log records could be quite helpful.
The implementation of the ACE_Log_Msg_Callback abstract class' log method provides with the rest of the functionality:
Code Block | ||
---|---|---|
| ||
// |
...
/// The pre-defined macro for outputting log entries. It accepts three parameters |
...
/// |
...
/// - flags: This parameter specifies the priority and additional log-entry |
...
/// flags, such as whether to output the runtime context (thread & process) |
...
/// or not. |
...
/// - routine: The fully qualified name of the routine where the log-entry is |
...
/// being generated. Can be 0, in which case the routine name is not output. |
...
/// - log: Formatted as (log_type, format_string, . . .). Passed as a parameter |
...
/// to ACE's logging macros. |
...
/// |
...
/// Usage example: |
...
/// |
...
/// ACS_LOG(LM_SOURCE_INFO | LM_PRIORITY(7), |
...
///"maci::ContainerImpl::init", |
...
///(LM_INFO, "A sample log entry %d", i)); |
...
/// |
...
#define ACS_LOG(flags, routine, log) \ |
...
{ \ |
...
LoggingProxy::Flags(flags); \ |
...
LoggingProxy::Routine(routine); \ |
...
ACE_ERROR(log); \ |
...
} |
...
/// |
...
/// |
...
/// Manipulate priority contained in the log entry's flags. The priority can |
...
/// be from 0 ("use default") through 1 (lowest) to 31 (highest). |
...
/// |
...
#define LM_PRIORITY(p) p |
...
#define LM_GET_PRIORITY(f) (f & 0x0F) |
...
/// If OR-ed with log entries' flags, the runtime context (host name, process name, |
...
/// thread name, context, stack ID and stack level) will also be output. |
...
/// |
...
#define LM_RUNTIME_CONTEXT |
...
0x00000200 /// |
...
/// If OR-ed with log entries' flags, the source code information (file name, |
...
/// line number) will also be output. |
...
/// |
...
#define LM_SOURCE_INFO 0x00000100 |
...
/// The Log Message Callback |
...
class logging_EXPORT LoggingProxy : public ACE_Log_Msg_Callback |
...
{ |
...
public: |
...
/// Receives all log entries submited |
...
/// within the process. Thread safe! |
...
void log(ACE_Log_Record &log_record); |
...
/// Specifies the log entry type, if the output representation is different |
...
/// than the one implied with ACE's log entry type. Applies for the next |
...
/// log entry only. Pointer to the string must be stored in the thread-specific |
...
/// storage! |
...
static void LogEntryType(const ACE_TCHAR *szType); |
...
/// Specifies the name of the routine (function) where the following log entry |
...
/// will be generated. Pointer to the string must be stored in the |
...
/// thread-specific storage! |
...
static void Routine(const ACE_TCHAR *szRoutine); |
...
/// Set the flags that will apply to the log entry that will be submitted next. |
...
/// Flags must be stored in thread-specific storage! Flags are obtained by OR-ing |
...
/// appropriate LM_* values above. If priority is 0, the default priority |
...
/// associated with ACE's log entry type (LM_INFO, LM_ERROR, ...) is implied. |
...
static void Flags(unsigned int uiFlags); |
...
/// Specifies the name of the thread. Pointer to the name must be stored in |
...
/// the thread-specific storage! |
...
static void ThreadName(const ACE_TCHAR *szName); |
...
/// Returns the name of the thread. |
...
static const ACE_TCHAR *ThreadName(); |
...
/// Specifies the name of the process. Must be stored in a process-wide global |
...
/// variable! |
...
static void ProcessName(const ACE_TCHAR *szName); |
...
/// Returns the name of the process. |
...
static const ACE_TCHAR *ProcessName(); |
...
/// Reset the list of custom attributes. The attributes are applicable to the |
...
/// next log entry only. |
...
static void ResetAttributes(); |
...
/// Add an attribute to the list of next log entries' attributes. |
...
static void AddAttribute(const ACE_TCHAR *szName, const ACE_TCHAR *szValue); |
...
/// Specify the LogId attribute of the log entry that follows. Can be 0 (default) |
...
/// in which case no LogId attribute is output. |
...
static void LogId(const ACE_TCHAR *szName); |
...
/// Specify the URI attribute of the log entry that follows. Can be 0 (default) |
...
/// in which case no URI attribute is output. |
...
static void URI(const ACE_TCHAR *szName); |
...
/// Specifies the stack ID of the current logical thread. Pointer to the name |
...
/// must be stored in the thread-specific storage! Can be set to NULL if |
...
/// the logical thread ID is unknown. |
...
static void StackId(const ACE_TCHAR *szId); |
...
/// Returns the the logical thread ID. Must have been set previously using |
...
/// StackId. |
...
static const ACE_TCHAR *StackId(); |
...
/// Set the stack level in the current logical thread. The value must be stored |
...
/// in the thread-specific storage! |
...
static void StackLevel(int nLevel); |
...
/// Retrieve the stack level in the current logical thread. |
...
static int StackLevel(); |
...
/// Set the context in which the code is operating. Pointer to the name must |
...
/// be stored in the thread-specific storage! |
...
static void Context(const ACE_TCHAR *szName); |
...
/// Retrieve the context in which the code is operating. |
...
static const ACE_TCHAR *Context(); |
...
/// Supply data with the log entry that follows. |
...
/// The maximum length for AddData value is ADD_DATA_VALUE_MAX (255+\0). If it is too long /// it will be truncated. |
...
static void AddData(const ACE_TCHAR *szName, const ACE_TCHAR *szFormat, ...); |
...
... |
...
}; |
An instance of the LoggingProxy class is created in Container's Init and destroyed in Container's Done method. It is configured from the Container's configuration record This implies that logging proxy can be configured on a per-activator (i.e., per Local Control Unit) basis. using the properties listed below.
...
Due to design of ACE, the callback for logging must be registered as well as unregistered with ACE_Log_Msg per-thread singleton for every thread individually. This is done automatically by the configuration methods of the Container initThread and doneThread that have the following signatures:
Code Block | ||
---|---|---|
| ||
class class maci_EXPORT ContainerImpl : : // . . . |
...
{ |
...
// . . . |
...
static void initThread(const char * threadName = 0); |
...
void doneThread(); |
...
}; |
The two methods are only a part of the Container servant and are not exposed through its CORBA interface.
If a nonempty string is passed as a parameter to initThread, a LM_INFO log entry is output associating the thread-ID of the current thread with its name.
...
The following code submits the source code information:
Code Block | ||
---|---|---|
| ||
ACS_LOG(LM_SOURCE_INFO, // flags |
...
"main", // routine name |
...
(LM_INFO, // informational log entry |
...
"")); // no additional message text |
The resulting log entry in XML would look like this (there would be no white-spaces in the actual output; they are shown below for purposes of legibility only).
Code Block | ||
---|---|---|
| ||
<Info TimeStamp="2000-09-10T21:34:32.132" |
...
File="test.cpp" Line="131" |
...
Routine="main" |
...
Priority='4'></Info> |
Anchor | ||||
---|---|---|---|---|
|
The configuration methods of the Container take care of setting up the runtime context information, e.g. the host name as well as the process and the thread information:
Code Block | ||
---|---|---|
| ||
ACE_Log_Msg::instance()->local_host("host"); // set the host name |
...
LoggingProxy::ProcessName("proc"); // called at process startup |
...
LoggingProxy::ThreadName("thr"); // called at thread startup |
...
ACS_LOG(LM_RUNTIME_CONTEXT, |
...
0, |
...
(LM_ERROR, |
...
"hello")); |
The resulting log entry in XML would look like this:
Code Block | ||
---|---|---|
| ||
<Error TimeStamp="2000-09-10T21:34:31.435" |
...
Host="host" Thread="thr" Process="proc" |
...
Priority='7'/> |
...
Any number 123 |
...
</Error> |
Anchor | ||||
---|---|---|---|---|
|
The following code submits a value of a variable:
Code Block | ||
---|---|---|
| ||
LoggingProxy::AddData("dMyDouble", "%f", dMyDouble); |
...
ACS_LOG(0, "main", (LM_TRACE, "")); |
The length of a value should not exceed 255 characters otherwise it is truncated.
...
The following code overrides the default priority of a log entry:
Code Block | ||
---|---|---|
| ||
ACS_LOG(LM_PRIORITY(12), 0, |
...
(LM_TRACE, // Could |
...
be anything... "Message")) // Could be |
...
anything... |
Anchor | ||||
---|---|---|---|---|
|
...
To
...
submit
...
an
...
arbitrary
...
message,
...
care
...
must
...
be
...
taken
...
not
...
to
...
break
...
XML
...
formatting
...
rules
...
(for
...
example,
...
<
...
and
...
>
...
should
...
be
...
used
...
with
...
care).
...
If
...
the
...
message
...
contents
...
are
...
not
...
known
...
in
...
advance
...
and
...
a
...
possibility
...
exists
...
that
...
they
...
would
...
break
...
XML
...
formatting
...
rules,
...
code
...
like
...
this
...
should
...
be
...
used:
Code Block | ||
---|---|---|
| ||
_// This macro is predefined by ACS_ #define LM_CDATA(t) "<!\[CDATA\[" t "\]\]>" ACE_ERROR((LM_WARNING, LM_CDATA("Some < text %s >"), szAString)) |
The
...
unpredictable
...
text
...
is
...
placed
...
in
...
an
...
XML
...
CDATA
...
section.
...
Anchor | ||||
---|---|---|---|---|
|
...