UdpLogOutput.cpp
Go to the documentation of this file.
00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
00002 
00003 // -- BEGIN LICENSE BLOCK ----------------------------------------------
00004 // This file is part of FZIs ic_workspace.
00005 //
00006 // This program is free software licensed under the LGPL
00007 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
00008 // You can find a copy of this license in LICENSE folder in the top
00009 // directory of the source code.
00010 //
00011 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
00012 //
00013 // -- END LICENSE BLOCK ------------------------------------------------
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   // Get the server configuration.
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   // Open the UDP socket.
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   // TODO: Which characters have to be escaped to ensure that a
00126   // correct SQL statement is created?
00127   str = boost::regex_replace(str, boost::regex("'"), "\\'");
00128   //str = boost::regex_replace(str, boost::regex("\\n"), "\\\\n");
00129   return str;
00130 }
00131 
00132 }
00133 }


fzi_icl_core
Author(s):
autogenerated on Thu Jun 6 2019 20:22:24