#include "ace/config-all.h" #if !defined (ACE_LACKS_UNIX_SYSLOG) #include "ace/ACE.h" #include "ace/Log_Category.h" #include "ace/Log_Msg_UNIX_Syslog.h" #include "ace/Log_Record.h" #include "ace/OS_NS_string.h" #include "ace/os_include/os_syslog.h" ACE_BEGIN_VERSIONED_NAMESPACE_DECL // NOTE: // The ACE_Log_Msg_UNIX_Syslog class can use the openlog(), // setlogmask(), syslog() and closelog() routines in a thread safe // manner (versus using openlog_r(), et. al.), as the ACE_Log_Msg // class uses the lock provided by its local ACE_Log_Msg_Manager // class when calling the methods of the backend classes. As a // result, logging semantics with respect to the UNIX syslog // facility, will be the same for all threads in a process. This // should not be too limiting, as the ACE_Log_Msg class itself can // be used to control thread specific logging behavior. ACE_Log_Msg_UNIX_Syslog::ACE_Log_Msg_UNIX_Syslog () { } ACE_Log_Msg_UNIX_Syslog::~ACE_Log_Msg_UNIX_Syslog () { (void) this->close (); } int ACE_Log_Msg_UNIX_Syslog::open (const ACE_TCHAR * logger_key) { if (logger_key == 0) logger_key = ACE_Log_Msg::program_name (); // Initialize the UNIX syslog facility. Default the syslog log // options LOG_CONS and LOG_PID to be set. There really should be a // logging strategy option to control the syslog log options, // however, we'll take the easy way out for now. #if defined (ACE_LACKS_OPENLOG) ACE_UNUSED_ARG (logger_key); ACE_NOTSUP_RETURN (-1); #else # if defined (ACE_USES_WCHAR) openlog (ACE_TEXT_ALWAYS_CHAR (logger_key), LOG_CONS|LOG_PID, ACE_DEFAULT_SYSLOG_FACILITY); # else openlog (const_cast (logger_key), LOG_CONS|LOG_PID, ACE_DEFAULT_SYSLOG_FACILITY); # endif /* ACE_USES_WCHAR */ #endif /* ACE_LACKS_OPENLOG */ // Enable logging of all syslog priorities. If logging of all // priorities is not desired, use the ACE_Log_Msg::priority_mask() // method to control the log output sent to the syslog daemon via // the log() method, or use the system's syslog.conf file to select // desired level of information. #if !defined (ACE_LACKS_SETLOGMASK) (void) setlogmask (LOG_UPTO (LOG_DEBUG)); #endif /* ACE_LACKS_SETLOGMASK */ return 0; } int ACE_Log_Msg_UNIX_Syslog::reset () { return this->close (); } int ACE_Log_Msg_UNIX_Syslog::close () { closelog(); return 0; } ssize_t ACE_Log_Msg_UNIX_Syslog::log (ACE_Log_Record &log_record) { int syslog_priority = this->convert_log_priority (log_record.type ()); u_long flags = ACE_LOG_MSG->flags (); // The UNIX syslog() facility does not support multi-line messages. // Break up the message data into separate lines and send each line // to the syslog daemon. ACE_TCHAR message[ACE_Log_Record::MAXVERBOSELOGMSGLEN]; ACE_OS::strcpy (message, log_record.msg_data ()); ACE_TCHAR *strtokp = 0; for (ACE_TCHAR *line = ACE_OS::strtok_r (message, ACE_TEXT ("\n"), &strtokp); line != 0; line = ACE_OS::strtok_r (0, ACE_TEXT ("\n"), &strtokp)) { // Format the message line. Note that the processing for // VERBOSE is the same as for VERBOSE_LITE, since syslog() // already provides us with the hostname and PID. However, the // timestamp is duplicated (albeit a shortened version) to // provide a timestamp with greater precision than that provided // by syslog(). if (ACE_BIT_ENABLED (flags, ACE_Log_Msg::VERBOSE) || ACE_BIT_ENABLED (flags, ACE_Log_Msg::VERBOSE_LITE)) { ACE_TCHAR date_and_time[27]; if (0 == ACE::timestamp (date_and_time, sizeof (date_and_time), 1)) ACE_OS::strcpy (date_and_time, ACE_TEXT ("