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