Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00022
00023 #include "icl_core_logging/UdpLogOutput.h"
00024
00025 #include <netdb.h>
00026 #include <boost/regex.hpp>
00027 #include <sys/types.h>
00028 #include <sys/socket.h>
00029
00030 #include "icl_core/StringHelper.h"
00031 #include "icl_core_config/Config.h"
00032 #include "icl_core_logging/Logging.h"
00033
00034 namespace icl_core {
00035 namespace logging {
00036
00037 REGISTER_LOG_OUTPUT_STREAM(UDP, &UdpLogOutput::create)
00038
00039 LogOutputStream *UdpLogOutput::create(const icl_core::String& name, const icl_core::String& config_prefix,
00040 icl_core::logging::LogLevel log_level)
00041 {
00042 return new UdpLogOutput(name, config_prefix, log_level);
00043 }
00044
00045 UdpLogOutput::UdpLogOutput(const icl_core::String& name, const icl_core::String& config_prefix,
00046 icl_core::logging::LogLevel log_level)
00047 : LogOutputStream(name, config_prefix, log_level),
00048 m_socket(-1)
00049 {
00050
00051 icl_core::String server_host;
00052 if (!icl_core::config::get<icl_core::String>(config_prefix + "/Host", server_host))
00053 {
00054 std::cerr << "No Host specified for UDP log output stream " << config_prefix << std::endl;
00055 }
00056
00057 icl_core::String server_port =
00058 icl_core::config::getDefault<icl_core::String>(config_prefix + "/Port", "60000");
00059
00060 if (!icl_core::config::get<icl_core::String>(config_prefix + "/SystemName", m_system_name))
00061 {
00062 std::cerr << "No SystemName specified for UDP log output stream " << config_prefix << std::endl;
00063 }
00064
00065
00066 struct addrinfo hints;
00067 memset (&hints, 0, sizeof(hints));
00068 hints.ai_family = AF_INET;
00069 hints.ai_socktype = SOCK_DGRAM;
00070
00071 struct addrinfo *res = 0, *res0 = 0;
00072 int n = getaddrinfo(server_host.c_str (), server_port.c_str (), &hints, &res0);
00073 if (n == 0)
00074 {
00075 for (res = res0; res != NULL && m_socket < 0; res = res->ai_next)
00076 {
00077 m_socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
00078 if (m_socket >= 0)
00079 {
00080 if (connect(m_socket, res->ai_addr, res->ai_addrlen) < 0)
00081 {
00082 close(m_socket);
00083 m_socket = -1;
00084 }
00085 }
00086 }
00087
00088 freeaddrinfo(res0);
00089 }
00090 }
00091
00092 UdpLogOutput::~UdpLogOutput()
00093 {
00094 if (m_socket >= 0)
00095 {
00096 close(m_socket);
00097 }
00098 }
00099
00100 void UdpLogOutput::pushImpl(const LogMessage& log_message)
00101 {
00102 if (m_socket >= 0)
00103 {
00104 std::stringstream ss;
00105 ss << "'" << m_system_name << "',"
00106 << "'" << log_message.timestamp.formatIso8601() << "'," << log_message.timestamp.tsNSec() << ","
00107 << "'" << logLevelDescription(log_message.log_level) << "',"
00108 << "'" << log_message.log_stream << "',"
00109 << "'" << log_message.filename << "'," << log_message.line << ","
00110 << "'" << log_message.class_name << "',"
00111 << "'" << escape(log_message.object_name) << "',"
00112 << "'" << log_message.function_name << "',"
00113 << "'" << escape(log_message.message_text) << "'";
00114 std::string str = ss.str();
00115 int res = write(m_socket, str.c_str(), str.length());
00116 if (res < 0)
00117 {
00118 perror("UdpLogOutput::pushImpl()");
00119 }
00120 }
00121 }
00122
00123 icl_core::String UdpLogOutput::escape(icl_core::String str) const
00124 {
00125
00126
00127 str = boost::regex_replace(str, boost::regex("'"), "\\'");
00128
00129 return str;
00130 }
00131
00132 }
00133 }