Provides a variable length argument message logging abstraction. More...
#include <Log_Msg.h>
Public Types | |
enum | { STDERR = 1, LOGGER = 2, OSTREAM = 4, MSG_CALLBACK = 8, VERBOSE = 16, VERBOSE_LITE = 32, SILENT = 64, SYSLOG = 128, CUSTOM = 256 } |
enum | MASK_TYPE { PROCESS = 0, THREAD = 1 } |
Public Member Functions | |
ACE_Log_Msg (void) | |
Initialize logger. | |
~ACE_Log_Msg (void) | |
cleanup logger. | |
int | open (const ACE_TCHAR *prog_name, u_long options_flags=ACE_Log_Msg::STDERR, const ACE_TCHAR *logger_key=0) |
Initialize the ACE logging facility. | |
void | set_flags (u_long f) |
void | clr_flags (u_long f) |
u_long | flags (void) |
void | sync (const ACE_TCHAR *program_name) |
void | op_status (int status) |
int | op_status (void) const |
void | errnum (int) |
int | errnum (void) const |
void | linenum (int) |
Set the line number where an error occurred. | |
int | linenum (void) const |
Get the line number where an error occurred. | |
void | file (const char *) |
Set the file name where an error occurred. | |
const char * | file (void) |
Get the file name where an error occurred. | |
void | msg (const ACE_TCHAR *) |
Set the message that describes what type of error occurred. | |
const ACE_TCHAR * | msg (void) |
Get the message that describes what type of error occurred. | |
void | restart (bool r) |
bool | restart (void) const |
void | msg_ostream (ACE_OSTREAM_TYPE *) |
Update the ostream without overwriting the delete_ostream_ flag. | |
void | msg_ostream (ACE_OSTREAM_TYPE *, bool delete_ostream) |
ACE_OSTREAM_TYPE * | msg_ostream (void) const |
Get the ostream that is used to print error messages. | |
ACE_Log_Msg_Callback * | msg_callback (ACE_Log_Msg_Callback *c) |
ACE_Log_Msg_Callback * | msg_callback (void) const |
int | inc (void) |
Nesting depth increment. | |
int | dec (void) |
Nesting depth decrement. | |
int | trace_depth (void) const |
Get trace depth. | |
void | trace_depth (int) |
Set trace depth. | |
bool | trace_active (void) const |
Get trace active status. | |
void | trace_active (bool value) |
Set trace active status. | |
ACE_Thread_Descriptor * | thr_desc (void) const |
Get the TSS thread descriptor. | |
void | thr_desc (ACE_Thread_Descriptor *td) |
void | stop_tracing (void) |
Stop tracing status on a per-thread basis... | |
void | start_tracing (void) |
Start tracing status on a per-thread basis... | |
bool | tracing_enabled (void) const |
Query tracing status on a per-thread basis... | |
u_long | priority_mask (MASK_TYPE=THREAD) |
Get the current ACE_Log_Priority mask. | |
u_long | priority_mask (u_long, MASK_TYPE=THREAD) |
Set the ACE_Log_Priority mask, returns original mask. | |
int | log_priority_enabled (ACE_Log_Priority log_priority) |
Return true if the requested priority is enabled. | |
int | log_priority_enabled (ACE_Log_Priority log_priority, const char *,...) |
Return true if the requested priority is enabled. | |
pid_t | getpid (void) const |
const ACE_TCHAR * | local_host (void) const |
Get the name of the local host. | |
void | local_host (const ACE_TCHAR *) |
Set the name of the local host. | |
void | set (const char *file, int line, int op_status=-1, int errnum=0, bool restart=true, ACE_OSTREAM_TYPE *os=0, ACE_Log_Msg_Callback *c=0) |
void | conditional_set (const char *file, int line, int op_status, int errnum) |
ssize_t | log (ACE_Log_Priority priority, const ACE_TCHAR *format,...) |
ssize_t | log (const ACE_TCHAR *format, ACE_Log_Priority priority, va_list argp) |
ssize_t | log (ACE_Log_Record &log_record, int suppress_stderr=0) |
int | log_hexdump (ACE_Log_Priority log_priority, const char *buffer, size_t size, const ACE_TCHAR *text=0) |
void | dump (void) const |
Dump the state of an object. | |
Allow apps to acquire and release internal synchronization | |
This lock is used internally by the ACE_Log_Msg implementation. By exporting the lock, applications can hold the lock atomically over a number of calls to ACE_Log_Msg. | |
int | acquire (void) |
Acquire the internal lock. | |
int | release (void) |
Release the internal lock. | |
Static Public Member Functions | |
static ACE_Log_Msg * | instance (void) |
Returns a pointer to the Singleton. | |
static int | last_error_adapter (void) |
Returns last error. | |
static int | exists (void) |
Returns non-null if an ACE_Log_Msg exists for the calling thread. | |
static const ACE_TCHAR * | program_name (void) |
Returns the current program name used for logging. | |
static void | disable_debug_messages (ACE_Log_Priority priority=LM_DEBUG) |
static void | enable_debug_messages (ACE_Log_Priority priority=LM_DEBUG) |
static ACE_Log_Msg_Backend * | msg_backend (ACE_Log_Msg_Backend *b) |
static ACE_Log_Msg_Backend * | msg_backend (void) |
static void | init_hook (ACE_OS_Log_Msg_Attributes &attributes) |
static void | inherit_hook (ACE_OS_Thread_Descriptor *thr_desc, ACE_OS_Log_Msg_Attributes &attributes) |
Public Attributes | |
ACE_ALLOC_HOOK_DECLARE | |
Declare the dynamic allocation hooks. | |
bool | is_set_ |
const char * | file_ |
int | line_ |
int | op_status_ |
Private Types | |
typedef ACE_Atomic_Op < ACE_SYNCH_MUTEX, unsigned long > | Atomic_ULong |
Private Member Functions | |
void | cleanup_ostream () |
ACE_Log_Msg & | operator= (const ACE_Log_Msg &) |
ACE_Log_Msg (const ACE_Log_Msg &) | |
Static Private Member Functions | |
static void | close (void) |
For cleanup, at program termination. | |
static void | sync_hook (const ACE_TCHAR *prg_name) |
Decouple the OS layer from the ACE_Log_Msg layer. | |
static ACE_OS_Thread_Descriptor * | thr_desc_hook (void) |
Return the TSS singleton thread descriptor. | |
Private Attributes | |
int | status_ |
Status of operation (-1 means failure, >= 0 means success). | |
int | errnum_ |
Type of error that occurred (see <sys/errno.h>). | |
int | linenum_ |
Line number where the error occurred. | |
char | file_ [MAXPATHLEN+1] |
File where the error occurred. | |
ACE_TCHAR * | msg_ |
bool | restart_ |
ACE_OSTREAM_TYPE * | ostream_ |
The ostream where logging messages can be written. | |
Atomic_ULong * | ostream_refcount_ |
ACE_Log_Msg_Callback * | msg_callback_ |
The callback object. | |
int | trace_depth_ |
Depth of the nesting for printing traces. | |
bool | trace_active_ |
Are we already within an ACE_Trace constructor call? | |
bool | tracing_enabled_ |
Are we allowing tracing in this thread? | |
ACE_Thread_Descriptor * | thr_desc_ |
u_long | priority_mask_ |
int | timestamp_ |
Always timestamp? | |
struct { | |
bool is_set_ | |
const char * file_ | |
int line_ | |
int op_status_ | |
int errnum_ | |
} | conditional_values_ |
Static Private Attributes | |
static u_long | process_priority_mask_ |
static const ACE_TCHAR * | program_name_ = 0 |
Records the program name. | |
static const ACE_TCHAR * | local_host_ = 0 |
Name of the local host (used when printing messages). | |
static pid_t | pid_ = -2 |
Process id of the current process. | |
static u_long | flags_ = ACE_Log_Msg::STDERR |
Default is to use stderr. | |
static ptrdiff_t | msg_off_ = 0 |
Offset of msg_[]. | |
static int | instance_count_ = 0 |
static u_long | default_priority_mask_ = 0 |
Provides a variable length argument message logging abstraction.
This class is very flexible since it allows formatted error messages to be printed in a thread-safe manner to various locations, such as stderr, cerr, a distributed logger, etc. The current message is also kept in a thread-specific storage location (threads spawned using ACE_Thread_Manager automatically get an ACE_Log_Msg object that inherits the spawning thread's settings), which can be used to communicate errors between framework methods and callers. A message is logged by the log() method, only if the message priority is currently enabled. Moreover, only the current log message is stored here -- it will be overwritten by the subsequent call to log().
The ACE_Log_Msg class uses two priority masks to control its logging behavior. The priority_mask_
object attribute is thread- specific and specifies the priority levels logged by the thread. The process_priority_mask_
class attribute is not thread-specific and specifies the priority levels that will be logged by all threads in the process. By default, all levels are disabled for priority_mask_
and all levels are enabled for process_priority_mask_
(i.e. the process-wide mask controls the settings, and each instance can expand on it if desired). Both priority masks can be modified using the priority_mask() method of this class.
Definition at line 179 of file Log_Msg.h.
typedef ACE_Atomic_Op<ACE_SYNCH_MUTEX, unsigned long> ACE_Log_Msg::Atomic_ULong [private] |
This pointer is 0 if we are not reference counting (the user has not passed "true" for the delete_ostream argument to msg_ostream). If we are reference counting, this points to a shared count that will be deleted when it reaches zero. Since we want optional but shared ownership neither std::auto_ptr nor ACE_Strong_Bound_Ptr have the right semantics. *Bound_Ptr also doesn't take advantage of Atomic_Op.
anonymous enum |
Definition at line 183 of file Log_Msg.h.
{ /// Write messages to stderr. STDERR = 1, /// Write messages to the local client logger deamon. LOGGER = 2, /// Write messages to the ostream * stored in thread-specific /// storage. OSTREAM = 4, /// Write messages to the callback object. MSG_CALLBACK = 8, /// Display messages in a verbose manner. VERBOSE = 16, /// Display messages in a less verbose manner (i.e., only print /// information that can change between calls). VERBOSE_LITE = 32, /// Do not print messages at all (just leave in thread-specific /// storage for later inspection). SILENT = 64, /// Write messages to the system's event log. SYSLOG = 128, /// Write messages to the user provided backend CUSTOM = 256 };
ACE_Log_Msg::ACE_Log_Msg | ( | void | ) |
Initialize logger.
Definition at line 641 of file Log_Msg.cpp.
: status_ (0), errnum_ (0), linenum_ (0), msg_ (0), restart_ (1), // Restart by default... ostream_ (0), ostream_refcount_ (0), msg_callback_ (0), trace_depth_ (0), trace_active_ (false), tracing_enabled_ (true), // On by default? thr_desc_ (0), priority_mask_ (default_priority_mask_), timestamp_ (0) { // ACE_TRACE ("ACE_Log_Msg::ACE_Log_Msg"); ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, *ACE_Log_Msg_Manager::get_lock ())); ++instance_count_; if (this->instance_count_ == 1) ACE_Base_Thread_Adapter::set_log_msg_hooks (ACE_Log_Msg::init_hook, ACE_Log_Msg::inherit_hook, ACE_Log_Msg::close, ACE_Log_Msg::sync_hook, ACE_Log_Msg::thr_desc_hook); this->conditional_values_.is_set_ = false; char *timestamp = ACE_OS::getenv ("ACE_LOG_TIMESTAMP"); if (timestamp != 0) { // If variable is set or is set to date tag so we print date and time. if (ACE_OS::strcmp (timestamp, "TIME") == 0) { this->timestamp_ = 1; } else if (ACE_OS::strcmp (timestamp, "DATE") == 0) { this->timestamp_ = 2; } } ACE_NEW_NORETURN (this->msg_, ACE_TCHAR[ACE_MAXLOGMSGLEN+1]); }
ACE_Log_Msg::~ACE_Log_Msg | ( | void | ) |
cleanup logger.
Definition at line 689 of file Log_Msg.cpp.
{ #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) int instance_count = 0; // Only hold the guard while updating the instance_count_. // If ACE_Log_Msg_Manager::close () is called, the lock will // be deleted. { ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, *ACE_Log_Msg_Manager::get_lock ())); instance_count = --instance_count_; } // Release the guard. #else /* ! ACE_MT_SAFE */ int instance_count = --instance_count_; #endif /* ! ACE_MT_SAFE */ // If this is the last instance then cleanup. Only the last // thread to destroy its ACE_Log_Msg instance should execute // this block. if (instance_count == 0) { // Destroy the message queue instance. if (ACE_Log_Msg_Manager::log_backend_ != 0) ACE_Log_Msg_Manager::log_backend_->close (); // Close down custom backend if (ACE_Log_Msg_Manager::custom_backend_ != 0) ACE_Log_Msg_Manager::custom_backend_->close (); # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) # if defined (ACE_HAS_TSS_EMULATION) ACE_Log_Msg_Manager::close (); # endif /* ACE_HAS_TSS_EMULATION */ # endif /* ACE_MT_SAFE */ if (ACE_Log_Msg::program_name_) { ACE_OS::free ((void *) ACE_Log_Msg::program_name_); ACE_Log_Msg::program_name_ = 0; } if (ACE_Log_Msg::local_host_) { ACE_OS::free ((void *) ACE_Log_Msg::local_host_); ACE_Log_Msg::local_host_ = 0; } } this->cleanup_ostream (); delete[] this->msg_; }
ACE_Log_Msg::ACE_Log_Msg | ( | const ACE_Log_Msg & | ) | [private] |
int ACE_Log_Msg::acquire | ( | void | ) |
Acquire the internal lock.
Definition at line 600 of file Log_Msg.cpp.
{ ACE_TRACE ("ACE_Log_Msg::acquire"); #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) return ACE_Log_Msg_Manager::get_lock ()->acquire (); #else /* ! ACE_MT_SAFE */ return 0; #endif /* ! ACE_MT_SAFE */ }
void ACE_Log_Msg::cleanup_ostream | ( | ) | [private] |
Definition at line 747 of file Log_Msg.cpp.
{ if (this->ostream_refcount_) { if (--*this->ostream_refcount_ == 0) { delete this->ostream_refcount_; #if defined (ACE_LACKS_IOSTREAM_TOTALLY) ACE_OS::fclose (this->ostream_); #else delete this->ostream_; this->ostream_ = 0; #endif } this->ostream_refcount_ = 0; } }
void ACE_Log_Msg::close | ( | void | ) | [static, private] |
For cleanup, at program termination.
Definition at line 473 of file Log_Msg.cpp.
{ // This call needs to go here to avoid memory leaks. ACE_MT (ACE_Log_Msg_Manager::close ()); // Please note that this will be called by a statement that is // harded coded into the ACE_Object_Manager's shutdown sequence, in // its destructor. #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) && \ (defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \ defined (ACE_HAS_TSS_EMULATION)) if (ACE_Log_Msg::key_created_) { ACE_thread_mutex_t *lock = reinterpret_cast<ACE_thread_mutex_t *> (ACE_OS_Object_Manager::preallocated_object [ACE_OS_Object_Manager::ACE_LOG_MSG_INSTANCE_LOCK]); ACE_OS::thread_mutex_lock (lock); if (ACE_Log_Msg::key_created_) { // Clean up this ACE_Log_Msg instance and reset the TSS to // prevent any future cleanup attempts via TSS mechanisms at // thread exit. Otherwise in the event of a dynamic library // unload of libACE, by a program not linked with libACE, // ACE_TSS_cleanup will be invoked after libACE has been unloaded. // See Bugzilla 2980 for lots of details. ACE_Log_Msg *tss_log_msg = 0; void *temp = 0; // Get the tss_log_msg from thread-specific storage. if (ACE_Thread::getspecific (*(log_msg_tss_key ()), &temp) != -1 && temp) { tss_log_msg = static_cast <ACE_Log_Msg *> (temp); // we haven't been cleaned up ACE_TSS_CLEANUP_NAME(tss_log_msg); if (ACE_Thread::setspecific(*(log_msg_tss_key()), reinterpret_cast <void *>(0)) != 0) ACE_OS::printf ("ACE_Log_Msg::close failed to ACE_Thread::setspecific to 0\n"); } // The key is not needed any longer; ACE_Log_Msg is closing // and will need to be reopened if this process wishes to use // logging again. So delete the key. ACE_Thread::keyfree (*(log_msg_tss_key())); ACE_Log_Msg::key_created_ = false; } ACE_OS::thread_mutex_unlock (lock); } #endif /* (ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION) && ACE_MT_SAFE */ }
void ACE_Log_Msg::clr_flags | ( | u_long | f | ) |
Disable the bits in the logger's options flags.
Definition at line 590 of file Log_Msg.cpp.
{ ACE_TRACE ("ACE_Log_Msg::clr_flags"); ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, *ACE_Log_Msg_Manager::get_lock ())); ACE_CLR_BITS (ACE_Log_Msg::flags_, flgs); }
void ACE_Log_Msg::conditional_set | ( | const char * | file, | |
int | line, | |||
int | op_status, | |||
int | errnum | |||
) |
These values are only actually set if the requested priority is enabled.
Definition at line 2419 of file Log_Msg.cpp.
{ this->conditional_values_.is_set_ = true; this->conditional_values_.file_ = filename; this->conditional_values_.line_ = line; this->conditional_values_.op_status_ = status; this->conditional_values_.errnum_ = err; }
int ACE_Log_Msg::dec | ( | void | ) | [inline] |
Nesting depth decrement.
Definition at line 93 of file Log_Msg.inl.
{ return this->trace_depth_ == 0 ? 0 : --this->trace_depth_; }
void ACE_Log_Msg::disable_debug_messages | ( | ACE_Log_Priority | priority = LM_DEBUG |
) | [static] |
Clears the flag from the default priority mask used to initialize ACE_Log_Msg instances.
Definition at line 426 of file Log_Msg.cpp.
{ ACE_CLR_BITS (ACE_Log_Msg::default_priority_mask_, priority); ACE_Log_Msg *i = ACE_Log_Msg::instance (); i->priority_mask (i->priority_mask () & ~priority); }
void ACE_Log_Msg::dump | ( | void | ) | const |
Dump the state of an object.
Definition at line 2432 of file Log_Msg.cpp.
{ #if defined (ACE_HAS_DUMP) ACE_TRACE ("ACE_Log_Msg::dump"); ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("status_ = %d\n"), this->status_)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nerrnum_ = %d\n"), this->errnum_)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nlinenum_ = %d\n"), this->linenum_)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nfile_ = %C\n"), this->file_)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nmsg_ = %s\n"), this->msg_)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nrestart_ = %d\n"), this->restart_)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nostream_ = %@\n"), this->ostream_)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nmsg_callback_ = %@\n"), this->msg_callback_)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nprogram_name_ = %s\n"), this->program_name_ ? this->program_name_ : ACE_TEXT ("<unknown>"))); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nlocal_host_ = %s\n"), this->local_host_ ? this->local_host_ : ACE_TEXT ("<unknown>"))); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\npid_ = %d\n"), this->getpid ())); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nflags_ = 0x%x\n"), this->flags_)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntrace_depth_ = %d\n"), this->trace_depth_)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntrace_active_ = %d\n"), this->trace_active_)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntracing_enabled_ = %d\n"), this->tracing_enabled_)); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\npriority_mask_ = 0x%x\n"), this->priority_mask_)); if (this->thr_desc_ != 0 && this->thr_desc_->state () != 0) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nthr_state_ = %d\n"), this->thr_desc_->state ())); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nmsg_off_ = %d\n"), this->msg_off_)); // Be sure that there is a message_queue_, with multiple threads. ACE_MT (ACE_Log_Msg_Manager::init_backend ()); ACE_MT (ACE_Log_Msg_Manager::get_lock ()->dump ()); // Synchronize output operations. ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP)); #endif /* ACE_HAS_DUMP */ }
void ACE_Log_Msg::enable_debug_messages | ( | ACE_Log_Priority | priority = LM_DEBUG |
) | [static] |
Sets the flag in the default priority mask used to initialize ACE_Log_Msg instances.
Definition at line 415 of file Log_Msg.cpp.
{ ACE_SET_BITS (ACE_Log_Msg::default_priority_mask_, priority); ACE_Log_Msg *i = ACE_Log_Msg::instance (); i->priority_mask (i->priority_mask () | priority); }
void ACE_Log_Msg::errnum | ( | int | e | ) | [inline] |
Set the value of the errnum (by convention this corresponds to errno).
Definition at line 65 of file Log_Msg.inl.
{ this->errnum_ = e; }
int ACE_Log_Msg::errnum | ( | void | ) | const [inline] |
Get the value of the errnum (by convention this corresponds to errno).
Definition at line 58 of file Log_Msg.inl.
{ return this->errnum_; }
int ACE_Log_Msg::exists | ( | void | ) | [static] |
Returns non-null if an ACE_Log_Msg exists for the calling thread.
Definition at line 266 of file Log_Msg.cpp.
{ #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \ defined (ACE_HAS_TSS_EMULATION) void *tss_log_msg = 0; // The actual type is ACE_Log_Msg*, but we need this // void to keep G++ from complaining. // Get the tss_log_msg from thread-specific storage. return ACE_Log_Msg::key_created_ && ACE_Thread::getspecific (*(log_msg_tss_key ()), &tss_log_msg) != -1 && tss_log_msg != 0; # else # error "Platform must support thread-specific storage if threads are used." # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */ #else /* ! ACE_MT_SAFE */ return 1; #endif /* ! ACE_MT_SAFE */ }
void ACE_Log_Msg::file | ( | const char * | s | ) | [inline] |
Set the file name where an error occurred.
Definition at line 165 of file Log_Msg.inl.
{ ACE_OS::strsncpy (this->file_, s, sizeof this->file_); }
const char * ACE_Log_Msg::file | ( | void | ) | [inline] |
Get the file name where an error occurred.
Definition at line 158 of file Log_Msg.inl.
{ return this->file_; }
u_long ACE_Log_Msg::flags | ( | void | ) |
Return the bits in the logger's options flags.
Definition at line 568 of file Log_Msg.cpp.
{ ACE_TRACE ("ACE_Log_Msg::flags"); u_long result; ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *ACE_Log_Msg_Manager::get_lock (), 0)); result = ACE_Log_Msg::flags_; return result; }
pid_t ACE_Log_Msg::getpid | ( | void | ) | const [inline] |
Optimize reading of the pid (avoids a system call if the value is cached...).
Definition at line 224 of file Log_Msg.inl.
{ if (ACE_Log_Msg::pid_ == -2) ACE_Log_Msg::pid_ = ACE_OS::getpid (); return ACE_Log_Msg::pid_; }
int ACE_Log_Msg::inc | ( | void | ) | [inline] |
Nesting depth increment.
Definition at line 86 of file Log_Msg.inl.
{ return this->trace_depth_++; }
void ACE_Log_Msg::inherit_hook | ( | ACE_OS_Thread_Descriptor * | thr_desc, | |
ACE_OS_Log_Msg_Attributes & | attributes | |||
) | [static] |
Inherit hook, the attributes field is a ACE_OS_Log_Msg_Attributes object, invoke the inherit_log_msg() method on it, then destroy it and set the attribute argument to 0.
Definition at line 2635 of file Log_Msg.cpp.
{ #if !defined (ACE_THREADS_DONT_INHERIT_LOG_MSG) && \ !defined (ACE_HAS_MINIMAL_ACE_OS) // Inherit the logging features if the parent thread has an // <ACE_Log_Msg>. Note that all of the following operations occur // within thread-specific storage. ACE_Log_Msg *new_log = ACE_LOG_MSG; // Note that we do not inherit the callback because this might have // been allocated off of the stack of the original thread, in which // case all hell would break loose... if (attributes.ostream_) { new_log->ostream_ = attributes.ostream_; new_log->ostream_refcount_ = static_cast<Atomic_ULong *> (attributes.ostream_refcount_); new_log->priority_mask (attributes.priority_mask_); if (attributes.tracing_enabled_) new_log->start_tracing (); new_log->restart (attributes.restart_); new_log->trace_depth (attributes.trace_depth_); } // @@ Now the TSS Log_Msg has been created, cache my thread // descriptor in. if (thr_desc != 0) // This downcast is safe. We do it to avoid having to #include // ace/Thread_Manager.h. new_log->thr_desc (static_cast<ACE_Thread_Descriptor *> (thr_desc)); // Block the thread from proceeding until // thread manager has thread descriptor ready. #endif /* ! ACE_THREADS_DONT_INHERIT_LOG_MSG && ! ACE_HAS_MINIMAL_ACE_OS */ }
void ACE_Log_Msg::init_hook | ( | ACE_OS_Log_Msg_Attributes & | attributes | ) | [static] |
attributes | Init hook, create a Log_Msg_Attribute object, initialize its attributes from the TSS Log_Msg and save the object in the attributes argument |
Definition at line 2603 of file Log_Msg.cpp.
{ # if defined (ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS) attributes.seh_except_selector_ = selector; attributes.seh_except_handler_ = handler; # endif /* ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS */ if (ACE_Log_Msg::exists ()) { ACE_Log_Msg *inherit_log = ACE_LOG_MSG; attributes.ostream_ = inherit_log->msg_ostream (); if (attributes.ostream_ && inherit_log->ostream_refcount_) { ++*inherit_log->ostream_refcount_; attributes.ostream_refcount_ = inherit_log->ostream_refcount_; } else { attributes.ostream_refcount_ = 0; } attributes.priority_mask_ = inherit_log->priority_mask (); attributes.tracing_enabled_ = inherit_log->tracing_enabled (); attributes.restart_ = inherit_log->restart (); attributes.trace_depth_ = inherit_log->trace_depth (); } }
ACE_Log_Msg * ACE_Log_Msg::instance | ( | void | ) | [static] |
Returns a pointer to the Singleton.
Definition at line 287 of file Log_Msg.cpp.
{ #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) # if defined (ACE_HAS_THREAD_SPECIFIC_STORAGE) || \ defined (ACE_HAS_TSS_EMULATION) // TSS Singleton implementation. if (!ACE_Log_Msg::key_created_) { ACE_thread_mutex_t *lock = reinterpret_cast<ACE_thread_mutex_t *> ( ACE_OS_Object_Manager::preallocated_object [ACE_OS_Object_Manager::ACE_LOG_MSG_INSTANCE_LOCK]); if (1 == ACE_OS_Object_Manager::starting_up()) //This function is called before ACE_OS_Object_Manager is //initialized. So the lock might not be valid. Assume it's //single threaded and so don't need the lock. ; else ACE_OS::thread_mutex_lock (lock); if (!ACE_Log_Msg::key_created_) { // Allocate the Singleton lock. ACE_Log_Msg_Manager::get_lock (); { ACE_NO_HEAP_CHECK; if (ACE_Thread::keycreate (log_msg_tss_key (), &ACE_TSS_CLEANUP_NAME) != 0) { if (1 == ACE_OS_Object_Manager::starting_up()) //This function is called before ACE_OS_Object_Manager is //initialized. So the lock might not be valid. Assume it's //single threaded and so don't need the lock. ; else ACE_OS::thread_mutex_unlock (lock); return 0; // Major problems, this should *never* happen! } } ACE_Log_Msg::key_created_ = true; } if (1 == ACE_OS_Object_Manager::starting_up()) //This function is called before ACE_OS_Object_Manager is //initialized. So the lock might not be valid. Assume it's //single threaded and so don't need the lock. ; else ACE_OS::thread_mutex_unlock (lock); } ACE_Log_Msg *tss_log_msg = 0; void *temp = 0; // Get the tss_log_msg from thread-specific storage. if (ACE_Thread::getspecific (*(log_msg_tss_key ()), &temp) == -1) return 0; // This should not happen! tss_log_msg = static_cast <ACE_Log_Msg *> (temp); // Check to see if this is the first time in for this thread. if (tss_log_msg == 0) { // Allocate memory off the heap and store it in a pointer in // thread-specific storage (on the stack...). Stop heap // checking, the memory will always be freed by the thread // rundown because of the TSS callback set up when the key was // created. This prevents from getting these blocks reported as // memory leaks. { ACE_NO_HEAP_CHECK; ACE_NEW_RETURN (tss_log_msg, ACE_Log_Msg, 0); // Store the dynamically allocated pointer in thread-specific // storage. It gets deleted via the ACE_TSS_cleanup function // when the thread terminates. if (ACE_Thread::setspecific (*(log_msg_tss_key()), reinterpret_cast<void *> (tss_log_msg)) != 0) return 0; // Major problems, this should *never* happen! } } return tss_log_msg; # else # error "Platform must support thread-specific storage if threads are used." # endif /* ACE_HAS_THREAD_SPECIFIC_STORAGE || ACE_HAS_TSS_EMULATION */ #else /* ! ACE_MT_SAFE */ // We don't have threads, we cannot call // ACE_Log_Msg_Manager::get_lock () to initialize the logger // callback, so instead we do it here. if (ACE_Log_Msg_Manager::init_backend () == -1) return 0; // Singleton implementation. if (log_msg_cleanup == 0) { ACE_NEW_RETURN (log_msg_cleanup, ACE_Msg_Log_Cleanup, 0); // Register the instance for destruction at program termination. ACE_Object_Manager::at_exit (log_msg_cleanup, 0, typeid (*log_msg_cleanup).name ()); } return &log_msg_cleanup->object (); #endif /* ! ACE_MT_SAFE */ }
int ACE_Log_Msg::last_error_adapter | ( | void | ) | [static] |
void ACE_Log_Msg::linenum | ( | int | l | ) | [inline] |
Set the line number where an error occurred.
Definition at line 79 of file Log_Msg.inl.
{ this->linenum_ = l; }
int ACE_Log_Msg::linenum | ( | void | ) | const [inline] |
Get the line number where an error occurred.
Definition at line 72 of file Log_Msg.inl.
{ return this->linenum_; }
const ACE_TCHAR * ACE_Log_Msg::local_host | ( | void | ) | const [inline] |
Get the name of the local host.
Definition at line 217 of file Log_Msg.inl.
{ return ACE_Log_Msg::local_host_; }
void ACE_Log_Msg::local_host | ( | const ACE_TCHAR * | s | ) |
Set the name of the local host.
Definition at line 2569 of file Log_Msg.cpp.
{ if (s) { ACE_OS::free ((void *) ACE_Log_Msg::local_host_); { ACE_NO_HEAP_CHECK; ACE_ALLOCATOR (ACE_Log_Msg::local_host_, ACE_OS::strdup (s)); } } }
ssize_t ACE_Log_Msg::log | ( | ACE_Log_Record & | log_record, | |
int | suppress_stderr = 0 | |||
) |
Log a custom built log record to the currently enabled logging sinks.
Definition at line 2252 of file Log_Msg.cpp.
{ ssize_t result = 0; // Format the message and print it to stderr and/or ship it off to // the log_client daemon, and/or print it to the ostream. Of // course, only print the message if "SILENT" mode is disabled. if (ACE_BIT_DISABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SILENT)) { bool tracing = this->tracing_enabled (); this->stop_tracing (); #if !defined (ACE_WIN32) // Make this block signal-safe. ACE_Log_Msg_Sig_Guard sb; #endif /* !ACE_WIN32 */ // Do the callback, if needed, before acquiring the lock // to avoid holding the lock during the callback so we don't // have deadlock if the callback uses the logger. if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::MSG_CALLBACK) && this->msg_callback () != 0) this->msg_callback ()->log (log_record); // Make sure that the lock is held during all this. ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *ACE_Log_Msg_Manager::get_lock (), -1)); if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::STDERR) && !suppress_stderr) // This is taken care of by our caller. log_record.print (ACE_Log_Msg::local_host_, ACE_Log_Msg::flags_, stderr); if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::CUSTOM) || ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG) || ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER)) { // Be sure that there is a message_queue_, with multiple threads. ACE_MT (ACE_Log_Msg_Manager::init_backend ()); } if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER) || ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG)) { result = ACE_Log_Msg_Manager::log_backend_->log (log_record); } if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::CUSTOM) && ACE_Log_Msg_Manager::custom_backend_ != 0) { result = ACE_Log_Msg_Manager::custom_backend_->log (log_record); } // This must come last, after the other two print operations // (see the <ACE_Log_Record::print> method for details). if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::OSTREAM) && this->msg_ostream () != 0) log_record.print (ACE_Log_Msg::local_host_, ACE_Log_Msg::flags_, #if defined (ACE_LACKS_IOSTREAM_TOTALLY) static_cast<FILE *> (this->msg_ostream ()) #else /* ! ACE_LACKS_IOSTREAM_TOTALLY */ *this->msg_ostream () #endif /* ! ACE_LACKS_IOSTREAM_TOTALLY */ ); if (tracing) this->start_tracing (); } return result; }
ssize_t ACE_Log_Msg::log | ( | ACE_Log_Priority | log_priority, | |
const ACE_TCHAR * | format_str, | |||
... | ||||
) |
Format a message to the thread-safe ACE logging mechanism. Valid options (prefixed by '', as in printf format strings) include:
Valid Options (prefixed by '', as in printf format strings) include: 'A': print an ACE_timer_t value 'a': exit the program at this point (var-argument is the exit status!) 'b': print a ssize_t value 'B': print a size_t value 'c': print a character 'C': print a character string 'i', 'd': print a decimal number 'I', indent according to nesting depth 'e', 'E', 'f', 'F', 'g', 'G': print a double 'l', print line number where an error occurred. 'M': print the name of the priority of the message. 'm': Return the message corresponding to errno value, e.g., as done by <strerror> 'N': print file name where the error occurred. 'n': print the name of the program (or "<unknown>" if not set) 'o': print as an octal number 'P': format the current process id 'p': format the appropriate errno message from sys_errlist, e.g., as done by <perror> 'Q': print out the uint64 number 'q': print out the int64 number '@': print a void* pointer (in hexadecimal) 'r': call the function pointed to by the corresponding argument 'R': print return status 'S': print out the appropriate signal message corresponding to var-argument, e.g., as done by strsignal() 's': format a character string 'T': print timestamp in hour:minute:sec:usec format. 'D': print timestamp in month/day/year hour:minute:sec:usec format. 't': print thread id (1 if single-threaded) 'u': print as unsigned int 'x': print as a hex number 'X': print as a hex number 'w': print a wide character 'W': print out a wide character string. 'z': print an ACE_OS::WChar character 'Z': print an ACE_OS::WChar character string ':': print a time_t value as an integral number '': format a single percent sign, ''
Definition at line 934 of file Log_Msg.cpp.
ssize_t ACE_Log_Msg::log | ( | const ACE_TCHAR * | format, | |
ACE_Log_Priority | priority, | |||
va_list | argp | |||
) |
An alternative logging mechanism that makes it possible to integrate variable argument lists from other logging mechanisms into the ACE mechanism.
Definition at line 978 of file Log_Msg.cpp.
{ ACE_TRACE ("ACE_Log_Msg::log"); // External decls. typedef void (*PTF)(...); // Check if there were any conditional values set. bool const conditional_values = this->conditional_values_.is_set_; // Reset conditional values. this->conditional_values_.is_set_ = false; // Only print the message if <priority_mask_> hasn't been reset to // exclude this logging priority. if (this->log_priority_enabled (log_priority) == 0) return 0; // If conditional values were set and the log priority is correct, // then the values are actually set. if (conditional_values) this->set (this->conditional_values_.file_, this->conditional_values_.line_, this->conditional_values_.op_status_, this->conditional_values_.errnum_, this->restart (), this->msg_ostream (), this->msg_callback ()); // Logging is supposed to be a benign activity (i.e., not interfer // with normal application operations), so don't inadvertently smash // errno! ACE_Errno_Guard guard (errno); ACE_Log_Record log_record (log_priority, ACE_OS::gettimeofday (), this->getpid ()); // bp is pointer to where to put next part of logged message. // bspace is the number of characters remaining in msg_. ACE_TCHAR *bp = const_cast<ACE_TCHAR *> (this->msg ()); size_t bspace = ACE_MAXLOGMSGLEN; // Leave room for Nul term. if (this->msg_off_ <= ACE_Log_Record::MAXLOGMSGLEN) bspace -= static_cast<size_t> (this->msg_off_); // If this platform has snprintf() capability to prevent overrunning the // output buffer, use it. To avoid adding a maintenance-hassle compile- // time couple between here and OS.cpp, don't try to figure this out at // compile time. Instead, do a quick check now; if we get a -1 return, // the platform doesn't support the length-limiting capability. ACE_TCHAR test[2]; bool can_check = ACE_OS::snprintf (test, 1, ACE_TEXT ("x")) != -1; bool abort_prog = false; int exit_value = 0; if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::VERBOSE)) { // Prepend the program name onto this message if (ACE_Log_Msg::program_name_ != 0) { for (const ACE_TCHAR *s = ACE_Log_Msg::program_name_; bspace > 1 && (*bp = *s) != '\0'; ++s, --bspace) bp++; *bp++ = '|'; --bspace; } } if (timestamp_ > 0) { ACE_TCHAR day_and_time[35]; const ACE_TCHAR *s = 0; if (timestamp_ == 1) { // Print just the time s = ACE::timestamp (day_and_time, sizeof day_and_time / sizeof (ACE_TCHAR), 1); } else { // Print time and date ACE::timestamp (day_and_time, sizeof day_and_time / sizeof (ACE_TCHAR)); s = day_and_time; } for (; bspace > 1 && (*bp = *s) != '\0'; ++s, --bspace) ++bp; *bp++ = '|'; --bspace; } while (*format_str != '\0' && bspace > 0) { // Copy input to output until we encounter a %, however a // % followed by another % is not a format specification. if (*format_str != '%') { *bp++ = *format_str++; --bspace; } else if (format_str[1] == '%') // An "escaped" '%' (just print one '%'). { *bp++ = *format_str++; // Store first % ++format_str; // but skip second % --bspace; } else { // This is most likely a format specification that ends with // one of the valid options described previously. To enable full // use of all sprintf capabilities, save the format specifier // from the '%' up to the format letter in a new char array. // This allows the full sprintf capability for padding, field // widths, alignment, etc. Any width/precision requiring a // caller-supplied argument is extracted and placed as text // into the format array. Lastly, we convert the caller-supplied // format specifier from the ACE_Log_Msg-supported list to the // equivalent sprintf specifier, and run the new format spec // through sprintf, adding it to the bp string. const ACE_TCHAR *abort_str = ACE_TEXT ("Aborting..."); const ACE_TCHAR *start_format = format_str; ACE_TCHAR format[128]; // Converted format string ACE_TCHAR *fp; // Current format pointer int wp = 0; // Width/precision extracted from args bool done = false; bool skip_nul_locate = false; int this_len = 0; // How many chars s[n]printf wrote fp = format; *fp++ = *format_str++; // Copy in the % // Initialization to satisfy VC6 int tmp_indent = 0; // Work through the format string to copy in the format // from the caller. While it's going across, extract ints // for '*' width/precision values from the argument list. // When the real format specifier is located, change it to // one recognized by sprintf, if needed, and do the sprintf // call. while (!done) { done = true; // Unless a conversion spec changes it switch (*format_str) { // The initial set of cases are the conversion // specifiers. Copy them in to the format array. // Note we don't use 'l', a normal conversion spec, // as a conversion because it is a ACE_Log_Msg format // specifier. case '-': case '+': case '0': case ' ': case '#': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': case 'L': case 'h': *fp++ = *format_str; done = false; break; case '*': wp = va_arg (argp, int); ACE_OS::sprintf (fp, ACE_TEXT ("%d"), wp); fp += ACE_OS::strlen (fp); done = false; break; case 'A': // ACE_timer_t { ACE_OS::strcpy (fp, ACE_TEXT ("f")); double const value = va_arg (argp, double); if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, value); else this_len = ACE_OS::sprintf (bp, format, value); ACE_UPDATE_COUNT (bspace, this_len); } break; case 'a': // Abort program after handling all of format string. abort_prog = true; exit_value = va_arg (argp, int); ACE_OS::strsncpy (bp, abort_str, bspace); if (bspace > ACE_OS::strlen (abort_str)) bspace -= ACE_OS::strlen (abort_str); else bspace = 0; break; case 'l': // Source file line number ACE_OS::strcpy (fp, ACE_TEXT ("d")); if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, this->linenum ()); else this_len = ACE_OS::sprintf (bp, format, this->linenum ()); ACE_UPDATE_COUNT (bspace, this_len); break; case 'N': // Source file name #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR) ACE_OS::strcpy (fp, ACE_TEXT ("ls")); #else ACE_OS::strcpy (fp, ACE_TEXT ("s")); #endif if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, this->file () ? ACE_TEXT_CHAR_TO_TCHAR (this->file ()) : ACE_TEXT ("<unknown file>")); else this_len = ACE_OS::sprintf (bp, format, this->file () ? ACE_TEXT_CHAR_TO_TCHAR (this->file ()) : ACE_TEXT ("<unknown file>")); ACE_UPDATE_COUNT (bspace, this_len); break; case 'n': // Program name #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR) ACE_OS::strcpy (fp, ACE_TEXT ("ls")); #else /* ACE_WIN32 && ACE_USES_WCHAR */ ACE_OS::strcpy (fp, ACE_TEXT ("s")); #endif if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, ACE_Log_Msg::program_name_ ? ACE_Log_Msg::program_name_ : ACE_TEXT ("<unknown>")); else this_len = ACE_OS::sprintf (bp, format, ACE_Log_Msg::program_name_ ? ACE_Log_Msg::program_name_ : ACE_TEXT ("<unknown>")); ACE_UPDATE_COUNT (bspace, this_len); break; case 'P': // Process ID #if defined (ACE_OPENVMS) // Print the process id in hex on OpenVMS. ACE_OS::strcpy (fp, ACE_TEXT ("x")); #else ACE_OS::strcpy (fp, ACE_TEXT ("d")); #endif if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, static_cast<int> (this->getpid ())); else this_len = ACE_OS::sprintf (bp, format, static_cast<int> (this->getpid ())); ACE_UPDATE_COUNT (bspace, this_len); break; case 'p': // <errno> string, ala perror() { errno = 0; char *msg = ACE_OS::strerror (ACE::map_errno (this->errnum ())); // Windows can try to translate the errnum using // system calls if strerror() doesn't get anything useful. #if defined (ACE_WIN32) if (errno == 0) { #endif #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR) ACE_OS::strcpy (fp, ACE_TEXT ("ls: %ls")); wchar_t *str = va_arg (argp, wchar_t *); #else ACE_OS::strcpy (fp, ACE_TEXT ("s: %s")); ACE_TCHAR *str = va_arg (argp, ACE_TCHAR *); #endif if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, str ? str : ACE_TEXT ("(null)"), ACE_TEXT_CHAR_TO_TCHAR (msg)); else this_len = ACE_OS::sprintf (bp, format, str ? str : ACE_TEXT ("(null)"), ACE_TEXT_CHAR_TO_TCHAR (msg)); #if defined (ACE_WIN32) } else { errno = ACE::map_errno (this->errnum ()); ACE_TCHAR *lpMsgBuf = 0; // PharLap can't do FormatMessage, so try for socket // error. # if !defined (ACE_HAS_PHARLAP) ACE_TEXT_FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_MAX_WIDTH_MASK | FORMAT_MESSAGE_FROM_SYSTEM, 0, errno, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (ACE_TCHAR *) &lpMsgBuf, 0, 0); # endif /* ACE_HAS_PHARLAP */ // If we don't get a valid response from // <FormatMessage>, we'll assume this is a // WinSock error and so we'll try to convert // it into a string. If this doesn't work it // returns "unknown error" which is fine for // our purposes. ACE_TCHAR *str = va_arg (argp, ACE_TCHAR *); if (lpMsgBuf == 0) { const ACE_TCHAR *message = ACE::sock_error (errno); ACE_OS::strcpy (fp, ACE_TEXT ("s: %s")); if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, str ? str : ACE_TEXT ("(null)"), message); else this_len = ACE_OS::sprintf (bp, format, str ? str : ACE_TEXT ("(null)"), message); } else { ACE_OS::strcpy (fp, ACE_TEXT ("s: %s")); if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, str ? str : ACE_TEXT ("(null)"), lpMsgBuf); else this_len = ACE_OS::sprintf (bp, format, str ? str : ACE_TEXT ("(null)"), lpMsgBuf); // Free the buffer. ::LocalFree (lpMsgBuf); } } #endif /* ACE_WIN32 */ ACE_UPDATE_COUNT (bspace, this_len); break; } case 'M': // Print the name of the priority of the message. // Look at the format precision specifier. .1 is interpreted // as a single character printout, otherwise we print the name of // the priority. // So, did we find a .1 specifier? Do we need to override it? if (format[1] == ACE_TEXT('.') && format[2] == ACE_TEXT('1')) { // Yup. // Print a single character signifying the severity of the message fp = format; fp++; # if defined (ACE_USES_WCHAR) # if defined (ACE_WIN32) // Windows uses 'c' for a wide character ACE_OS::strcpy (fp, ACE_TEXT ("c")); # else // Other platforms behave differently # if defined (HPUX) // HP-Unix compatible ACE_OS::strcpy (fp, ACE_TEXT ("C")); # else // Other ACE_OS::strcpy (fp, ACE_TEXT ("lc")); # endif /* HPUX */ # endif # else /* ACE_USES_WCHAR */ // Non-unicode builds simply use a standard character format specifier ACE_OS::strcpy (fp, ACE_TEXT ("c")); # endif /* ACE_USES_WCHAR */ // Below is an optimized (binary search based) // version of the following simple piece of code: // // log_priority == LM_SHUTDOWN ? 'S' : // Shutdown // log_priority == LM_TRACE ? 'T' : // Trace // log_priority == LM_DEBUG ? 'D' : // Debug // log_priority == LM_INFO ? 'I' : // Info // log_priority == LM_NOTICE ? 'N' : // Notice // log_priority == LM_WARNING ? 'W' : // Warning // log_priority == LM_STARTUP ? 'U' : // Startup // log_priority == LM_ERROR ? 'E' : // Error // log_priority == LM_CRITICAL ? 'C' : // Critical // log_priority == LM_ALERT ? 'A' : // Alert // log_priority == LM_EMERGENCY ? '!' : // Emergency // '?' // Unknown if (can_check) { this_len = ACE_OS::snprintf (bp, bspace, format, #if !defined (ACE_USES_WCHAR) || defined (ACE_WIN32) (int) #else (wint_t) #endif (log_priority <= LM_WARNING) ? (log_priority <= LM_DEBUG) ? (log_priority <= LM_TRACE) ? (log_priority == LM_SHUTDOWN) ? ACE_TEXT('S') : ACE_TEXT('T') : ACE_TEXT('D') : (log_priority <= LM_NOTICE) ? (log_priority == LM_INFO) ? ACE_TEXT('I') : ACE_TEXT('N') : ACE_TEXT('W') : (log_priority <= LM_CRITICAL) ? (log_priority <= LM_ERROR) ? (log_priority == LM_STARTUP) ? ACE_TEXT('U') : ACE_TEXT('E') : ACE_TEXT('C') : (log_priority <= LM_EMERGENCY) ? (log_priority == LM_ALERT) ? ACE_TEXT('A') : ACE_TEXT('!') : ACE_TEXT('?')); } else { this_len = ACE_OS::sprintf (bp, format, #if !defined (ACE_USES_WCHAR) || defined (ACE_WIN32) (int) #else (wint_t) #endif (log_priority <= LM_WARNING) ? (log_priority <= LM_DEBUG) ? (log_priority <= LM_TRACE) ? (log_priority == LM_SHUTDOWN) ? ACE_TEXT('S') : ACE_TEXT('T') : ACE_TEXT('D') : (log_priority <= LM_NOTICE) ? (log_priority == LM_INFO) ? ACE_TEXT('I') : ACE_TEXT('N') : ACE_TEXT('W') : (log_priority <= LM_CRITICAL) ? (log_priority <= LM_ERROR) ? (log_priority == LM_STARTUP) ? ACE_TEXT('U') : ACE_TEXT('E') : ACE_TEXT('C') : (log_priority <= LM_EMERGENCY) ? (log_priority == LM_ALERT) ? ACE_TEXT('A') : ACE_TEXT('!') : ACE_TEXT('?')); } ACE_UPDATE_COUNT (bspace, this_len); } else { // Nope, print out standard priority_name() string #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR) ACE_OS::strcpy (fp, ACE_TEXT ("ls")); #else ACE_OS::strcpy (fp, ACE_TEXT ("s")); #endif if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, ACE_Log_Record::priority_name (log_priority)); else this_len = ACE_OS::sprintf (bp, format, ACE_Log_Record::priority_name (log_priority)); ACE_UPDATE_COUNT (bspace, this_len); } break; case 'm': // Format the string assocated with the errno value. { errno = 0; char *msg = ACE_OS::strerror (ACE::map_errno (this->errnum ())); // Windows can try to translate the errnum using // system calls if strerror() doesn't get anything useful. #if defined (ACE_WIN32) if (errno == 0) { #endif #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR) ACE_OS::strcpy (fp, ACE_TEXT ("ls")); #else /* ACE_WIN32 && ACE_USES_WCHAR */ ACE_OS::strcpy (fp, ACE_TEXT ("s")); #endif if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, ACE_TEXT_CHAR_TO_TCHAR (msg)); else this_len = ACE_OS::sprintf (bp, format, ACE_TEXT_CHAR_TO_TCHAR (msg)); #if defined (ACE_WIN32) } else { errno = ACE::map_errno (this->errnum ()); ACE_TCHAR *lpMsgBuf = 0; // PharLap can't do FormatMessage, so try for socket // error. # if !defined (ACE_HAS_PHARLAP) ACE_TEXT_FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_MAX_WIDTH_MASK | FORMAT_MESSAGE_FROM_SYSTEM, 0, errno, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (ACE_TCHAR *) &lpMsgBuf, 0, 0); # endif /* ACE_HAS_PHARLAP */ // If we don't get a valid response from // <FormatMessage>, we'll assume this is a // WinSock error and so we'll try to convert // it into a string. If this doesn't work it // returns "unknown error" which is fine for // our purposes. if (lpMsgBuf == 0) { const ACE_TCHAR *message = ACE::sock_error (errno); ACE_OS::strcpy (fp, ACE_TEXT ("s")); if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, message); else this_len = ACE_OS::sprintf (bp, format, message); } else { ACE_OS::strcpy (fp, ACE_TEXT ("s")); if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, lpMsgBuf); else this_len = ACE_OS::sprintf (bp, format, lpMsgBuf); // Free the buffer. ::LocalFree (lpMsgBuf); } } #endif /* ACE_WIN32 */ ACE_UPDATE_COUNT (bspace, this_len); break; } case 'R': // Format the return status of the operation. this->op_status (va_arg (argp, int)); ACE_OS::strcpy (fp, ACE_TEXT ("d")); if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, this->op_status ()); else this_len = ACE_OS::sprintf (bp, format, this->op_status ()); ACE_UPDATE_COUNT (bspace, this_len); break; case '{': // Increment the trace_depth, then indent skip_nul_locate = true; (void) this->inc (); break; case '}': // indent, then decrement trace_depth skip_nul_locate = true; (void) this->dec (); break; case '$': // insert a newline, then indent the next line // according to %I *bp++ = '\n'; --bspace; /* fallthrough */ case 'I': // Indent with nesting_depth*width spaces // Caller can do %*I to override nesting indent, and // if %*I was done, wp has the extracted width. #if defined (ACE_HAS_TRACE) if (0 == wp) wp = ACE_Trace::get_nesting_indent (); #else if (0 == wp) wp = 4; #endif /* ACE_HAS_TRACE */ wp *= this->trace_depth_; if (static_cast<size_t> (wp) > bspace) wp = static_cast<int> (bspace); for (tmp_indent = wp; tmp_indent; --tmp_indent) *bp++ = ' '; *bp = '\0'; bspace -= static_cast<size_t> (wp); skip_nul_locate = true; break; case 'r': // Run (invoke) this subroutine. { ptrdiff_t const osave = ACE_Log_Msg::msg_off_; if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SILENT) && bspace > 1) { *bp++ = '{'; --bspace; } ACE_Log_Msg::msg_off_ = bp - this->msg_; (*va_arg (argp, PTF))(); if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SILENT) && bspace > (1 + ACE_OS::strlen (bp))) { bspace -= (ACE_OS::strlen (bp) + 1); bp += ACE_OS::strlen (bp); *bp++ = '}'; } *bp = '\0'; skip_nul_locate = true; ACE_Log_Msg::msg_off_ = osave; break; } case 'S': // format the string for with this signal number. { const int sig = va_arg (argp, int); ACE_OS::strcpy (fp, ACE_TEXT ("s")); if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, ACE_OS::strsignal(sig)); else this_len = ACE_OS::sprintf (bp, format, ACE_OS::strsignal(sig)); ACE_UPDATE_COUNT (bspace, this_len); break; } case 'D': // Format the timestamp in format: // Weekday Month day year hour:minute:sec.usec { ACE_TCHAR day_and_time[35]; // Did we find the flag indicating a time value argument if (format[1] == ACE_TEXT('#')) { ACE_Time_Value* time_value = va_arg (argp, ACE_Time_Value*); ACE::timestamp (*time_value, day_and_time, sizeof day_and_time / sizeof (ACE_TCHAR)); } else { ACE::timestamp (day_and_time, sizeof day_and_time / sizeof (ACE_TCHAR)); } #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR) ACE_OS::strcpy (fp, ACE_TEXT ("ls")); #else ACE_OS::strcpy (fp, ACE_TEXT ("s")); #endif if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, day_and_time); else this_len = ACE_OS::sprintf (bp, format, day_and_time); ACE_UPDATE_COUNT (bspace, this_len); break; } case 'T': // Format the timestamp in // hour:minute:sec:usec format. { ACE_TCHAR day_and_time[35]; #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR) ACE_OS::strcpy (fp, ACE_TEXT ("ls")); #else ACE_OS::strcpy (fp, ACE_TEXT ("s")); #endif // Did we find the flag indicating a time value argument if (format[1] == ACE_TEXT('#')) { ACE_Time_Value* time_value = va_arg (argp, ACE_Time_Value*); if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, ACE::timestamp (*time_value, day_and_time, sizeof day_and_time / sizeof (ACE_TCHAR))); else this_len = ACE_OS::sprintf (bp, format, ACE::timestamp (*time_value, day_and_time, sizeof day_and_time / sizeof (ACE_TCHAR))); } else { if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, ACE::timestamp (day_and_time, sizeof day_and_time / sizeof (ACE_TCHAR))); else this_len = ACE_OS::sprintf (bp, format, ACE::timestamp (day_and_time, sizeof day_and_time / sizeof (ACE_TCHAR))); } ACE_UPDATE_COUNT (bspace, this_len); break; } case 't': // Format thread id. #if defined (ACE_WIN32) ACE_OS::strcpy (fp, ACE_TEXT ("u")); if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, static_cast<unsigned> (ACE_Thread::self ())); else this_len = ACE_OS::sprintf (bp, format, static_cast <unsigned> (ACE_Thread::self ())); #elif defined (DIGITAL_UNIX) ACE_OS::strcpy (fp, ACE_TEXT ("u")); { int id = # if defined (ACE_HAS_THREADS) pthread_getselfseq_np (); # else ACE_Thread::self (); # endif /* ACE_HAS_THREADS */ if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, id); else this_len = ACE_OS::sprintf (bp, format, id); } #else ACE_hthread_t t_id; ACE_Thread::self (t_id); # if defined (ACE_MVS) || defined (ACE_TANDEM_T1248_PTHREADS) // MVS's pthread_t is a struct... yuck. So use the ACE 5.0 // code for it. ACE_OS::strcpy (fp, ACE_TEXT ("u")); if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, t_id); else this_len = ACE_OS::sprintf (bp, format, t_id); # else // Yes, this is an ugly C-style cast, but the correct // C++ cast is different depending on whether the t_id // is an integral type or a pointer type. FreeBSD uses // a pointer type, but doesn't have a _np function to // get an integral type, like the OSes above. ACE_OS::strcpy (fp, ACE_TEXT ("lu")); if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, (unsigned long)t_id); else this_len = ACE_OS::sprintf (bp, format, (unsigned long)t_id); # endif /* ACE_MWS || ACE_TANDEM_T1248_PTHREADS */ #endif /* ACE_WIN32 */ ACE_UPDATE_COUNT (bspace, this_len); break; case 's': // String { #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR) wchar_t *str = va_arg (argp, wchar_t *); ACE_OS::strcpy (fp, ACE_TEXT ("ls")); #else /* ACE_WIN32 && ACE_USES_WCHAR */ ACE_TCHAR *str = va_arg (argp, ACE_TCHAR *); ACE_OS::strcpy (fp, ACE_TEXT ("s")); #endif /* ACE_WIN32 && ACE_USES_WCHAR */ if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, str ? str : ACE_TEXT ("(null)")); else this_len = ACE_OS::sprintf (bp, format, str ? str : ACE_TEXT ("(null)")); ACE_UPDATE_COUNT (bspace, this_len); } break; case 'C': // Narrow-char string { char *cstr = va_arg (argp, char *); #if defined (ACE_WIN32) && defined (ACE_USES_WCHAR) ACE_OS::strcpy (fp, ACE_TEXT ("S")); #else /* ACE_WIN32 && ACE_USES_WCHAR */ ACE_OS::strcpy (fp, ACE_TEXT ("s")); #endif /* ACE_WIN32 && ACE_USES_WCHAR */ if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, cstr ? cstr : "(null)"); else this_len = ACE_OS::sprintf (bp, format, cstr ? cstr : "(null)"); ACE_UPDATE_COUNT (bspace, this_len); } break; case 'W': { #if defined (ACE_HAS_WCHAR) wchar_t *wchar_str = va_arg (argp, wchar_t *); # if defined (HPUX) ACE_OS::strcpy (fp, ACE_TEXT ("S")); # elif defined (ACE_WIN32) # if defined (ACE_USES_WCHAR) ACE_OS::strcpy (fp, ACE_TEXT ("s")); # else /* ACE_USES_WCHAR */ ACE_OS::strcpy (fp, ACE_TEXT ("S")); # endif /* ACE_USES_WCHAR */ # else ACE_OS::strcpy (fp, ACE_TEXT ("ls")); # endif /* HPUX */ if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, wchar_str ? wchar_str : ACE_TEXT_WIDE("(null)")); else this_len = ACE_OS::sprintf (bp, format, wchar_str ? wchar_str : ACE_TEXT_WIDE("(null)")); #endif /* ACE_HAS_WCHAR */ ACE_UPDATE_COUNT (bspace, this_len); } break; case 'w': // Wide character #if defined (ACE_WIN32) # if defined (ACE_USES_WCHAR) ACE_OS::strcpy (fp, ACE_TEXT ("c")); # else /* ACE_USES_WCHAR */ ACE_OS::strcpy (fp, ACE_TEXT ("C")); # endif /* ACE_USES_WCHAR */ if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, va_arg (argp, int)); else this_len = ACE_OS::sprintf (bp, format, va_arg (argp, int)); #elif defined (ACE_USES_WCHAR) # if defined (HPUX) ACE_OS::strcpy (fp, ACE_TEXT ("C")); # else ACE_OS::strcpy (fp, ACE_TEXT ("lc")); # endif /* HPUX */ if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, va_arg (argp, wint_t)); else this_len = ACE_OS::sprintf (bp, format, va_arg (argp, wint_t)); #else /* ACE_WIN32 */ ACE_OS::strcpy (fp, ACE_TEXT ("u")); if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, va_arg (argp, int)); else this_len = ACE_OS::sprintf (bp, format, va_arg (argp, int)); #endif /* ACE_WIN32 */ ACE_UPDATE_COUNT (bspace, this_len); break; case 'z': // ACE_OS::WChar character { // On some platforms sizeof (wchar_t) can be 2 // on the others 4 ... wchar_t wtchar = static_cast<wchar_t> (va_arg (argp, int)); #if defined (ACE_WIN32) # if defined (ACE_USES_WCHAR) ACE_OS::strcpy (fp, ACE_TEXT ("c")); # else /* ACE_USES_WCHAR */ ACE_OS::strcpy (fp, ACE_TEXT ("C")); # endif /* ACE_USES_WCHAR */ #elif defined (ACE_USES_WCHAR) # if defined (HPUX) ACE_OS::strcpy (fp, ACE_TEXT ("C")); # else ACE_OS::strcpy (fp, ACE_TEXT ("lc")); # endif /* HPUX */ #else /* ACE_WIN32 */ ACE_OS::strcpy (fp, ACE_TEXT ("u")); #endif /* ACE_WIN32 */ if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, wtchar); else this_len = ACE_OS::sprintf (bp, format, wtchar); ACE_UPDATE_COUNT (bspace, this_len); break; } case 'Z': // ACE_OS::WChar character string { ACE_OS::WChar *wchar_str = va_arg (argp, ACE_OS::WChar*); if (wchar_str == 0) break; wchar_t *wchar_t_str = 0; if (sizeof (ACE_OS::WChar) != sizeof (wchar_t)) { size_t len = ACE_OS::wslen (wchar_str) + 1; ACE_NEW_NORETURN(wchar_t_str, wchar_t[len]); if (wchar_t_str == 0) break; for (size_t i = 0; i < len; ++i) { wchar_t_str[i] = wchar_str[i]; } } if (wchar_t_str == 0) { wchar_t_str = reinterpret_cast<wchar_t*> (wchar_str); } #if defined (ACE_WIN32) # if defined (ACE_USES_WCHAR) ACE_OS::strcpy (fp, ACE_TEXT ("s")); # else /* ACE_USES_WCHAR */ ACE_OS::strcpy (fp, ACE_TEXT ("S")); # endif /* ACE_USES_WCHAR */ #elif defined (ACE_HAS_WCHAR) # if defined (HPUX) ACE_OS::strcpy (fp, ACE_TEXT ("S")); # else ACE_OS::strcpy (fp, ACE_TEXT ("ls")); # endif /* HPUX */ #endif /* ACE_WIN32 / ACE_HAS_WCHAR */ if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, wchar_t_str); else this_len = ACE_OS::sprintf (bp, format, wchar_t_str); if(sizeof(ACE_OS::WChar) != sizeof(wchar_t)) { delete [] wchar_t_str; } ACE_UPDATE_COUNT (bspace, this_len); break; } case 'c': #if defined (ACE_WIN32) && defined (ACE_USES_WCHAR) ACE_OS::strcpy (fp, ACE_TEXT ("C")); #else ACE_OS::strcpy (fp, ACE_TEXT ("c")); #endif /* ACE_WIN32 && ACE_USES_WCHAR */ if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, va_arg (argp, int)); else this_len = ACE_OS::sprintf (bp, format, va_arg (argp, int)); ACE_UPDATE_COUNT (bspace, this_len); break; case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': fp[0] = *format_str; fp[1] = '\0'; if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, va_arg (argp, int)); else this_len = ACE_OS::sprintf (bp, format, va_arg (argp, int)); ACE_UPDATE_COUNT (bspace, this_len); break; case 'F': case 'f': case 'e': case 'E': case 'g': case 'G': fp[0] = *format_str; fp[1] = '\0'; if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, va_arg (argp, double)); else this_len = ACE_OS::sprintf (bp, format, va_arg (argp, double)); ACE_UPDATE_COUNT (bspace, this_len); break; case 'Q': #if defined (ACE_LACKS_LONGLONG_T) || defined (ACE_LACKS_UNSIGNEDLONGLONG_T) { // This relies on the ACE_U_LongLong storage layout. ACE_UINT32 hi = va_arg (argp, ACE_UINT32); ACE_UINT32 lo = va_arg (argp, ACE_UINT32); if (hi > 0) this_len = ACE_OS::sprintf (bp, "0x%lx%0*lx", hi, 2 * sizeof lo, lo); else this_len = ACE_OS::sprintf (bp, "0x%lx", lo); } #else /* ! ACE_LACKS_LONGLONG_T */ { const ACE_TCHAR *fmt = ACE_UINT64_FORMAT_SPECIFIER; ACE_OS::strcpy (fp, &fmt[1]); // Skip leading % if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, va_arg (argp, ACE_UINT64)); else this_len = ACE_OS::sprintf (bp, format, va_arg (argp, ACE_UINT64)); } #endif /* ! ACE_LACKS_LONGLONG_T || ACE_LACKS_UNSIGNEDLONGLONG_T */ ACE_UPDATE_COUNT (bspace, this_len); break; case 'q': #if defined (ACE_LACKS_LONGLONG_T) // No implementation available yet, no ACE_INT64 emulation // available yet #else /* ! ACE_LACKS_LONGLONG_T */ { const ACE_TCHAR *fmt = ACE_INT64_FORMAT_SPECIFIER; ACE_OS::strcpy (fp, &fmt[1]); // Skip leading % if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, va_arg (argp, ACE_INT64)); else this_len = ACE_OS::sprintf (bp, format, va_arg (argp, ACE_INT64)); } #endif /* ! ACE_LACKS_LONGLONG_T */ ACE_UPDATE_COUNT (bspace, this_len); break; case 'b': { const ACE_TCHAR *fmt = ACE_SSIZE_T_FORMAT_SPECIFIER; ACE_OS::strcpy (fp, &fmt[1]); // Skip leading % } if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, va_arg (argp, ssize_t)); else this_len = ACE_OS::sprintf (bp, format, va_arg (argp, ssize_t)); ACE_UPDATE_COUNT (bspace, this_len); break; case 'B': { const ACE_TCHAR *fmt = ACE_SIZE_T_FORMAT_SPECIFIER; ACE_OS::strcpy (fp, &fmt[1]); // Skip leading % } if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, va_arg (argp, size_t)); else this_len = ACE_OS::sprintf (bp, format, va_arg (argp, size_t)); ACE_UPDATE_COUNT (bspace, this_len); break; case ':': { // Assume a 32 bit time_t and change if needed. const ACE_TCHAR *fmt = ACE_TEXT ("%d"); if (sizeof (time_t) == 8) fmt = ACE_INT64_FORMAT_SPECIFIER; ACE_OS::strcpy (fp, &fmt[1]); // Skip leading % } if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, va_arg (argp, time_t)); else this_len = ACE_OS::sprintf (bp, format, va_arg (argp, time_t)); ACE_UPDATE_COUNT (bspace, this_len); break; case '@': ACE_OS::strcpy (fp, ACE_TEXT ("p")); if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, va_arg (argp, void*)); else this_len = ACE_OS::sprintf (bp, format, va_arg (argp, void*)); ACE_UPDATE_COUNT (bspace, this_len); break; case '?': // Stack trace up to this point { // skip the frame that we're currently in ACE_Stack_Trace t(2); ACE_OS::strcpy (fp, ACE_TEXT ("s")); if (can_check) this_len = ACE_OS::snprintf (bp, bspace, format, t.c_str ()); else this_len = ACE_OS::sprintf (bp, format, t.c_str ()); ACE_UPDATE_COUNT (bspace, this_len); break; } default: // So, it's not a legit format specifier after all... // Copy from the original % to where we are now, then // continue with whatever comes next. while (start_format != format_str && bspace > 0) { *bp++ = *start_format++; --bspace; } if (bspace > 0) { *bp++ = *format_str; --bspace; } break; } // Bump to the next char in the caller's format_str ++format_str; } if (!skip_nul_locate) while (*bp != '\0') // Locate end of bp. ++bp; } } *bp = '\0'; // Terminate bp, but don't auto-increment this! ssize_t result = 0; // Check that memory was not corrupted, if it corrupted we can't log anything // anymore because all our members could be corrupted. if (bp >= (this->msg_ + ACE_MAXLOGMSGLEN+1)) { abort_prog = true; ACE_OS::fprintf (stderr, "The following logged message is too long!\n"); } else { // Copy the message from thread-specific storage into the transfer // buffer (this can be optimized away by changing other code...). log_record.msg_data (this->msg ()); // Write the <log_record> to the appropriate location. result = this->log (log_record, abort_prog); } if (abort_prog) { // Since we are now calling abort instead of exit, this value is // not used. ACE_UNUSED_ARG (exit_value); // *Always* print a message to stderr if we're aborting. We // don't use verbose, however, to avoid recursive aborts if // something is hosed. log_record.print (ACE_Log_Msg::local_host_, 0, stderr); ACE_OS::abort (); } return result; }
int ACE_Log_Msg::log_hexdump | ( | ACE_Log_Priority | log_priority, | |
const char * | buffer, | |||
size_t | size, | |||
const ACE_TCHAR * | text = 0 | |||
) |
Method to log hex dump. This is useful for debugging. Calls log() to do the actual print, but formats first to make the chars printable.
Definition at line 2338 of file Log_Msg.cpp.
{ // Only print the message if <priority_mask_> hasn't been reset to // exclude this logging priority. if (this->log_priority_enabled (log_priority) == 0) return 0; ACE_TCHAR* buf = 0; size_t const buf_sz = ACE_Log_Record::MAXLOGMSGLEN - ACE_Log_Record::VERBOSE_LEN - 58; ACE_NEW_RETURN (buf, ACE_TCHAR[buf_sz], -1); ACE_TCHAR *msg_buf = 0; const size_t text_sz = text ? ACE_OS::strlen(text) : 0; ACE_NEW_RETURN (msg_buf, ACE_TCHAR[text_sz + 58], -1); buf[0] = 0; // in case size = 0 size_t const len = ACE::format_hexdump (buffer, size, buf, buf_sz / sizeof (ACE_TCHAR) - text_sz); int sz = 0; if (text) sz = ACE_OS::sprintf (msg_buf, #if !defined (ACE_WIN32) && defined (ACE_USES_WCHAR) ACE_TEXT ("%ls - "), #else ACE_TEXT ("%s - "), #endif text); sz += ACE_OS::sprintf (msg_buf + sz, ACE_TEXT ("HEXDUMP ") ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT (" bytes"), size); if (len < size) ACE_OS::sprintf (msg_buf + sz, ACE_TEXT (" (showing first ") ACE_SIZE_T_FORMAT_SPECIFIER ACE_TEXT (" bytes)"), len); // Now print out the formatted buffer. this->log (log_priority, ACE_TEXT ("%s\n%s"), msg_buf, buf); delete [] msg_buf; delete [] buf; return 0; }
int ACE_Log_Msg::log_priority_enabled | ( | ACE_Log_Priority | log_priority | ) | [inline] |
Return true if the requested priority is enabled.
Definition at line 21 of file Log_Msg.inl.
{ return ACE_BIT_ENABLED (this->priority_mask_ | ACE_Log_Msg::process_priority_mask_, log_priority); }
int ACE_Log_Msg::log_priority_enabled | ( | ACE_Log_Priority | log_priority, | |
const char * | , | |||
... | ||||
) |
Return true if the requested priority is enabled.
Definition at line 2583 of file Log_Msg.cpp.
{ return this->log_priority_enabled (log_priority); }
void ACE_Log_Msg::msg | ( | const ACE_TCHAR * | m | ) | [inline] |
Set the message that describes what type of error occurred.
Definition at line 179 of file Log_Msg.inl.
{ ACE_OS::strsncpy (this->msg_, m, ((ACE_MAXLOGMSGLEN+1) / sizeof (ACE_TCHAR))); }
const ACE_TCHAR * ACE_Log_Msg::msg | ( | void | ) | [inline] |
Get the message that describes what type of error occurred.
Definition at line 172 of file Log_Msg.inl.
{ return this->msg_ + ACE_Log_Msg::msg_off_; }
ACE_Log_Msg_Backend * ACE_Log_Msg::msg_backend | ( | void | ) | [static] |
Definition at line 2526 of file Log_Msg.cpp.
{ ACE_TRACE ("ACE_Log_Msg::msg_backend"); ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *ACE_Log_Msg_Manager::get_lock (), 0)); return ACE_Log_Msg_Manager::custom_backend_; }
ACE_Log_Msg_Backend * ACE_Log_Msg::msg_backend | ( | ACE_Log_Msg_Backend * | b | ) | [static] |
Set a new backend object and return the existing backend to allow "chaining". Note that as opposed to ACE_Log_Msg_Callback, ACE_Log_Msg_Backend is a per-process entity.
Definition at line 2514 of file Log_Msg.cpp.
{ ACE_TRACE ("ACE_Log_Msg::msg_backend"); ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *ACE_Log_Msg_Manager::get_lock (), 0)); ACE_Log_Msg_Backend *tmp = ACE_Log_Msg_Manager::custom_backend_; ACE_Log_Msg_Manager::custom_backend_ = b; return tmp; }
ACE_Log_Msg_Callback * ACE_Log_Msg::msg_callback | ( | ACE_Log_Msg_Callback * | c | ) | [inline] |
Set a new callback object and return the existing callback to allow "chaining". Note that ACE_Log_Msg_Callback objects are not inherited when spawning a new thread, so you'll need to reset them in each thread.
Definition at line 194 of file Log_Msg.inl.
{ ACE_Log_Msg_Callback *old = this->msg_callback_; this->msg_callback_ = c; return old; }
ACE_Log_Msg_Callback * ACE_Log_Msg::msg_callback | ( | void | ) | const [inline] |
Definition at line 187 of file Log_Msg.inl.
{ return this->msg_callback_; }
void ACE_Log_Msg::msg_ostream | ( | ACE_OSTREAM_TYPE * | m, | |
bool | delete_ostream | |||
) |
delete_stream == true, forces Log_Msg.h to delete the stream in its own ~dtor (assumes control of the stream) use only with proper ostream (eg: fstream), not (cout, cerr)
Definition at line 2536 of file Log_Msg.cpp.
{ if (this->ostream_ == m) { // Same stream, allow user to change the delete_ostream "flag" if (delete_ostream && !this->ostream_refcount_) { ACE_NEW (this->ostream_refcount_, Atomic_ULong (1)); } else if (!delete_ostream && this->ostream_refcount_) { if (--*this->ostream_refcount_ == 0) { delete this->ostream_refcount_; } this->ostream_refcount_ = 0; } // The other two cases are no-ops, the user has requested the same // state that's already present. return; } this->cleanup_ostream (); if (delete_ostream) { ACE_NEW (this->ostream_refcount_, Atomic_ULong (1)); } this->ostream_ = m; }
ACE_OSTREAM_TYPE * ACE_Log_Msg::msg_ostream | ( | void | ) | const [inline] |
Get the ostream that is used to print error messages.
Definition at line 203 of file Log_Msg.inl.
{ return this->ostream_; }
void ACE_Log_Msg::msg_ostream | ( | ACE_OSTREAM_TYPE * | m | ) | [inline] |
Update the ostream without overwriting the delete_ostream_ flag.
Definition at line 210 of file Log_Msg.inl.
{ this->ostream_ = m; }
void ACE_Log_Msg::op_status | ( | int | status | ) | [inline] |
Set the result of the operation status (by convention, -1 means error).
Definition at line 30 of file Log_Msg.inl.
{ this->status_ = status; }
int ACE_Log_Msg::op_status | ( | void | ) | const [inline] |
Get the result of the operation status (by convention, -1 means error).
Definition at line 37 of file Log_Msg.inl.
{ return this->status_; }
int ACE_Log_Msg::open | ( | const ACE_TCHAR * | prog_name, | |
u_long | options_flags = ACE_Log_Msg::STDERR , |
|||
const ACE_TCHAR * | logger_key = 0 | |||
) |
Initialize the ACE logging facility.
Initialize the ACE logging facility. Supplies the program name that is available to each logging message call. Default arguments set up logging to STDERR only.
prog_name | The name of the calling program. | |
options_flags | A bitwise-or of options flags used to set the initial behavior and logging sink(s). (see the enum above for the valid values). | |
logger_key | The name of ACE_FIFO rendezvous point where the local client logger daemon is listening for logging messages if the LOGGER bit is set in the flags argument. If the SYSLOG bit is set in flags, logger_key is the source/program name specified in the syslog facility (UNIX/Linux) or the Windows event log (Windows). In the SYSLOG case, if logger_key is 0, prog_name is used. |
Definition at line 768 of file Log_Msg.cpp.
{ ACE_TRACE ("ACE_Log_Msg::open"); ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *ACE_Log_Msg_Manager::get_lock (), -1)); if (prog_name) { ACE_OS::free ((void *) ACE_Log_Msg::program_name_); // Stop heap checking, block will be freed by the destructor. { ACE_NO_HEAP_CHECK; ACE_ALLOCATOR_RETURN (ACE_Log_Msg::program_name_, ACE_OS::strdup (prog_name), -1); } } else if (ACE_Log_Msg::program_name_ == 0) { // Stop heap checking, block will be freed by the destructor. ACE_NO_HEAP_CHECK; ACE_ALLOCATOR_RETURN (ACE_Log_Msg::program_name_, ACE_OS::strdup (ACE_TEXT ("<unknown>")), -1); } int status = 0; // Be sure that there is a message_queue_, with multiple threads. ACE_MT (ACE_Log_Msg_Manager::init_backend (&flags)); // Always close the current handle before doing anything else. if (ACE_Log_Msg_Manager::log_backend_ != 0) ACE_Log_Msg_Manager::log_backend_->reset (); if (ACE_Log_Msg_Manager::custom_backend_ != 0) ACE_Log_Msg_Manager::custom_backend_->reset (); // Note that if we fail to open the message queue the default action // is to use stderr (set via static initialization in the // Log_Msg.cpp file). if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::LOGGER) || ACE_BIT_ENABLED (flags, ACE_Log_Msg::SYSLOG)) { // The SYSLOG backends (both NT and UNIX) can get along fine // without the logger_key - they will default to prog_name if // logger key is 0. if (logger_key == 0 && ACE_BIT_ENABLED (flags, ACE_Log_Msg::LOGGER)) status = -1; else status = ACE_Log_Msg_Manager::log_backend_->open (logger_key); if (status == -1) ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::STDERR); else { if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::LOGGER)) ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER); if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::SYSLOG)) ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG); } } else if (ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER) || ACE_BIT_ENABLED (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG)) { // If we are closing down logger, redirect logging to stderr. ACE_CLR_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::LOGGER); ACE_CLR_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::SYSLOG); ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::STDERR); } if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::CUSTOM)) { status = ACE_Log_Msg_Manager::custom_backend_->open (logger_key); if (status != -1) ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::CUSTOM); } // Remember, ACE_Log_Msg::STDERR bit is on by default... if (status != -1 && ACE_BIT_ENABLED (flags, ACE_Log_Msg::STDERR) == 0) ACE_CLR_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::STDERR); // VERBOSE takes precedence over VERBOSE_LITE... if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::VERBOSE_LITE)) ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::VERBOSE_LITE); else if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::VERBOSE)) ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::VERBOSE); if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::OSTREAM)) { ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::OSTREAM); // Only set this to cerr if it hasn't already been set. if (this->msg_ostream () == 0) this->msg_ostream (ACE_DEFAULT_LOG_STREAM); } if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::MSG_CALLBACK)) ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::MSG_CALLBACK); if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::SILENT)) ACE_SET_BITS (ACE_Log_Msg::flags_, ACE_Log_Msg::SILENT); return status; }
ACE_Log_Msg& ACE_Log_Msg::operator= | ( | const ACE_Log_Msg & | ) | [private] |
u_long ACE_Log_Msg::priority_mask | ( | MASK_TYPE | mask_type = THREAD |
) | [inline] |
Get the current ACE_Log_Priority mask.
Definition at line 12 of file Log_Msg.inl.
{ return mask_type == THREAD ? this->priority_mask_ : ACE_Log_Msg::process_priority_mask_; }
u_long ACE_Log_Msg::priority_mask | ( | u_long | n_mask, | |
MASK_TYPE | mask_type = THREAD | |||
) |
Set the ACE_Log_Priority mask, returns original mask.
Definition at line 611 of file Log_Msg.cpp.
{ u_long o_mask; if (mask_type == THREAD) { o_mask = this->priority_mask_; this->priority_mask_ = n_mask; } else { o_mask = ACE_Log_Msg::process_priority_mask_; ACE_Log_Msg::process_priority_mask_ = n_mask; } return o_mask; }
const ACE_TCHAR * ACE_Log_Msg::program_name | ( | void | ) | [static] |
Returns the current program name used for logging.
Definition at line 434 of file Log_Msg.cpp.
{ return ACE_Log_Msg::program_name_; }
int ACE_Log_Msg::release | ( | void | ) |
Release the internal lock.
Definition at line 630 of file Log_Msg.cpp.
{ ACE_TRACE ("ACE_Log_Msg::release"); #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) return ACE_Log_Msg_Manager::get_lock ()->release (); #else /* ! ACE_MT_SAFE */ return 0; #endif /* ! ACE_MT_SAFE */ }
bool ACE_Log_Msg::restart | ( | void | ) | const [inline] |
Get the field that indicates whether interrupted calls should be restarted.
Definition at line 51 of file Log_Msg.inl.
{ return this->restart_; }
void ACE_Log_Msg::restart | ( | bool | r | ) | [inline] |
Set the field that indicates whether interrupted calls should be restarted.
Definition at line 44 of file Log_Msg.inl.
{ this->restart_ = r; }
void ACE_Log_Msg::set | ( | const char * | file, | |
int | line, | |||
int | op_status = -1 , |
|||
int | errnum = 0 , |
|||
bool | restart = true , |
|||
ACE_OSTREAM_TYPE * | os = 0 , |
|||
ACE_Log_Msg_Callback * | c = 0 | |||
) |
Set the line number, file name, operational status, error number, restart flag, ostream, and the callback object. This combines all the other set methods into a single method.
Definition at line 2400 of file Log_Msg.cpp.
void ACE_Log_Msg::set_flags | ( | u_long | f | ) |
Enable the bits in the logger's options flags.
Definition at line 580 of file Log_Msg.cpp.
{ ACE_TRACE ("ACE_Log_Msg::set_flags"); ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, *ACE_Log_Msg_Manager::get_lock ())); ACE_SET_BITS (ACE_Log_Msg::flags_, flgs); }
void ACE_Log_Msg::start_tracing | ( | void | ) | [inline] |
Start tracing status on a per-thread basis...
Enable the tracing facility on a per-thread basis.
Definition at line 136 of file Log_Msg.inl.
{ this->tracing_enabled_ = true; }
void ACE_Log_Msg::stop_tracing | ( | void | ) | [inline] |
Stop tracing status on a per-thread basis...
Disable the tracing facility on a per-thread basis.
Definition at line 144 of file Log_Msg.inl.
{ this->tracing_enabled_ = false; }
void ACE_Log_Msg::sync | ( | const ACE_TCHAR * | program_name | ) |
Call after doing a fork()
to resynchronize the process id and program_name_
variables.
Definition at line 544 of file Log_Msg.cpp.
{ ACE_TRACE ("ACE_Log_Msg::sync"); if (prog_name) { // Must free if already allocated!!! ACE_OS::free ((void *) ACE_Log_Msg::program_name_); // Stop heap checking, block will be freed by the destructor when // the last ACE_Log_Msg instance is deleted. // Heap checking state will be restored when the block is left. { ACE_NO_HEAP_CHECK; ACE_Log_Msg::program_name_ = ACE_OS::strdup (prog_name); } } ACE_Log_Msg::pid_ = ACE_OS::getpid (); ACE_Log_Msg::msg_off_ = 0; }
void ACE_Log_Msg::sync_hook | ( | const ACE_TCHAR * | prg_name | ) | [static, private] |
Decouple the OS layer from the ACE_Log_Msg layer.
Definition at line 530 of file Log_Msg.cpp.
{ ACE_LOG_MSG->sync (prg_name); }
void ACE_Log_Msg::thr_desc | ( | ACE_Thread_Descriptor * | td | ) |
Set the TSS thread descriptor. This method will call td->acquire_release to block execution until this call return.
Definition at line 2479 of file Log_Msg.cpp.
{ this->thr_desc_ = td; if (td != 0) td->acquire_release (); }
ACE_Thread_Descriptor * ACE_Log_Msg::thr_desc | ( | void | ) | const [inline] |
Get the TSS thread descriptor.
Definition at line 128 of file Log_Msg.inl.
{ return this->thr_desc_; }
ACE_OS_Thread_Descriptor * ACE_Log_Msg::thr_desc_hook | ( | void | ) | [static, private] |
Return the TSS singleton thread descriptor.
Definition at line 536 of file Log_Msg.cpp.
{ return ACE_LOG_MSG->thr_desc (); }
bool ACE_Log_Msg::trace_active | ( | void | ) | const [inline] |
Get trace active status.
Definition at line 114 of file Log_Msg.inl.
{ return this->trace_active_; }
void ACE_Log_Msg::trace_active | ( | bool | value | ) | [inline] |
Set trace active status.
Definition at line 121 of file Log_Msg.inl.
{ this->trace_active_ = value; }
void ACE_Log_Msg::trace_depth | ( | int | depth | ) | [inline] |
int ACE_Log_Msg::trace_depth | ( | void | ) | const [inline] |
bool ACE_Log_Msg::tracing_enabled | ( | void | ) | const [inline] |
Query tracing status on a per-thread basis...
Definition at line 151 of file Log_Msg.inl.
{ return this->tracing_enabled_; }
struct { ... } ACE_Log_Msg::conditional_values_ [private] |
Anonymous struct since there will only be one instance. This struct keeps information stored away in case we actually end up calling log() if the log priority is correct.
u_long ACE_Log_Msg::default_priority_mask_ = 0 [static, private] |
int ACE_Log_Msg::errnum_ [private] |
char ACE_Log_Msg::file_[MAXPATHLEN+1] [private] |
const char* ACE_Log_Msg::file_ |
u_long ACE_Log_Msg::flags_ = ACE_Log_Msg::STDERR [static, private] |
int ACE_Log_Msg::instance_count_ = 0 [static, private] |
Number of existing ACE_Log_Msg instances; when 0, delete program/host names
Instance count for Log_Msg - used to know when dynamically allocated storage (program name and host name) can be safely deleted.
bool ACE_Log_Msg::is_set_ |
int ACE_Log_Msg::linenum_ [private] |
const ACE_TCHAR * ACE_Log_Msg::local_host_ = 0 [static, private] |
ACE_TCHAR* ACE_Log_Msg::msg_ [private] |
ACE_Log_Msg_Callback* ACE_Log_Msg::msg_callback_ [private] |
ptrdiff_t ACE_Log_Msg::msg_off_ = 0 [static, private] |
ACE_OSTREAM_TYPE* ACE_Log_Msg::ostream_ [private] |
Atomic_ULong* ACE_Log_Msg::ostream_refcount_ [private] |
pid_t ACE_Log_Msg::pid_ = -2 [static, private] |
u_long ACE_Log_Msg::priority_mask_ [private] |
u_long ACE_Log_Msg::process_priority_mask_ [static, private] |
LM_SHUTDOWN | LM_TRACE | LM_DEBUG | LM_INFO | LM_NOTICE | LM_WARNING | LM_STARTUP | LM_ERROR | LM_CRITICAL | LM_ALERT | LM_EMERGENCY
Keeps track of all the per-process ACE_Log_Priority values that are currently enabled. Default is for all logging priorities to be enabled.
Default per-process priority mask By default, all priorities are enabled.
const ACE_TCHAR * ACE_Log_Msg::program_name_ = 0 [static, private] |
bool ACE_Log_Msg::restart_ [private] |
int ACE_Log_Msg::status_ [private] |
ACE_Thread_Descriptor* ACE_Log_Msg::thr_desc_ [private] |
If we're running in the context of an ACE_Thread_Manager this will point to the thread descriptor adapter which holds the thread descriptor of the thread. This can be used to repidly access all thread data kept in ACE_Thread_Descriptor.
int ACE_Log_Msg::timestamp_ [private] |
bool ACE_Log_Msg::trace_active_ [private] |
int ACE_Log_Msg::trace_depth_ [private] |
bool ACE_Log_Msg::tracing_enabled_ [private] |