From ce550adf5449c874f3ec1211d65269274918def8 Mon Sep 17 00:00:00 2001 From: Helge Norberg Date: Wed, 16 Dec 2015 20:56:19 +0100 Subject: [PATCH] Made calltracing configurable --- common/enum_class.h | 107 +++++++++++++++-------------- common/log.cpp | 75 ++++++++++++++++++-- common/log.h | 11 +-- modules/psd/misc.h | 8 +-- protocol/amcp/AMCPCommandsImpl.cpp | 18 +++++ shell/casparcg.config | 1 + shell/main.cpp | 12 +++- 7 files changed, 164 insertions(+), 68 deletions(-) diff --git a/common/enum_class.h b/common/enum_class.h index c1cec94d5..54336823b 100644 --- a/common/enum_class.h +++ b/common/enum_class.h @@ -1,63 +1,68 @@ -#pragma once - -#include - -#include - -#include "linq.h" - -// Macro that defines & and &= for an enum class. Add more when needed. - -#define ENUM_ENABLE_BITWISE(enum_class) \ - static enum_class operator&(enum_class lhs, enum_class rhs) \ - { \ - return static_cast( \ - static_cast::type>(lhs) \ - & static_cast::type>(rhs)); \ - }; \ - static enum_class& operator&=(enum_class& lhs, enum_class rhs) \ - { \ - lhs = lhs & rhs; \ - return lhs; \ - }; \ +#pragma once + +#include + +#include + +#include "linq.h" + +// Macro that defines & and &= for an enum class. Add more when needed. + +#define ENUM_ENABLE_BITWISE(enum_class) \ + static enum_class operator&(enum_class lhs, enum_class rhs) \ + { \ + return static_cast( \ + static_cast::type>(lhs) \ + & static_cast::type>(rhs)); \ + }; \ + static enum_class& operator&=(enum_class& lhs, enum_class rhs) \ + { \ + lhs = lhs & rhs; \ + return lhs; \ + }; \ static enum_class operator | (enum_class lhs, enum_class rhs) \ { \ return static_cast( \ static_cast::type>(lhs) \ | static_cast::type>(rhs)); \ }; \ - static enum_class& operator|=(enum_class& lhs, enum_class rhs) \ - { \ - lhs = lhs | rhs; \ - return lhs; \ - }; \ + static enum_class& operator|=(enum_class& lhs, enum_class rhs) \ + { \ + lhs = lhs | rhs; \ + return lhs; \ + }; \ static enum_class operator ^ (enum_class lhs, enum_class rhs) \ { \ return static_cast( \ static_cast::type>(lhs) \ ^ static_cast::type>(rhs)); \ }; \ - static enum_class& operator^=(enum_class& lhs, enum_class rhs) \ - { \ - lhs = lhs ^ rhs; \ - return lhs; \ - }; - -namespace caspar { - -// For enum classes starting at 0 and without any gaps with a terminating count constant. -template -const std::vector& enum_constants() -{ - typedef typename std::underlying_type::type integer; - - static const auto ints = boost::irange(static_cast(0), static_cast(E::count)); - static const auto result = cpplinq::from(ints.begin(), ints.end()) - //.cast() - .select([](int i) { return static_cast(i); }) - .to_vector(); - - return result; -} - -} + static enum_class& operator^=(enum_class& lhs, enum_class rhs) \ + { \ + lhs = lhs ^ rhs; \ + return lhs; \ + }; \ + static enum_class operator~ (enum_class e) \ + { \ + return static_cast( \ + ~static_cast::type>(e)); \ + }; + +namespace caspar { + +// For enum classes starting at 0 and without any gaps with a terminating count constant. +template +const std::vector& enum_constants() +{ + typedef typename std::underlying_type::type integer; + + static const auto ints = boost::irange(static_cast(0), static_cast(E::count)); + static const auto result = cpplinq::from(ints.begin(), ints.end()) + //.cast() + .select([](int i) { return static_cast(i); }) + .to_vector(); + + return result; +} + +} diff --git a/common/log.cpp b/common/log.cpp index 78957b60a..31a345776 100644 --- a/common/log.cpp +++ b/common/log.cpp @@ -55,6 +55,7 @@ #include #include #include +#include #include @@ -152,7 +153,7 @@ void init() auto stream_sink = boost::make_shared(stream_backend); // Never log calltrace to console. The terminal is too slow, so the log queue will build up faster than consumed. - stream_sink->set_filter(category != log_category::call); + stream_sink->set_filter(category != log_category::calltrace); bool print_all_characters = false; stream_sink->set_formatter(boost::bind(&my_formatter, print_all_characters, _1, _2)); @@ -220,6 +221,7 @@ std::shared_ptr add_preformatted_line_sink(std::functionset_formatter(boost::bind(&my_formatter, print_all_characters, _1, _2)); + sink->set_filter(category != log_category::calltrace); boost::log::core::get()->add_sink(sink); @@ -229,20 +231,79 @@ std::shared_ptr add_preformatted_line_sink(std::function= get_level(); + auto disabled_categories = get_disabled_categories(); + + boost::log::core::get()->set_filter([=](const boost::log::attribute_value_set& attributes) + { + return severity_filter(attributes) + && static_cast(disabled_categories & attributes["Channel"].extract().get()) == 0; + }); +} + void set_log_level(const std::wstring& lvl) { + boost::lock_guard lock(get_filter_mutex()); + if (boost::iequals(lvl, L"trace")) - boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::trace); + get_level() = boost::log::trivial::trace; else if (boost::iequals(lvl, L"debug")) - boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::debug); + get_level() = boost::log::trivial::debug; else if (boost::iequals(lvl, L"info")) - boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::info); + get_level() = boost::log::trivial::info; else if (boost::iequals(lvl, L"warning")) - boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::warning); + get_level() = boost::log::trivial::warning; else if (boost::iequals(lvl, L"error")) - boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::error); + get_level() = boost::log::trivial::error; else if (boost::iequals(lvl, L"fatal")) - boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::fatal); + get_level() = boost::log::trivial::fatal; + + set_log_filter(); +} + +void set_log_category(const std::wstring& cat, bool enabled) +{ + log_category category_to_set; + + if (boost::iequals(cat, L"calltrace")) + category_to_set = log_category::calltrace; + else if (boost::iequals(cat, L"communication")) + category_to_set = log_category::communication; + else + return; // Ignore + + boost::lock_guard lock(get_filter_mutex()); + auto& disabled_categories = get_disabled_categories(); + + if (enabled) + disabled_categories &= ~category_to_set; + else + disabled_categories |= category_to_set; + + set_log_filter(); } void print_child( diff --git a/common/log.h b/common/log.h index a4415c60f..4cc983e45 100644 --- a/common/log.h +++ b/common/log.h @@ -24,6 +24,7 @@ #include "os/stack_trace.h" #include "utf.h" #include "thread_info.h" +#include "enum_class.h" #include #include @@ -69,10 +70,11 @@ std::shared_ptr add_preformatted_line_sink(std::function caspar_logger; @@ -88,7 +90,7 @@ BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(logger, caspar_logger) #define CASPAR_LOG(lvl)\ BOOST_LOG_CHANNEL_SEV(::caspar::log::logger::get(), ::caspar::log::log_category::normal, ::boost::log::trivial::lvl) #define CASPAR_LOG_CALL(lvl)\ - BOOST_LOG_CHANNEL_SEV(::caspar::log::logger::get(), ::caspar::log::log_category::call, ::boost::log::trivial::lvl) + BOOST_LOG_CHANNEL_SEV(::caspar::log::logger::get(), ::caspar::log::log_category::calltrace, ::boost::log::trivial::lvl) #define CASPAR_LOG_COMMUNICATION(lvl)\ BOOST_LOG_CHANNEL_SEV(::caspar::log::logger::get(), ::caspar::log::log_category::communication, ::boost::log::trivial::lvl) @@ -108,6 +110,7 @@ BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(logger, caspar_logger) catch(...){} void set_log_level(const std::wstring& lvl); +void set_log_category(const std::wstring& cat, bool enabled); void print_child( boost::log::trivial::severity_level level, diff --git a/modules/psd/misc.h b/modules/psd/misc.h index 840b365b9..3cf07ec9a 100644 --- a/modules/psd/misc.h +++ b/modules/psd/misc.h @@ -129,15 +129,15 @@ enum class layer_tag : int { moveable = 4, resizable = 8, rasterized = 16, - cornerpin = 32, - all = 63 + cornerpin = 32//, + //all = 63 }; ENUM_ENABLE_BITWISE(layer_tag); -inline layer_tag operator ~ (layer_tag rhs) +/*inline layer_tag operator ~ (layer_tag rhs) { return (layer_tag)(static_cast(layer_tag::all) ^ static_cast(rhs)); -} +}*/ layer_tag string_to_layer_tags(const std::wstring& str); diff --git a/protocol/amcp/AMCPCommandsImpl.cpp b/protocol/amcp/AMCPCommandsImpl.cpp index 2a377d225..9297e03f0 100644 --- a/protocol/amcp/AMCPCommandsImpl.cpp +++ b/protocol/amcp/AMCPCommandsImpl.cpp @@ -704,6 +704,23 @@ std::wstring log_level_command(command_context& ctx) return L"202 LOG OK\r\n"; } +void log_category_describer(core::help_sink& sink, const core::help_repository& repo) +{ + sink.short_description(L"Enable/disable a logging category in the server."); + sink.syntax(L"LOG CATEGORY [category:calltrace,communication] [enable:0,1]"); + sink.para()->text(L"Enables or disables the specified logging category."); + sink.para()->text(L"Examples:"); + sink.example(L">> LOG CATEGORY calltrace 1", L"to enable call trace"); + sink.example(L">> LOG CATEGORY calltrace 0", L"to disable call trace"); +} + +std::wstring log_category_command(command_context& ctx) +{ + log::set_log_category(ctx.parameters.at(0), ctx.parameters.at(1) == L"1"); + + return L"202 LOG OK\r\n"; +} + void set_describer(core::help_sink& sink, const core::help_repository& repo) { sink.short_description(L"Change the value of a channel variable."); @@ -2856,6 +2873,7 @@ void register_commands(amcp_command_repository& repo) repo.register_channel_command( L"Basic Commands", L"REMOVE", remove_describer, remove_command, 0); repo.register_channel_command( L"Basic Commands", L"PRINT", print_describer, print_command, 0); repo.register_command( L"Basic Commands", L"LOG LEVEL", log_level_describer, log_level_command, 1); + repo.register_command( L"Basic Commands", L"LOG CATEGORY", log_category_describer, log_category_command, 2); repo.register_channel_command( L"Basic Commands", L"SET", set_describer, set_command, 2); repo.register_command( L"Basic Commands", L"LOCK", lock_describer, lock_command, 2); diff --git a/shell/casparcg.config b/shell/casparcg.config index 231954018..076e4b0fa 100644 --- a/shell/casparcg.config +++ b/shell/casparcg.config @@ -36,6 +36,7 @@