You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by ms...@apache.org on 2019/04/25 12:15:28 UTC
[plc4x] branch develop updated: Add Logger-Folder with following
Blogger, DatDmp, DbgTrace, ErrorCategory, ErrorInfoException, ExLog,
CMakeLists Modify TopLevel CMakeLists
This is an automated email from the ASF dual-hosted git repository.
msommer pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/develop by this push:
new 7f6749d Add Logger-Folder with following Blogger, DatDmp, DbgTrace, ErrorCategory, ErrorInfoException, ExLog, CMakeLists Modify TopLevel CMakeLists
7f6749d is described below
commit 7f6749d6dc2fb14dae1720ae455f8f605ca791ac
Author: Markus Sommer <ms...@apache.org>
AuthorDate: Thu Apr 25 14:15:07 2019 +0200
Add Logger-Folder with following Blogger, DatDmp, DbgTrace, ErrorCategory, ErrorInfoException, ExLog, CMakeLists
Modify TopLevel CMakeLists
---
plc4cpp/CMakeLists.txt | 1 +
plc4cpp/{ => utils/logger}/CMakeLists.txt | 16 +-
.../org/apache/plc4x/cpp/utils/logger/BLogger.cpp | 475 +++++++++++++++++++++
.../org/apache/plc4x/cpp/utils/logger/BLogger.h | 157 +++++++
.../org/apache/plc4x/cpp/utils/logger/DatDmp.cpp | 143 +++++++
.../cpp/org/apache/plc4x/cpp/utils/logger/DatDmp.h | 88 ++++
.../org/apache/plc4x/cpp/utils/logger/DbgTrace.cpp | 52 +++
.../org/apache/plc4x/cpp/utils/logger/DbgTrace.h | 54 +++
.../plc4x/cpp/utils/logger/ErrorCategory.cpp | 71 +++
.../apache/plc4x/cpp/utils/logger/ErrorCategory.h | 125 ++++++
.../plc4x/cpp/utils/logger/ErrorInfoException.cpp | 171 ++++++++
.../plc4x/cpp/utils/logger/ErrorInfoException.h | 83 ++++
.../org/apache/plc4x/cpp/utils/logger/ExLog.cpp | 143 +++++++
.../cpp/org/apache/plc4x/cpp/utils/logger/ExLog.h | 71 +++
14 files changed, 1645 insertions(+), 5 deletions(-)
diff --git a/plc4cpp/CMakeLists.txt b/plc4cpp/CMakeLists.txt
index 1cf4d14..c0fdfef 100644
--- a/plc4cpp/CMakeLists.txt
+++ b/plc4cpp/CMakeLists.txt
@@ -30,3 +30,4 @@ set(PLC4CPP_ROOT_DIR ${CMAKE_SOURCE_DIR})
]]
add_subdirectory(api)
add_subdirectory(protocols/driver-bases/base)
+add_subdirectory(utils/logger)
\ No newline at end of file
diff --git a/plc4cpp/CMakeLists.txt b/plc4cpp/utils/logger/CMakeLists.txt
similarity index 58%
copy from plc4cpp/CMakeLists.txt
copy to plc4cpp/utils/logger/CMakeLists.txt
index 1cf4d14..6f20fcd 100644
--- a/plc4cpp/CMakeLists.txt
+++ b/plc4cpp/utils/logger/CMakeLists.txt
@@ -22,11 +22,17 @@ set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
-set(PLC4CPP_ROOT_DIR ${CMAKE_SOURCE_DIR})
-
+add_library(plc4cpp-utils-logger
+ src/main/cpp/org/apache/plc4x/cpp/utils/logger/BLogger.cpp
+ src/main/cpp/org/apache/plc4x/cpp/utils/logger/DatDmp.cpp
+ src/main/cpp/org/apache/plc4x/cpp/utils/logger/DbgTrace.cpp
+ src/main/cpp/org/apache/plc4x/cpp/utils/logger/ErrorCategory.cpp
+ src/main/cpp/org/apache/plc4x/cpp/utils/logger/ErrorInfoException.cpp
+ src/main/cpp/org/apache/plc4x/cpp/utils/logger/ExLog.cpp
+ )
#[[
- Build all the modules of PLC4Cpp
+ Import the headers for boost and the plc4cpp-utils module
]]
-add_subdirectory(api)
-add_subdirectory(protocols/driver-bases/base)
+target_include_directories (plc4cpp-utils-logger PUBLIC ../../libs/libs/boost/include)
+target_include_directories (plc4cpp-utils-logger PUBLIC ../../api/src/main/cpp)
\ No newline at end of file
diff --git a/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/BLogger.cpp b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/BLogger.cpp
new file mode 100644
index 0000000..1eafef4
--- /dev/null
+++ b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/BLogger.cpp
@@ -0,0 +1,475 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+#include "BLogger.h"
+#include <boost/log/utility/setup/common_attributes.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
+#include <boost/regex.hpp>
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <boost/log/sinks/text_file_backend.hpp>
+#include <boost/log/core/core.hpp>
+#include <boost/log/attributes.hpp>
+#include <boost/log/attributes/scoped_attribute.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/thread.hpp>
+#include <boost/log/sinks/text_file_backend.hpp>
+#include <boost/log/utility/setup/file.hpp>
+#include <boost/log/sources/severity_logger.hpp>
+#include <boost/log/sources/record_ostream.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/log/support/date_time.hpp>
+
+#include <ctime>
+
+namespace org
+{
+ namespace apache
+ {
+ namespace plc4x
+ {
+ namespace cpp
+ {
+ namespace utils
+ {
+ namespace fs = boost::filesystem;
+ namespace logging = boost::log;
+ namespace attrs = boost::log::attributes;
+
+ const char* BLogger::_pDefaultFileTitle = "plc4x";
+ const char* BLogger::_pDefaultFileExtension = ".log";
+
+ BLogger* BLogger::m_pInstance = NULL;
+
+ BLogger* BLogger::Instance()
+ {
+ if (!m_pInstance)
+ {
+ m_pInstance = new BLogger;
+ }
+
+ return m_pInstance;
+ }
+
+ void BLogger::Release()
+ {
+ if (m_pInstance != NULL)
+ {
+ delete m_pInstance;
+ m_pInstance = NULL;
+ }
+
+ return;
+ }
+
+ BLogger::BLogger() :
+ _iMaxFileSize(10 * 1024 * 1024), /* default max. filesize = 10 MB */
+ _uiMaxNumberOfFiles(5),
+ _strFileTitle(_pDefaultFileTitle),
+ _strFileExtension(_pDefaultFileExtension),
+ _logFilter (BoostLogger::trivial::severity >= BoostLogger::trivial::trace),
+ _severityLevel(BoostLogger::trivial::trace),
+ _uiFlushCounter(0)
+ {
+ _iSeverityLevelNumber=getNumberfromSeverityLevel(_severityLevel);
+
+ _uiMaxFlushEntrys[0] = 20 ; // trace
+ _uiMaxFlushEntrys[1] = 10 ; // debug
+ _uiMaxFlushEntrys[2] = 20 ; // info // 0 -> write once
+ _uiMaxFlushEntrys[3] = 0 ; // warning // 0 -> write once
+ _uiMaxFlushEntrys[4] = 0 ; // error // 0 -> write once
+ _uiMaxFlushEntrys[5] = 0 ; // fatal // 0 -> write once
+
+ Initialize();
+
+ return;
+ }
+
+ BLogger::~BLogger()
+ {
+ _uiFlushCounter = _uiMaxFlushEntrys[_iSeverityLevelNumber];
+ FlushLog();
+
+ return;
+ }
+
+ void BLogger::setFileTitle(string strFileTitle)
+ {
+ if (strFileTitle != _strFileTitle)
+ {
+ _strFileTitle = strFileTitle;
+ }
+
+ return;
+ }
+
+ void BLogger::setFileExtension(string strFileExtension)
+ {
+ if (strFileExtension != _strFileExtension)
+ {
+ _strFileExtension = strFileExtension;
+ }
+
+ return;
+ }
+
+ void BLogger::setMaxFileSize(int iMaxFileSize)
+ {
+ if (iMaxFileSize != _iMaxFileSize)
+ {
+ _iMaxFileSize = iMaxFileSize; /* MB */
+ }
+
+ return;
+ }
+
+ void BLogger::setMaxNumberOfFiles(unsigned int uiMaxNumberOfFiles)
+ {
+ if (uiMaxNumberOfFiles != _uiMaxNumberOfFiles)
+ {
+ _uiMaxNumberOfFiles = uiMaxNumberOfFiles;
+ }
+
+ return;
+ }
+
+ void BLogger::setSeverityLogLevel(severity_level severityLevel)
+ {
+ _severityLevel = severityLevel;
+
+ _iSeverityLevelNumber = getNumberfromSeverityLevel(_severityLevel);
+
+ _logFilter = BoostLogger::trivial::severity >= severityLevel;
+
+ BoostLogger::core::get()->set_filter(_logFilter);
+
+ return;
+ }
+
+
+ void BLogger::clearLogDir()
+ {
+ const boost::regex logFilter( "(.*\\" + _strFileExtension + ")" );
+
+ fs::path phPathFile(_strFileTitle);
+ fs::path phDir = phPathFile.parent_path();
+ if (fs::exists(phDir))
+ {
+ fs::directory_iterator it{phDir};
+ while (it != boost::filesystem::directory_iterator{})
+ {
+ if (fs::is_regular_file(*it))
+ {
+ std::string logFilename = it->path().filename().string();
+
+ if( boost::regex_match( logFilename, logFilter ) )
+ {
+ boost::filesystem::remove(it->path());
+ }
+ }
+ it++;
+ }
+ }
+
+ return;
+ }
+
+ void BLogger::Initialize()
+ {
+
+ if (_strFileTitle.length() == 0) _strFileTitle = _pDefaultFileTitle;
+ if (_strFileExtension.length() == 0) _strFileExtension = _pDefaultFileExtension;
+ string strLogFileName = _strFileTitle + "_%m%d%Y_%H%M%S_%N" + _strFileExtension;
+
+ boost::shared_ptr< logging::core > core = logging::core::get();
+ core->flush();
+ core->remove_all_sinks();
+ core->add_global_attribute("TimeStamp", attrs::local_clock());
+
+ boost::shared_ptr< sinks::text_file_backend > backend =
+ boost::make_shared< sinks::text_file_backend >
+ (
+ keywords::file_name = strLogFileName.c_str(),
+ keywords::rotation_size = _iMaxFileSize * 1024 * 1024,
+ keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0)
+ );
+
+ fs::path phDirPath(strLogFileName);
+
+ backend->set_file_collector(sinks::file::make_collector
+ (
+ keywords::target = phDirPath.parent_path().c_str(),
+ keywords::max_size = (_uiMaxNumberOfFiles - 1) * _iMaxFileSize * 1024 * 1024,
+ keywords::min_free_space = 50 * 1024 * 1024
+ ));
+
+ typedef sinks::synchronous_sink< sinks::text_file_backend > sink_t;
+ boost::shared_ptr< sink_t > sink(new sink_t(backend));
+
+ sink->set_formatter
+ (
+ expr::stream
+ << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "[%d.%m. %H:%M:%S.%f] ")
+ << " <" << BoostLogger::trivial::severity
+ << "> : " << expr::message
+ );
+
+ core->add_sink(sink);
+
+ return;
+ }
+
+ void BLogger::Log(const char* pMessage, severity_level logLevel /*= info*/)
+ {
+ try
+ {
+ if (isLog(logLevel))
+ {
+ _mtxLock.lock();
+
+ BOOST_LOG_SEV(_lg, severity_level::info) << "ThreadID 0x" << boost::this_thread::get_id() << " " << pMessage;
+
+ if(logLevel == severity_level::fatal)
+ ForceFlushLog();
+ else
+ FlushLog();
+
+ _mtxLock.unlock();
+ }
+ }
+ catch(...)
+ {
+ _mtxLock.unlock();
+ }
+
+ return;
+ }
+
+ void BLogger::Log(string strMessage, severity_level logLevel /* = info */)
+ {
+ try
+ {
+ if (isLog(logLevel))
+ {
+ _mtxLock.lock();
+
+ BOOST_LOG_SEV(_lg, logLevel) << "ThreadID 0x" << boost::this_thread::get_id() << " " << strMessage;
+
+ if(logLevel == severity_level::fatal)
+ ForceFlushLog();
+ else
+ FlushLog();
+
+ _mtxLock.unlock();
+ }
+ }
+ catch(...)
+ {
+ _mtxLock.unlock();
+ }
+
+ return;
+ }
+
+ void BLogger::LogBool(bool b, severity_level logLevel /*= info*/)
+ {
+
+ try
+ {
+ if (isLog(logLevel))
+ {
+ _mtxLock.lock();
+
+ string strBoolMessage = b ? _strTrueMessage : _strFalseMessage;
+ BOOST_LOG_SEV(_lg, logLevel) << "ThreadID 0x" << boost::this_thread::get_id() << " " << strBoolMessage;
+
+ if(logLevel == severity_level::fatal)
+ ForceFlushLog();
+ else
+ FlushLog();
+
+ _mtxLock.unlock();
+ }
+ }
+ catch(...)
+ {
+ _mtxLock.unlock();
+ }
+
+ return;
+ }
+
+ void BLogger::LogBool(string strMessage, bool b, severity_level logLevel /*= info*/)
+ {
+ try
+ {
+ if (isLog(logLevel))
+ {
+ _mtxLock.lock();
+
+ string strBoolMessage = b ? _strTrueMessage : _strFalseMessage;
+ BOOST_LOG_SEV(_lg, logLevel) << "ThreadID 0x" << boost::this_thread::get_id() << " " << strMessage << ' ' << strBoolMessage;
+
+ if(logLevel == severity_level::fatal)
+ ForceFlushLog();
+ else
+ FlushLog();
+
+ _mtxLock.unlock();
+ }
+ }
+ catch(...)
+ {
+ _mtxLock.unlock();
+ }
+
+ return;
+ }
+
+ void BLogger::LogHexDump(unsigned char* pBinaryData, unsigned int uiNumBytes, const char* pDumpPrefix /*= NULL*/, severity_level logLevel /*= info*/)
+ {
+ try
+ {
+ if (isLog(logLevel))
+ {
+ _mtxLock.lock();
+
+ DatDmp dump;
+ dump.setLeadingNewLine(true);
+ dump.setPrefix(pDumpPrefix);
+ string strDumpMessage = dump.Show(pBinaryData, uiNumBytes);
+ BOOST_LOG_SEV(_lg, logLevel) << "ThreadID 0x" << boost::this_thread::get_id() << " " << strDumpMessage;
+
+ if (logLevel == severity_level::fatal)
+ {
+ ForceFlushLog();
+ }
+ else
+ {
+ FlushLog();
+ }
+
+ _mtxLock.unlock();
+ }
+ }
+ catch(...)
+ {
+ _mtxLock.unlock();
+ }
+
+ return;
+ }
+
+ void BLogger::FlushLog(void)
+ {
+ if(_uiFlushCounter >= _uiMaxFlushEntrys[_iSeverityLevelNumber])
+ {
+ BOOST_LOG_SEV(_lg, boost::log::trivial::severity_level::info) << "ThreadID 0x" << boost::this_thread::get_id() << " Flush LogEntries";
+ logging::core::get()->flush();
+ _uiFlushCounter = 0;
+ }
+ else
+ {
+ _uiFlushCounter++;
+ }
+
+ return;
+ }
+
+ void BLogger::ForceFlushLog(void)
+ {
+ unsigned int ui = _uiMaxFlushEntrys[_iSeverityLevelNumber];
+ _uiMaxFlushEntrys[_iSeverityLevelNumber] = 0;
+ FlushLog();
+ _uiMaxFlushEntrys[_iSeverityLevelNumber] = ui;
+
+ return;
+ }
+
+ void BLogger::setSeverityLogLevelNumber(int iSeverityLevelNumber)
+ {
+
+ _iSeverityLevelNumber = iSeverityLevelNumber;
+
+ _severityLevel = getSeverityLevelfromNumber(_iSeverityLevelNumber);
+
+ setSeverityLogLevel(_severityLevel);
+
+ return;
+ }
+
+ bool BLogger::isLog(severity_level logLevel)
+ {
+ bool bResult = false;
+
+ try
+ {
+ int ilogLevel = getNumberfromSeverityLevel(logLevel);
+
+ if (_iSeverityLevelNumber <= ilogLevel)
+ {
+ bResult = true;
+ }
+ }
+ catch(...)
+ {
+ }
+
+ return bResult;
+ }
+
+ severity_level BLogger::getSeverityLevelfromNumber(int iSeverityLevelNumber)
+ {
+ severity_level logLevel = boost::log::trivial::severity_level::trace;
+
+ switch (iSeverityLevelNumber)
+ {
+ case 0: logLevel = boost::log::trivial::severity_level::trace; break;
+ case 1: logLevel = boost::log::trivial::severity_level::debug; break;
+ case 2: logLevel = boost::log::trivial::severity_level::info; break;
+ case 3: logLevel = boost::log::trivial::severity_level::warning; break;
+ case 4: logLevel = boost::log::trivial::severity_level::error; break;
+ case 5: logLevel = boost::log::trivial::severity_level::fatal; break;
+ default: logLevel = boost::log::trivial::severity_level::trace; break;
+ }
+
+ return logLevel;
+ }
+
+ int BLogger::getNumberfromSeverityLevel(severity_level severityLevel)
+ {
+ int iSeverityLevelNumber = 0;
+
+ switch (severityLevel)
+ {
+ case boost::log::trivial::severity_level::trace: iSeverityLevelNumber = 0; break;
+ case boost::log::trivial::severity_level::debug: iSeverityLevelNumber = 1; break;
+ case boost::log::trivial::severity_level::info: iSeverityLevelNumber = 2; break;
+ case boost::log::trivial::severity_level::warning: iSeverityLevelNumber = 3; break;
+ case boost::log::trivial::severity_level::error: iSeverityLevelNumber = 4; break;
+ case boost::log::trivial::severity_level::fatal: iSeverityLevelNumber = 5; break;
+ }
+
+ return iSeverityLevelNumber;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/BLogger.h b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/BLogger.h
new file mode 100644
index 0000000..57063e1
--- /dev/null
+++ b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/BLogger.h
@@ -0,0 +1,157 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+#ifndef _B_LOGGER_H_
+#define _B_LOGGER_H_
+
+#include <boost/log/core.hpp>
+#include <boost/log/trivial.hpp>
+#include <boost/log/expressions.hpp>
+#include <boost/log/sources/severity_logger.hpp>
+#include <boost/thread/mutex.hpp>
+#include "ExLog.h"
+
+#include "DatDmp.h"
+
+#define LOG_TRACE(x) org::apache::plc4x::cpp::utils::BLogger::Instance()->Log(x,boost::log::trivial::severity_level::trace)
+#define LOG_DEBUG(x) org::apache::plc4x::cpp::utils::BLogger::Instance()->Log(x,boost::log::trivial::severity_level::debug)
+#define LOG_INFO(x) org::apache::plc4x::cpp::utils::BLogger::Instance()->Log(x,boost::log::trivial::severity_level::info)
+#define LOG_WARNING(x) org::apache::plc4x::cpp::utils::BLogger::Instance()->Log(x, boost::log::trivial::severity_level::warning)
+#define LOG_ERROR(x) org::apache::plc4x::cpp::utils::BLogger::Instance()->Log(x, boost::log::trivial::severity_level::error)
+#define LOG_FATAL(x) org::apache::plc4x::cpp::utils::BLogger::Instance()->Log(x, boost::log::trivial::severity_level::fatal)
+#define LOG_BOOL(x,y) org::apache::plc4x::cpp::utils::BLogger::Instance()->LogBool(x,y)
+
+#define IS_LOG(x) org::apache::plc4x::cpp::utils::BLogger::Instance()->isLog(x)
+
+
+namespace org
+{
+ namespace apache
+ {
+ namespace plc4x
+ {
+ namespace cpp
+ {
+ namespace utils
+ {
+ namespace src = boost::log::sources;
+ namespace expr = boost::log::expressions;
+ namespace sinks = boost::log::sinks;
+ namespace keywords = boost::log::keywords;
+ namespace BoostLogger = boost::log;
+
+ using namespace BoostLogger::trivial;
+ using namespace std;
+
+
+ class BLogger
+ {
+
+ public:
+
+ static BLogger* Instance();
+ void Release();
+
+ ~BLogger();
+
+ void Initialize();
+
+ void Log(const char* strMessage, severity_level logLevel = boost::log::trivial::severity_level::info);
+
+ void Log(string strMessage, severity_level logLevel = boost::log::trivial::severity_level::info);
+
+ void LogBool(bool b, severity_level logLevel = boost::log::trivial::severity_level::info);
+
+ void LogBool(string strMessage, bool b, severity_level logLevel = boost::log::trivial::severity_level::info);
+
+ void LogHexDump(unsigned char* pBinaryData, unsigned int nNumBytes, const char* szDumpPrefix = NULL, severity_level logLevel = boost::log::trivial::severity_level::info);
+
+ string getFileExtension() { return _strFileExtension; }
+ void setFileExtension(string strExtension);
+
+ string getFileTitle() { return _strFileTitle; }
+ void setFileTitle(string strFileTitle);
+
+ int getMaxFileSize() const { return _iMaxFileSize; }
+ void setMaxFileSize(int maxFileSize);
+
+ unsigned int getMaxNumberOfFiles() { return _uiMaxNumberOfFiles; }
+ void setMaxNumberOfFiles(unsigned int uiMaxNumberOfFiles);
+
+ severity_level getSeverityLogLevel() { return _severityLevel; }
+ void setSeverityLogLevel(severity_level severityLevel);
+
+ int getSeverityLogLevelNumber() { return getNumberfromSeverityLevel(_severityLevel); }
+ void setSeverityLogLevelNumber(int iSeverityLevelNumber);
+
+ bool isLog(severity_level logLevel);
+
+ string getTrueMessage() const { return _strTrueMessage; }
+ void setTrueMessage(string strTrueMessage) { _strTrueMessage = strTrueMessage; }
+
+ string getFalseMessage() const { return _strFalseMessage; }
+ void setFalseMessage(string strFalseMessage) { _strFalseMessage = strFalseMessage; }
+
+ void clearLogDir();
+ void ForceFlushLog(void);
+
+ private:
+
+ BLogger(); // Private so that it can not be called
+ BLogger(BLogger const&){}; // copy constructor is private
+ BLogger& operator=(BLogger const&){ }; // assignment operator is private
+
+ int getNumberfromSeverityLevel(severity_level severityLevel);
+ severity_level getSeverityLevelfromNumber(int iSeverityLevelNumber);
+
+ void FlushLog(void);
+
+ static BLogger* m_pInstance;
+
+ int _iMaxFileSize;
+ unsigned int _uiMaxNumberOfFiles;
+
+ unsigned int _uiFlushCounter;
+
+ unsigned int _uiMaxFlushEntrys[6];
+
+ severity_level _severityLevel;
+ int _iSeverityLevelNumber;
+
+ boost::log::filter _logFilter;
+
+ src::severity_logger_mt<severity_level> _lg;
+
+ boost::mutex _mtxLock;
+
+ string _strFileTitle;
+ string _strFileExtension;
+
+ string _strTrueMessage;
+ string _strFalseMessage;
+
+ static const char* _pDefaultFileTitle;
+ static const char* _pDefaultFileExtension;
+ };
+ }
+ }
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/DatDmp.cpp b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/DatDmp.cpp
new file mode 100644
index 0000000..e92c2ef
--- /dev/null
+++ b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/DatDmp.cpp
@@ -0,0 +1,143 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+#include "DatDmp.h"
+
+namespace org
+{
+ namespace apache
+ {
+ namespace plc4x
+ {
+ namespace cpp
+ {
+ namespace utils
+ {
+
+ char DatDmp::achHex[3] = { '\0', '\0', '\0' };
+
+ DatDmp::DatDmp() :
+ _strHexDump(""),
+ _strPrefix(""),
+ _uiBytesPerLine(16),
+ _bLeadingNewLine(false)
+ {
+ }
+
+ DatDmp::DatDmp(unsigned int uiBytesPerLine) :
+ _strHexDump(""),
+ _strPrefix(""),
+ _uiBytesPerLine(uiBytesPerLine),
+ _bLeadingNewLine(false)
+ {
+ }
+
+ string DatDmp::Show(unsigned char* pStream, unsigned int uiNumbersBytes, const char* pLinePrefix /*= NULL*/)
+ {
+ _strHexDump = "";
+ if (_bLeadingNewLine)
+ {
+ _bLeadingNewLine = false;
+ _strHexDump += '\n';
+ }
+
+ for (unsigned int uiByteCounter = 0, iStopByte = _uiBytesPerLine;
+ uiByteCounter < uiNumbersBytes;
+ uiByteCounter += _uiBytesPerLine, iStopByte += _uiBytesPerLine
+ )
+ {
+ if (pLinePrefix != NULL) _strHexDump += pLinePrefix;
+ _strHexDump += _strPrefix;
+
+ int nBoundaryBytes = 0;
+ if (iStopByte > uiNumbersBytes)
+ {
+ nBoundaryBytes = iStopByte - uiNumbersBytes;
+ iStopByte = uiNumbersBytes;
+ }
+
+ for (unsigned int uiByteLine = uiByteCounter; uiByteLine < iStopByte; uiByteLine++)
+ {
+ unsigned char byte = pStream[uiByteLine];
+ _strHexDump += Hex(byte);
+ _strHexDump += ' ';
+ }
+ if (nBoundaryBytes > 0) _strHexDump += std::string(3 * nBoundaryBytes, ' ');
+ _strHexDump += "| ";
+
+ for (unsigned int uiByteLine = uiByteCounter; uiByteLine < iStopByte; uiByteLine++)
+ {
+ char ch = (char)pStream[uiByteCounter];
+ if (ch >= 0)
+ {
+ if (!isprint(ch)) ch = '.';
+ }
+ else
+ {
+ ch = '.';
+ }
+ _strHexDump += ch;
+ }
+ _strHexDump += "\n";
+ }
+ return _strHexDump;
+ }
+
+ string DatDmp::HexByte(unsigned char ucByte)
+ {
+ return string(Hex(ucByte));
+ }
+
+ string DatDmp::HexWord(unsigned short usWord)
+ {
+ return string(Hex((unsigned char)(usWord >> 8))) + string(Hex((unsigned char)(usWord & 0xff)));
+ }
+
+ string DatDmp::HexDWord(unsigned int uiDWord)
+ {
+ return string(Hex((unsigned char)((uiDWord & 0xff000000) >> 24)))
+ + string(Hex((unsigned char)((uiDWord & 0x00ff0000) >> 16)))
+ + string(Hex((unsigned char)((uiDWord & 0x0000ff00) >> 8)))
+ + string(Hex((unsigned char)((uiDWord & 0x000000ff))));
+ }
+
+ const char* DatDmp::Hex(unsigned char ucByte)
+ {
+ achHex[0] = HexNibbleHigh(ucByte);
+ achHex[1] = HexNibbleLow(ucByte);
+ achHex[2] = '\0';
+ return (const char*)achHex;
+ }
+
+ char DatDmp::HexNibbleHigh(unsigned char ucByte)
+ {
+ unsigned char btNibble = (unsigned char)(ucByte >> 4);
+ return btNibble <= (unsigned char)9 ? '0' + btNibble : 'A' + btNibble - (unsigned char)10;
+ }
+
+ char DatDmp::HexNibbleLow(unsigned char ucByte)
+ {
+ unsigned char btNibble = (unsigned char)(ucByte & 0x0f);
+ return btNibble <= (unsigned char)9 ? '0' + btNibble : 'A' + btNibble - (unsigned char)10;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/DatDmp.h b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/DatDmp.h
new file mode 100644
index 0000000..bf4006c
--- /dev/null
+++ b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/DatDmp.h
@@ -0,0 +1,88 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+#ifndef _DATDMP_H_
+#define _DATDMP_H_
+
+#include <stdlib.h>
+#include <string>
+#include <iostream>
+
+using namespace std;
+
+namespace org
+{
+ namespace apache
+ {
+ namespace plc4x
+ {
+ namespace cpp
+ {
+ namespace utils
+ {
+ class DatDmp
+ {
+ public:
+
+ DatDmp();
+ DatDmp(unsigned int uiBytesPerLine);
+
+ string Show(unsigned char* pStream, unsigned int uiNumbersBytes, const char* pLinePrefix = NULL);
+
+ string getPrefix() { return _strPrefix; }
+ void setPrefix(string strPrefix) { _strPrefix = strPrefix; }
+
+ void setPrefix(const char* pPrefix) { _strPrefix.clear();
+ if (pPrefix != NULL) { _strPrefix = pPrefix; };
+ }
+
+ inline unsigned getBytesPerLine() const { return _uiBytesPerLine; }
+ void setBytesPerLine(unsigned int uiBytesPerLine) { _uiBytesPerLine = uiBytesPerLine; }
+
+ inline bool getLeadingNewLine() const { return _bLeadingNewLine; }
+ void setLeadingNewLine(bool bLeadingNewLine) { _bLeadingNewLine = bLeadingNewLine; }
+
+ static string HexByte(unsigned char ucByte);
+ static string HexWord(unsigned short usWord);
+ static string HexDWord(unsigned int uiDword);
+
+ protected:
+
+ static const char* Hex(unsigned char ucByte);
+ static char HexNibbleHigh(unsigned char ucByte);
+ static char HexNibbleLow(unsigned char ucByte);
+
+ protected:
+
+ string _strHexDump;
+ string _strPrefix;
+ unsigned int _uiBytesPerLine;
+ bool _bLeadingNewLine;
+
+ private:
+
+ static char achHex[3];
+ };
+ }
+ }
+ }
+ }
+}
+
+#endif
diff --git a/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/DbgTrace.cpp b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/DbgTrace.cpp
new file mode 100644
index 0000000..57c99e5
--- /dev/null
+++ b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/DbgTrace.cpp
@@ -0,0 +1,52 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+#define TRACE_BUFFERSIZE 0x1000000
+
+#if defined(_DEBUG)
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <wtypes.h>
+#include <tchar.h>
+#include <windows.h>
+
+
+void TracerW(const wchar_t* formatStr, ...)
+{
+ static wchar_t arcBuffer[TRACE_BUFFERSIZE];
+ va_list args;
+ va_start(args, formatStr);
+ _vstprintf_s(arcBuffer, TRACE_BUFFERSIZE, formatStr, args);
+ va_end(args);
+ ::OutputDebugString(buffer);
+}
+
+
+void Tracer(const char* formatStr, ...)
+{
+ static char arcBuffer[TRACE_BUFFERSIZE];
+ va_list args;
+ va_start(args, formatStr);
+ vsprintf_s(arcBuffer, TRACE_BUFFERSIZE, formatStr, args);
+ va_end(args);
+ ::OutputDebugStringA(buffer);
+}
+
+#endif
diff --git a/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/DbgTrace.h b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/DbgTrace.h
new file mode 100644
index 0000000..b27889f
--- /dev/null
+++ b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/DbgTrace.h
@@ -0,0 +1,54 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+#ifndef _DBG_TRACE_H_
+#define _DBG_TRACE_H_
+
+#define TRACE_BUFFERSIZE 0x1000000
+
+// TRACE MACROS to main header file
+#if defined(_DEBUG)
+
+#define DEBUG_TRACE_0(f) TracerW(f)
+#define DEBUG_TRACE_1(f,a) TracerW(f,a)
+#define DEBUG_TRACE_2(f,a,b) TracerW(f,a,b)
+#define DEBUG_TRACE_3(f,a,b,c) TracerW(f,a,b,c)
+void TracerW(const wchar_t* formatStr, ...);
+
+#define DEBUG_TRACE0(f) Tracer(f)
+#define DEBUG_TRACE1(f,a) Tracer(f,a)
+#define DEBUG_TRACE2(f,a,b) Tracer(f,a,b)
+#define DEBUG_TRACE3(f,a,b,c) Tracer(f,a,b,c)
+void Tracer(const char* formatStr, ...);
+
+#else
+
+#define DEBUG_TRACE_0(f) ((void)NULL)
+#define DEBUG_TRACE_1(f,a) ((void)NULL)
+#define DEBUG_TRACE_2(f,a,b) ((void)NULL)
+#define DEBUG_TRACE_3(f,a,b,c) ((void)NULL)
+
+#define DEBUG_TRACE0(f) ((void)NULL)
+#define DEBUG_TRACE1(f,a) ((void)NULL)
+#define DEBUG_TRACE2(f,a,b) ((void)NULL)
+#define DEBUG_TRACE3(f,a,b,c) ((void)NULL)
+
+#endif
+
+#endif
diff --git a/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ErrorCategory.cpp b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ErrorCategory.cpp
new file mode 100644
index 0000000..d40b723
--- /dev/null
+++ b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ErrorCategory.cpp
@@ -0,0 +1,71 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+#include "ErrorCategory.h"
+
+namespace org
+{
+ namespace apache
+ {
+ namespace plc4x
+ {
+ namespace cpp
+ {
+ namespace utils
+ {
+
+ const char* Error_Category::_paErrorMessage[] =
+ {
+ "success",
+ "err0",
+ "err1",
+ "err2",
+ "err3",
+ "err4",
+ "err5",
+ "err6"
+ };
+
+
+ std::string Error_Category::message(int iEv) const
+ {
+ std::string strMessage = "";
+ if (IsValidMessageIndex(iEv))
+ {
+ strMessage = _paErrorMessage[iEv];
+ }
+ else
+ {
+ strMessage = DefaultMessage(iEv);
+ }
+
+ return strMessage;
+ }
+
+ std::string Error_Category::DefaultMessage(int iEv) const
+ {
+ boost::system::error_code ecCode(iEv, boost::system::system_category());
+
+ return ecCode.message();
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ErrorCategory.h b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ErrorCategory.h
new file mode 100644
index 0000000..65abd48
--- /dev/null
+++ b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ErrorCategory.h
@@ -0,0 +1,125 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+#ifndef _ERRORCATEGORY_H_
+#define _ERRORCATEGORY_H_
+
+#include <boost\system\error_code.hpp>
+#include <string>
+
+namespace org
+{
+ namespace apache
+ {
+ namespace plc4x
+ {
+ namespace cpp
+ {
+ namespace utils
+ {
+ class IError_Category
+ {
+ public:
+
+ virtual const char* name() const = 0;
+ virtual inline std::string getName() const = 0;
+
+ virtual std::string message(int iEv) const = 0;
+
+ protected:
+ virtual bool IsValidMessageIndex(int iEv) const = 0;
+ };
+
+
+ class Error_Category : IError_Category
+ {
+ public:
+ enum Category
+ {
+ System = 0,
+ Application,
+ max_category = Application,
+ num_categories
+ };
+
+ Error_Category() :
+ _Category(System),
+ _strName("System"),
+ _iMsgOffset(0)
+ {
+ }
+
+ virtual const char* name() const { return _strName.c_str(); }
+
+ virtual std::string message(int ev) const;
+
+ virtual inline std::string getName() const { return _strName; }
+
+ protected:
+
+ std::string DefaultMessage(int ev) const;
+
+ virtual bool IsValidMessageIndex(int ev) const { return false; }
+
+ protected:
+ std::string _strName;
+ Category _Category;
+ int _iMsgOffset;
+
+ static const char* _paErrorMessage[];
+ };
+
+ class Error_Category_Application : public Error_Category
+ {
+ public:
+
+ enum errc_t
+ {
+ success = 0,
+ err1,
+ err2,
+ err3,
+ err4,
+ err5,
+ err6,
+ max_err = err6,
+ num_codes
+ };
+
+ Error_Category_Application()
+ {
+ _Category = Application;
+ _strName = "Application";
+ _iMsgOffset = 0; // Start-Offset to error message index, to be set ..
+ } // .. individually for each derivation of Error_Category!
+ // Provide messages in array Error_Category::_aszErrorMessage[]!
+ protected:
+
+ virtual bool IsValidMessageIndex(int iEv) const
+ {
+ return iEv >= (int)success && iEv <= _iMsgOffset + (int)max_err;
+ }
+
+ };
+ }
+ }
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ErrorInfoException.cpp b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ErrorInfoException.cpp
new file mode 100644
index 0000000..0cbb1a3
--- /dev/null
+++ b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ErrorInfoException.cpp
@@ -0,0 +1,171 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+#include <boost/exception/all.hpp>
+#include <exception>
+#include <boost/lexical_cast.hpp>
+#include "ErrorInfoException.h"
+#include "ExLog.h"
+#include "DbgTrace.h"
+#include "BLogger.h"
+
+namespace org
+{
+ namespace apache
+ {
+ namespace plc4x
+ {
+ namespace cpp
+ {
+ namespace utils
+ {
+
+ ErrorInfoException::ErrorInfoException() :
+ _uiUserMessageID(-1),
+ pCategory(NULL),
+ _iEv(-1)
+ {
+ std::string strErrorMessage = " ErrorInfoException no Message";
+ LOG_ERROR(strErrorMessage);
+ DEBUG_TRACE1("%s\n", strErrorMessage.c_str());
+
+ return;
+ }
+
+ ErrorInfoException::ErrorInfoException(unsigned int uiUserMessageID, std::string strErrorInfo) :
+ _uiUserMessageID(uiUserMessageID),
+ _strWhat(strErrorInfo),
+ pCategory(NULL),
+ _iEv(-1)
+ {
+ LOG_ERROR(strErrorInfo);
+ DEBUG_TRACE1("%s\n", strErrorInfo.c_str());
+
+ return;
+ }
+
+ ErrorInfoException::ErrorInfoException(unsigned int uiUserMessageID, std::exception& ex) :
+ _uiUserMessageID(uiUserMessageID),
+ _strWhat(ex.what()),
+ pCategory(NULL),
+ _iEv(-1)
+ {
+ LOG_ERROR(ex.what());
+ DEBUG_TRACE1("%s\n", ex.what());
+
+ return;
+ }
+
+ ErrorInfoException::ErrorInfoException(unsigned int uiUserMessageID, boost::exception& ex) :
+ _uiUserMessageID(uiUserMessageID),
+ _strWhat(*boost::get_error_info<errmsg_info>(ex)),
+ pCategory(NULL),
+ _iEv(-1)
+ {
+ LOG_ERROR(*boost::get_error_info<errmsg_info>(ex));
+ DEBUG_TRACE1("%s\n", _strWhat.c_str());
+
+ return;
+ }
+
+ ErrorInfoException::ErrorInfoException(unsigned int uiUserMessageID, Error_Category::Category cat, int iErrorValue) :
+ _uiUserMessageID(uiUserMessageID),
+ pCategory(CreateErrorCategory(cat)),
+ _iEv(iErrorValue)
+ {
+ std::string strMessage = boost::lexical_cast<std::string>(iErrorValue);
+ LOG_ERROR(strMessage.c_str());
+ DEBUG_TRACE1("ErrorValue:%i\n", iErrorValue);
+
+ return;
+ }
+
+ ErrorInfoException::ErrorInfoException(unsigned int uiUserMessageID, Error_Category::Category cat, int iErrorValue, std::string strErrorInfo) :
+ _uiUserMessageID(uiUserMessageID),
+ _strWhat(strErrorInfo),
+ pCategory(CreateErrorCategory(cat)),
+ _iEv(iErrorValue)
+ {
+ LOG_ERROR(strErrorInfo);
+ DEBUG_TRACE1("%s\n", strErrorInfo.c_str());
+
+ return;
+ }
+
+
+ ErrorInfoException::ErrorInfoException(unsigned int uiUserMessageID, Error_Category::Category cat, int iErrorValue, std::exception& ex) :
+ _uiUserMessageID(uiUserMessageID),
+ _strWhat(ex.what()),
+ pCategory(CreateErrorCategory(cat)),
+ _iEv(iErrorValue)
+ {
+ LOG_ERROR(ex.what());
+ DEBUG_TRACE1("%s\n", ex.what());
+
+ return;
+ }
+
+ ErrorInfoException::ErrorInfoException(unsigned int uiUserMessageID, Error_Category::Category cat, int iErrorValue, boost::exception& ex) :
+ _uiUserMessageID(uiUserMessageID),
+ _strWhat(*boost::get_error_info<errmsg_info>(ex)),
+ pCategory(CreateErrorCategory(cat)),
+ _iEv(iErrorValue)
+ {
+ LOG_ERROR(*boost::get_error_info<errmsg_info>(ex));
+ DEBUG_TRACE1("%s\n", _strWhat.c_str());
+
+ return;
+ }
+
+ ErrorInfoException::~ErrorInfoException()
+ {
+ if (pCategory != NULL) { delete pCategory; };
+
+ return;
+ }
+
+ Error_Category* ErrorInfoException::CreateErrorCategory(Error_Category::Category cat) throw()
+ {
+ Error_Category* pCat = NULL;
+ try
+ {
+ switch (cat)
+ {
+ case Error_Category::Category::System:
+ default:
+ pCat = new Error_Category();
+ break;
+
+ case Error_Category::Category::Application:
+ pCat = new Error_Category_Application();
+ break;
+ }
+ }
+ catch (...)
+ {
+ pCat = NULL;
+ }
+
+ return pCat;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ErrorInfoException.h b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ErrorInfoException.h
new file mode 100644
index 0000000..ebaf0b6
--- /dev/null
+++ b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ErrorInfoException.h
@@ -0,0 +1,83 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+#ifndef _ERROR_INFO_EXCEPTION_H_
+#define _ERROR_INFO_EXCEPTION_H_
+
+#include <exception>
+#include <boost/exception/exception.hpp>
+#include "ErrorCategory.h"
+
+namespace org
+{
+ namespace apache
+ {
+ namespace plc4x
+ {
+ namespace cpp
+ {
+ namespace utils
+ {
+
+ class ErrorInfoException : public boost::exception, public std::exception
+ {
+ public:
+ ErrorInfoException();
+
+ virtual ~ErrorInfoException();
+
+ ErrorInfoException(unsigned int uiUserMessageID, std::string strErrorInfo);
+
+ ErrorInfoException(unsigned int uiUserMessageID, std::exception& ex);
+
+ ErrorInfoException(unsigned int uiUserMessageID, boost::exception& ex);
+
+ ErrorInfoException(unsigned int uiUserMessageID, Error_Category::Category cat, int iErrorValue);
+
+ ErrorInfoException(unsigned int uiUserMessageID, Error_Category::Category cat, int iErrorValue, std::string strErrorInfo);
+
+ ErrorInfoException(unsigned int uiUserMessageID, Error_Category::Category cat, int iErrorValue, std::exception& ex);
+
+ ErrorInfoException(unsigned int uiUserMessageID, Error_Category::Category cat, int iErrorValue, boost::exception& ex);
+
+ inline unsigned int getUserMessageID() const { return _uiUserMessageID; }
+
+ virtual const char* what() const throw() { return _strWhat.c_str(); }
+
+ Error_Category* pCategory;
+
+ inline int getErrorValue() const { return _iEv; }
+
+ protected:
+
+ Error_Category* CreateErrorCategory(Error_Category::Category cat) throw();
+
+ protected:
+
+ std::string _strWhat;
+ int _iEv;
+ unsigned int _uiUserMessageID;
+
+ };
+ }
+ }
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ExLog.cpp b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ExLog.cpp
new file mode 100644
index 0000000..455d907
--- /dev/null
+++ b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ExLog.cpp
@@ -0,0 +1,143 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+#include <boost/exception/all.hpp>
+#include <exception>
+#include <boost/lexical_cast.hpp>"
+#include <typeinfo>
+#include "ErrorInfoException.h"
+
+#include "DbgTrace.h"
+#include "BLogger.h"
+
+namespace org
+{
+ namespace apache
+ {
+ namespace plc4x
+ {
+ namespace cpp
+ {
+ namespace utils
+ {
+ using namespace std;
+ using namespace boost;
+
+ ExLog::ExLog()
+ {
+
+ }
+
+ ExLog::ExLog(unsigned int uiUserMessageID, std::exception& ex, const char* pError) :
+ _strWhat(ex.what())
+ {
+ string strExceptionClassName = typeid(ex).name();
+
+ if (strExceptionClassName.find(typeid(ExLog).name()) != std::string::npos)
+ {
+ _uiUserMessageID = (reinterpret_cast<ExLog&>(ex)).getUserMessageID();
+ }
+ else if (strExceptionClassName.find(typeid(ErrorInfoException).name()) != std::string::npos)
+ {
+ _uiUserMessageID = (reinterpret_cast<ErrorInfoException&>(ex)).getUserMessageID();
+ }
+ else
+ {
+ _uiUserMessageID = uiUserMessageID;
+ }
+
+ std::stringstream strStream;
+
+ _strLastErrorMessage = std::string(pError) + '\n';
+
+ _strLastErrorMessage = _strLastErrorMessage + std::string("MessageID: ") + lexical_cast<std::string>(_uiUserMessageID) + '\n';
+
+ strStream << diagnostic_information(ex) << std::endl;
+ _strLastErrorMessage = _strLastErrorMessage + strStream.str();
+
+ _strLastErrorMessage = _strLastErrorMessage + printStackTrace();
+
+ DEBUG_TRACE1("%s\n", _strLastErrorMessage.c_str());
+ LOG_ERROR(_strLastErrorMessage);
+
+ return;
+ }
+
+ ExLog::ExLog(unsigned int uiUserMessageID, boost::exception& ex, const char* pError) :
+ _strWhat(*get_error_info<errmsg_info>(ex))
+ {
+ string strExceptionClassName = typeid(ex).name();
+
+ if (strExceptionClassName.find(typeid(ExLog).name()) != std::string::npos)
+ {
+ _uiUserMessageID = (reinterpret_cast<ExLog&>(ex)).getUserMessageID();
+ }
+ else if (strExceptionClassName.find(typeid(ErrorInfoException).name()) != std::string::npos)
+ {
+ _uiUserMessageID = (reinterpret_cast<ErrorInfoException&>(ex)).getUserMessageID();
+ }
+ else
+ {
+ _uiUserMessageID = uiUserMessageID;
+ }
+
+ std::stringstream strStream;
+
+ _strLastErrorMessage = std::string(pError) + '\n';
+
+ _strLastErrorMessage = _strLastErrorMessage + std::string("MessageID: ") + lexical_cast<std::string>(_uiUserMessageID) + '\n';
+
+ strStream << diagnostic_information(ex) << std::endl;
+ _strLastErrorMessage = _strLastErrorMessage + strStream.str();
+
+ _strLastErrorMessage = _strLastErrorMessage + printStackTrace();
+
+ DEBUG_TRACE1("%s\n", _strLastErrorMessage.c_str());
+ LOG_ERROR(_strLastErrorMessage);
+
+ return;
+ }
+
+ ExLog::~ExLog()
+ {
+ }
+
+ void ExLog::logInfo(std::string strInfo)
+ {
+ LOG_INFO(strInfo);
+ DEBUG_TRACE1("%s\n", strInfo.c_str());
+
+ return;
+ }
+
+ std::string ExLog::printStackTrace(unsigned int uiMaxFrame /* = 63 */)
+ {
+ /* TODO: Implement Stackwalker */
+
+ std::string strTrace;
+
+ strTrace = "Stack Trace\n";
+
+ return strTrace;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ExLog.h b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ExLog.h
new file mode 100644
index 0000000..64c8d01
--- /dev/null
+++ b/plc4cpp/utils/logger/src/main/cpp/org/apache/plc4x/cpp/utils/logger/ExLog.h
@@ -0,0 +1,71 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+#ifndef _EX_LOG_H_
+#define _EX_LOG_H_
+
+#include <boost/exception/exception.hpp>
+#include <exception>
+#include <string>
+
+namespace org
+{
+ namespace apache
+ {
+ namespace plc4x
+ {
+ namespace cpp
+ {
+ namespace utils
+ {
+ typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info;
+
+ class ExLog : public boost::exception, public std::exception
+ {
+
+ public:
+ ExLog();
+
+ virtual ~ExLog() throw();
+
+ ExLog(unsigned int uiUserMessageID, std::exception& ex, const char* pError);
+
+ ExLog(unsigned int uiUserMessageID, boost::exception& ex, const char* pError);
+
+ void logInfo(std::string strInfo);
+
+ inline unsigned int getUserMessageID() const { return _uiUserMessageID; }
+ virtual const char* what() const throw() { return _strWhat.c_str(); }
+
+ protected:
+
+ std::string printStackTrace(unsigned int max_frames = 63);
+
+ protected:
+
+ std::string _strWhat;
+ std::string _strLastErrorMessage;
+ unsigned int _uiUserMessageID;
+ };
+ }
+ }
+ }
+ }
+}
+#endif