extension_app_launcher.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Copyright Andrey Semashev 2007 - 2015.
  3. * Distributed under the Boost Software License, Version 1.0.
  4. * (See accompanying file LICENSE_1_0.txt or copy at
  5. * http://www.boost.org/LICENSE_1_0.txt)
  6. */
  7. #include <cstdlib>
  8. #include <string>
  9. #include <utility>
  10. #include <stdexcept>
  11. #include <boost/smart_ptr/shared_ptr.hpp>
  12. #include <boost/phoenix.hpp>
  13. #include <boost/log/trivial.hpp>
  14. #include <boost/log/core.hpp>
  15. #include <boost/log/expressions.hpp>
  16. #include <boost/log/attributes/current_process_name.hpp>
  17. #include <boost/log/sinks/sync_frontend.hpp>
  18. #include <boost/log/sinks/basic_sink_backend.hpp>
  19. #include <boost/log/sources/record_ostream.hpp>
  20. #include <boost/log/utility/value_ref.hpp>
  21. #include <boost/log/utility/formatting_ostream.hpp>
  22. #include <boost/log/utility/manipulators/add_value.hpp>
  23. namespace logging = boost::log;
  24. namespace attrs = boost::log::attributes;
  25. namespace src = boost::log::sources;
  26. namespace expr = boost::log::expressions;
  27. namespace sinks = boost::log::sinks;
  28. namespace keywords = boost::log::keywords;
  29. //[ example_extension_app_launcher_definition
  30. // The backend starts an external application to display notifications
  31. class app_launcher :
  32. public sinks::basic_formatted_sink_backend<
  33. char, /*< target character type >*/
  34. sinks::synchronized_feeding /*< in order not to spawn too many application instances we require records to be processed serial >*/
  35. >
  36. {
  37. public:
  38. // The function consumes the log records that come from the frontend
  39. void consume(logging::record_view const& rec, string_type const& command_line);
  40. };
  41. //]
  42. //[ example_extension_app_launcher_consume
  43. // The function consumes the log records that come from the frontend
  44. void app_launcher::consume(logging::record_view const& rec, string_type const& command_line)
  45. {
  46. std::system(command_line.c_str());
  47. }
  48. //]
  49. //[ example_extension_app_launcher_formatting
  50. BOOST_LOG_ATTRIBUTE_KEYWORD(process_name, "ProcessName", std::string)
  51. BOOST_LOG_ATTRIBUTE_KEYWORD(caption, "Caption", std::string)
  52. // Custom severity level formatting function
  53. std::string severity_level_as_urgency(
  54. logging::value_ref< logging::trivial::severity_level, logging::trivial::tag::severity > const& level)
  55. {
  56. if (!level || level.get() == logging::trivial::info)
  57. return "normal";
  58. logging::trivial::severity_level lvl = level.get();
  59. if (lvl < logging::trivial::info)
  60. return "low";
  61. else
  62. return "critical";
  63. }
  64. // The function initializes the logging library
  65. void init_logging()
  66. {
  67. boost::shared_ptr< logging::core > core = logging::core::get();
  68. typedef sinks::synchronous_sink< app_launcher > sink_t;
  69. boost::shared_ptr< sink_t > sink(new sink_t());
  70. const std::pair< const char*, const char* > shell_decorations[] =
  71. {
  72. std::pair< const char*, const char* >("\"", "\\\""),
  73. std::pair< const char*, const char* >("$", "\\$"),
  74. std::pair< const char*, const char* >("!", "\\!")
  75. };
  76. // Make the formatter generate the command line for notify-send
  77. sink->set_formatter
  78. (
  79. expr::stream << "notify-send -t 2000 -u "
  80. << boost::phoenix::bind(&severity_level_as_urgency, logging::trivial::severity.or_none())
  81. << expr::if_(expr::has_attr(process_name))
  82. [
  83. expr::stream << " -a '" << process_name << "'"
  84. ]
  85. << expr::if_(expr::has_attr(caption))
  86. [
  87. expr::stream << " \"" << expr::char_decor(shell_decorations)[ expr::stream << caption ] << "\""
  88. ]
  89. << " \"" << expr::char_decor(shell_decorations)[ expr::stream << expr::message ] << "\""
  90. );
  91. core->add_sink(sink);
  92. // Add attributes that we will use
  93. core->add_global_attribute("ProcessName", attrs::current_process_name());
  94. }
  95. //]
  96. //[ example_extension_app_launcher_logging
  97. void test_notifications()
  98. {
  99. BOOST_LOG_TRIVIAL(debug) << "Hello, it's a simple notification";
  100. BOOST_LOG_TRIVIAL(info) << logging::add_value(caption, "Caption text") << "And this notification has caption as well";
  101. }
  102. //]
  103. int main(int, char*[])
  104. {
  105. init_logging();
  106. test_notifications();
  107. return 0;
  108. }