Logger.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
3 
4  This file is part of the TerraLib - a Framework for building GIS enabled applications.
5 
6  TerraLib is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published by
8  the Free Software Foundation, either version 3 of the License,
9  or (at your option) any later version.
10 
11  TerraLib is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with TerraLib. See COPYING. If not, write to
18  TerraLib Team at <terralib-team@terralib.org>.
19  */
20 
21 /*!
22  \file terralib/core/logger/Logger.cpp
23 
24  \brief This class is designed to manage the log of information in TerraLib.
25 
26  \author Matheus Cavassan Zaglia
27  \author Gilberto Ribeiro de Queiroz
28  */
29 
30 // TerraLib
31 #include "Logger.h"
32 #include "../Exception.h"
33 #include "../translator/Translator.h"
34 
35 // Boost
36 #include <boost/format.hpp>
37 #include <boost/filesystem/fstream.hpp>
38 #include <boost/log/attributes/current_process_name.hpp>
39 #include <boost/log/attributes/current_thread_id.hpp>
40 #include <boost/log/sinks/text_ostream_backend.hpp>
41 #include <boost/log/sources/severity_channel_logger.hpp>
42 #include <boost/log/trivial.hpp>
43 #include <boost/log/utility/setup/common_attributes.hpp>
44 #include <boost/log/utility/setup/file.hpp>
45 #include <boost/log/utility/setup/from_stream.hpp>
46 
47 BOOST_LOG_ATTRIBUTE_KEYWORD(channel, "Channel", std::string)
48 
49 
50 struct te::core::Logger::Impl
51 {
52  /*! \brief Multi-Thread severity logger*/
53  boost::log::sources::severity_channel_logger_mt<boost::log::trivial::severity_level, std::string> m_logger;
54 
55  /*! \brief Logger list */
56  std::vector< std::string > m_logger_list;
57 };
58 
60 {
61  static Logger instance;
62 
63  return instance;
64 }
65 
66 void te::core::Logger::addLoggerFromFile(const std::string& filename)
67 {
68  if(filename.empty())
69  te::InvalidArgumentException() << te::ErrorDescription(TE_TR("The logger configuration file name cannot be empty."));
70 
71  if(exists(filename))
72  {
73  boost::format err_msg(TE_TR("There is already a logger registered using the configuration in file named: %1%"));
74 
75  te::InvalidArgumentException() << te::ErrorDescription((err_msg % filename).str());
76  }
77 
78  boost::filesystem::ifstream settings(filename);
79  boost::log::init_from_stream(settings);
80 
81  m_pimpl->m_logger_list.push_back(filename);
82 }
83 
84 void te::core::Logger::addLogger(const std::string& name, const std::string& filename, std::string format)
85 {
86  if(name.empty())
87  throw te::InvalidArgumentException() << te::ErrorDescription(TE_TR("The logger name cannot be empty."));
88 
89  if(exists(name))
90  {
91  boost::format err_msg(TE_TR("There is already a logger registered with the name: %1%"));
92 
93  throw te::InvalidArgumentException() << te::ErrorDescription((err_msg % name).str());
94  }
95 
96  if(format.empty())
97  format = "[%TimeStamp%] <%Severity%>: %Message%";
98 
99  boost::log::add_file_log(boost::log::keywords::auto_flush = true,
100  boost::log::keywords::format = format,
101  boost::log::keywords::file_name = filename,
102  boost::log::keywords::channel = name,
103  boost::log::keywords::open_mode = std::ios_base::app,
104  boost::log::keywords::filter = (channel == name)
105  );
106 
107  m_pimpl->m_logger_list.push_back(name);
108 }
109 
110 bool te::core::Logger::exists(const std::string &name)
111 {
112  return std::find_if(m_pimpl->m_logger_list.begin(), m_pimpl->m_logger_list.end(),
113  [&name](const std::string& n)
114  { return name == n; }) != m_pimpl->m_logger_list.end();
115 }
116 
118 {
119  boost::log::core::get()->remove_all_sinks();
120  m_pimpl->m_logger_list.clear();
121 }
122 
124  m_pimpl(nullptr)
125 {
126  boost::log::register_simple_formatter_factory< boost::log::trivial::severity_level, char >("Severity");
127 
128  boost::log::core::get()->add_global_attribute("Process",
129  boost::log::attributes::current_process_name());
130  boost::log::core::get()->add_global_attribute("ProcessID",
131  boost::log::attributes::current_process_id());
132  boost::log::core::get()->add_global_attribute("ThreadID",
133  boost::log::attributes::current_thread_id());
134  boost::log::add_common_attributes();
135 
136  m_pimpl = new Impl;
137 }
138 
140 {
141  delete m_pimpl;
142 }
143 
144 
145 void te::core::Logger::log(const std::string& message, const std::string& channel, severity_level severity)
146 {
147  if(std::find(m_pimpl->m_logger_list.begin(), m_pimpl->m_logger_list.end(),
148  channel) == m_pimpl->m_logger_list.end())
149  return;
150 
151  boost::log::trivial::severity_level boost_severity;
152  switch(severity)
153  {
154  case severity_level::trace :
155  boost_severity = boost::log::trivial::trace;
156  break;
157  case severity_level::debug :
158  boost_severity = boost::log::trivial::debug;
159  break;
160  case severity_level::info :
161  boost_severity = boost::log::trivial::info;
162  break;
163  case severity_level::warning :
164  boost_severity = boost::log::trivial::warning;
165  break;
166  case severity_level::error :
167  boost_severity = boost::log::trivial::error;
168  break;
169  case severity_level::fatal :
170  boost_severity = boost::log::trivial::fatal;
171  break;
172  default:
173  throw InvalidArgumentException() << ErrorDescription(TE_TR("Invalid severity level."));
174  break;
175  }
176 
177  BOOST_LOG_CHANNEL_SEV(m_pimpl->m_logger, channel, boost_severity) << message;
178 }
179 
180 
This class is a singleton designed to manage log messages in TerraLib.
Impl * m_pimpl
Definition: Logger.h:146
void log(const std::string &message, const std::string &channel, severity_level severity)
It logs a given string message, channel and severity.
Definition: Logger.cpp:145
void addLogger(const std::string &name, const std::string &filename, std::string format)
It sets the logger using a default implementation.
Definition: Logger.cpp:84
void addLoggerFromFile(const std::string &filename)
It sets the logger configuration from a given file.
Definition: Logger.cpp:66
Logger()
Singleton constructor must be private or protected.
Definition: Logger.cpp:123
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
boost::error_info< struct tag_error_description, std::string > ErrorDescription
The base type for error report messages.
static Logger & instance()
It returns a reference to the singleton instance.
bool exists(const std::string &name)
Checks if exists a logger registered with the given name.
Definition: Logger.cpp:110
URI C++ Library.
Definition: Attributes.h:37
void removeAllLoggers()
It removes all added loggers.
Definition: Logger.cpp:117
This class is designed to manage the log of information in TerraLib.
~Logger()
Singleton destructor must be private or protected.
Definition: Logger.cpp:139
An exception indicating that a given argument is not valid, for instance if a given item already exis...