]> git.sesse.net Git - casparcg/commitdiff
Implemented a TCP server, simply sending every log line to the remote client. If...
authorHelge Norberg <helge.norberg@svt.se>
Fri, 13 Nov 2015 15:39:54 +0000 (16:39 +0100)
committerHelge Norberg <helge.norberg@svt.se>
Fri, 13 Nov 2015 15:39:54 +0000 (16:39 +0100)
common/log.cpp
common/log.h
protocol/CMakeLists.txt
protocol/log/tcp_logger_protocol_strategy.cpp [new file with mode: 0644]
protocol/log/tcp_logger_protocol_strategy.h [new file with mode: 0644]
shell/casparcg.config
shell/server.cpp

index 82211663c2e07d82ca1a7e87c818a992f2c37b20..3b857caa5c0ae38d87380f78fe2f0de3fb8d0a68 100644 (file)
@@ -181,6 +181,45 @@ void add_file_sink(const std::wstring& folder)
        }
 }
 
+std::shared_ptr<void> add_preformatted_line_sink(std::function<void(std::string line)> formatted_line_sink)
+{
+       class sink_backend : public boost::log::sinks::basic_formatted_sink_backend<char>
+       {
+               std::function<void(std::string line)> formatted_line_sink_;
+       public:
+               sink_backend(std::function<void(std::string line)> formatted_line_sink)
+                       : formatted_line_sink_(std::move(formatted_line_sink))
+               {
+               }
+
+               void consume(const boost::log::record_view& rec, const std::string& formatted_message)
+               {
+                       try
+                       {
+                               formatted_line_sink_(formatted_message);
+                       }
+                       catch (...)
+                       {
+                               std::cerr << "[sink_backend] Error while consuming formatted message: " << formatted_message << std::endl << std::endl;
+                       }
+               }
+       };
+
+       typedef boost::log::sinks::synchronous_sink<sink_backend> sink_type;
+
+       auto sink = boost::make_shared<sink_type>(std::move(formatted_line_sink));
+       bool print_all_characters = true;
+
+       sink->set_formatter(boost::bind(&my_formatter<boost::log::formatting_ostream>, print_all_characters, _1, _2));
+
+       boost::log::core::get()->add_sink(sink);
+
+       return std::shared_ptr<void>(nullptr, [=](void*)
+       {
+               boost::log::core::get()->remove_sink(sink);
+       });
+}
+
 void set_log_level(const std::wstring& lvl)
 {
        if (boost::iequals(lvl, L"trace"))
index 441837116dff836e5ef37be480059117344bc960..2704e3823b6efc38b71007671ab4004c57ce186a 100644 (file)
@@ -32,6 +32,8 @@
 
 #include <string>
 #include <locale>
+#include <functional>
+#include <memory>
 
 namespace caspar { namespace log {
        
@@ -61,6 +63,7 @@ inline std::basic_string<T> replace_nonprintable_copy(std::basic_string<T, std::
 }
 
 void add_file_sink(const std::wstring& folder);
+std::shared_ptr<void> add_preformatted_line_sink(std::function<void(std::string line)> formatted_line_sink);
 
 typedef boost::log::sources::wseverity_logger_mt<boost::log::trivial::severity_level> caspar_logger;
 
index 9aa96d00d9c00dbc4ce52a9674ee8296abffd300..fc1e0a1960595de94a68c5c20a13a7d02b924328 100644 (file)
@@ -14,6 +14,8 @@ set(SOURCES
                clk/clk_commands.cpp
                clk/clk_command_processor.cpp
 
+               log/tcp_logger_protocol_strategy.cpp
+
                osc/oscpack/OscOutboundPacketStream.cpp
                osc/oscpack/OscPrintReceivedElements.cpp
                osc/oscpack/OscReceivedElements.cpp
@@ -43,6 +45,8 @@ set(HEADERS
                clk/clk_commands.h
                clk/clk_command_processor.h
 
+               log/tcp_logger_protocol_strategy.h
+
                osc/oscpack/MessageMappingOscPacketListener.h
                osc/oscpack/OscException.h
                osc/oscpack/OscHostEndianness.h
@@ -75,6 +79,7 @@ include_directories(${TBB_INCLUDE_PATH})
 source_group(sources\\amcp amcp/*)
 source_group(sources\\cii cii/*)
 source_group(sources\\clk clk/*)
+source_group(sources\\log log/*)
 source_group(sources\\osc\\oscpack osc/oscpack/*)
 source_group(sources\\osc osc/*)
 source_group(sources\\util util/*)
diff --git a/protocol/log/tcp_logger_protocol_strategy.cpp b/protocol/log/tcp_logger_protocol_strategy.cpp
new file mode 100644 (file)
index 0000000..1539062
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
+*
+* This file is part of CasparCG (www.casparcg.com).
+*
+* CasparCG is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* CasparCG is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
+*
+* Author: Helge Norberg, helge.norberg@svt.se
+*/
+
+#include "../StdAfx.h"
+
+#include "tcp_logger_protocol_strategy.h"
+
+#include <common/log.h>
+
+namespace caspar { namespace protocol { namespace log {
+
+class tcp_logger_protocol_strategy : public IO::protocol_strategy<char>
+{
+       spl::shared_ptr<IO::client_connection<char>>    client_connection_;
+       std::shared_ptr<void>                                                   log_sink_                       = caspar::log::add_preformatted_line_sink([=](std::string line)
+                                                                                                                                                               {
+                                                                                                                                                                       handle_log_line(std::move(line));
+                                                                                                                                                               });
+public:
+       tcp_logger_protocol_strategy(spl::shared_ptr<IO::client_connection<char>> client_connection)
+               : client_connection_(std::move(client_connection))
+       {
+       }
+
+       void handle_log_line(std::string line)
+       {
+               line += "\r\n";
+               client_connection_->send(std::move(line));
+       }
+
+       void parse(const std::string& data) override
+       {
+       }
+};
+
+spl::shared_ptr<IO::protocol_strategy<char>> tcp_logger_protocol_strategy_factory::create(
+               const spl::shared_ptr<IO::client_connection<char>>& client_connection)
+{
+       return spl::make_shared<tcp_logger_protocol_strategy>(client_connection);
+}
+
+}}}
diff --git a/protocol/log/tcp_logger_protocol_strategy.h b/protocol/log/tcp_logger_protocol_strategy.h
new file mode 100644 (file)
index 0000000..d6e2fc3
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
+*
+* This file is part of CasparCG (www.casparcg.com).
+*
+* CasparCG is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* CasparCG is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
+*
+* Author: Helge Norberg, helge.norberg@svt.se
+*/
+
+#pragma once
+
+#include "../util/protocol_strategy.h"
+
+namespace caspar { namespace protocol { namespace log {
+
+struct tcp_logger_protocol_strategy_factory : public IO::protocol_strategy_factory<char>
+{
+       spl::shared_ptr<IO::protocol_strategy<char>> create(
+                       const spl::shared_ptr<IO::client_connection<char>>& client_connection) override;
+};
+
+}}}
index c69af225a5ed81abaa88d914fccec29de441333e..3691c67cfec6121c686585a5c5a48d690ba59123 100644 (file)
       <port>5250</port>\r
       <protocol>AMCP</protocol>\r
     </tcp>\r
+    <tcp>\r
+      <port>3250</port>\r
+      <protocol>LOG</protocol>\r
+    </tcp>\r
   </controllers>\r
 </configuration>\r
 \r
index 53814d14283f08018a383df318653043e04c9ec9..1645d2d2c61ee1d58fceeaeedb7e0b296226d909 100644 (file)
@@ -65,6 +65,7 @@
 #include <protocol/util/AsyncEventServer.h>
 #include <protocol/util/strategy_adapters.h>
 #include <protocol/osc/client.h>
+#include <protocol/log/tcp_logger_protocol_strategy.h>
 
 #include <boost/algorithm/string.hpp>
 #include <boost/thread.hpp>
@@ -411,7 +412,9 @@ struct server::impl : boost::noncopyable
                        return spl::make_shared<to_unicode_adapter_factory>(
                                        "ISO-8859-1",
                                        spl::make_shared<CLK::clk_protocol_strategy_factory>(channels_, cg_registry_, producer_registry_));
-               
+               else if (boost::iequals(name, L"LOG"))
+                       return spl::make_shared<protocol::log::tcp_logger_protocol_strategy_factory>();
+
                CASPAR_THROW_EXCEPTION(caspar_exception() << arg_name_info(L"name") << arg_value_info(name) << msg_info(L"Invalid protocol"));
        }