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