diff --git a/include/log.h b/include/log.h
new file mode 100644
index 0000000000000000000000000000000000000000..0c299b9dbf6d473a22008c9825e2859398f411b6
--- /dev/null
+++ b/include/log.h
@@ -0,0 +1,168 @@
+/*!
+    @file
+    @date 18.01.2019
+    @author Raphael Bach
+    @copyright
+
+The MIT License (MIT)
+
+Copyright (c) 2019 Raphael Bach
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+    @brief
+    @details
+*/
+/*==============================================================================
+    GUARD
+==============================================================================*/
+#ifndef LOG_H_20190119152151
+#define LOG_H_20190119152151
+/*==============================================================================
+    INCLUDE
+==============================================================================*/
+// C Standard Library
+#include <stdbool.h>
+#include <stdio.h> // FILE, size_t
+/*==============================================================================
+    ENUM
+==============================================================================*/
+/*------------------------------------------------------------------------------
+    LogLevel
+------------------------------------------------------------------------------*/
+enum LogLevel
+{
+    LOG_LEVEL_NONE    = 0x00, // 0000 0000
+    LOG_LEVEL_TRACE   = 0x01, // 0000 0001
+    LOG_LEVEL_DEBUG   = 0x02, // 0000 0010
+    LOG_LEVEL_INFO    = 0x04, // 0000 0100
+    LOG_LEVEL_WARNING = 0x08, // 0000 1000
+    LOG_LEVEL_ERROR   = 0x10, // 0001 0000
+    LOG_LEVEL_FATAL   = 0x20, // 0010 0000
+    LOG_LEVEL_ALL     = 0x3F  // 0011 1111
+};
+/*------------------------------------------------------------------------------
+    rtw_log_Output
+------------------------------------------------------------------------------*/
+enum LogOutput
+{
+    LOG_OUTPUT_NONE   = 0x00, // 0000 0000
+    LOG_OUTPUT_STDERR = 0x01, // 0000 0001
+    LOG_OUTPUT_STDOUT = 0x02, // 0000 0010
+    LOG_OUTPUT_FILE   = 0x04  // 0000 0100
+};
+/*==============================================================================
+    STRUCT
+==============================================================================*/
+/*------------------------------------------------------------------------------
+    Logger
+------------------------------------------------------------------------------*/
+struct Logger
+{
+    enum LogLevel level_flag; // Levels allowed
+    enum LogOutput output;
+};
+/*==============================================================================
+    MACRO
+==============================================================================*/
+/*------------------------------------------------------------------------------
+   Log_Trace()
+------------------------------------------------------------------------------*/
+#define Log_Trace(logger, ...)                                                 \
+do {                                                                           \
+    if(Log_IsLevelSet(logger, LOG_LEVEL_TRACE) == true) {                      \
+        logger_write(logger, LOG_LEVEL_TRACE,                                  \
+                     __FILE__, __LINE__, __func__, __VA_ARGS__);               \
+    }                                                                          \
+} while(0)
+/*------------------------------------------------------------------------------
+   Log_Debug()
+------------------------------------------------------------------------------*/
+#define Log_Debug(logger, ...)                                                 \
+do {                                                                           \
+    if(Log_IsLevelSet(logger, LOG_LEVEL_DEBUG) == true) {                      \
+        logger_write(logger, LOG_LEVEL_DEBUG,                                  \
+                     __FILE__, __LINE__, __func__, __VA_ARGS__);               \
+    }                                                                          \
+} while(0)
+/*------------------------------------------------------------------------------
+   Log_Info()
+------------------------------------------------------------------------------*/
+#define Log_Info(logger, ...)                                                  \
+do {                                                                           \
+    if(Log_IsLevelSet(logger, LOG_LEVEL_INFO) == true) {                       \
+        logger_write(logger, LOG_LEVEL_INFO,                                   \
+                     __FILE__, __LINE__, __func__, __VA_ARGS__);               \
+    }                                                                          \
+} while(0)
+/*------------------------------------------------------------------------------
+   Log_Warning()
+------------------------------------------------------------------------------*/
+#define Log_Warning(logger, ...)                                               \
+do {                                                                           \
+    if(Log_IsLevelSet(logger, LOG_LEVEL_WARNING) == true) {                    \
+        logger_write(logger, LOG_LEVEL_WARNING,                                \
+                     __FILE__, __LINE__, __func__, __VA_ARGS__);               \
+    }                                                                          \
+} while(0)
+/*------------------------------------------------------------------------------
+   Log_Error()
+------------------------------------------------------------------------------*/
+#define Log_Error(logger, ...)                                                 \
+do {                                                                           \
+    if(Log_IsLevelSet(logger, LOG_LEVEL_ERROR) == true) {                      \
+        logger_write(logger, LOG_LEVEL_ERROR,                                  \
+                     __FILE__, __LINE__, __func__, __VA_ARGS__);               \
+    }                                                                          \
+} while(0)
+/*------------------------------------------------------------------------------
+   Log_Fatal()
+------------------------------------------------------------------------------*/
+#define Log_Fatal(logger, ...)                                                 \
+do {                                                                           \
+    if(Log_IsLevelSet(logger, LOG_LEVEL_FATAL) == true) {                      \
+        logger_write(logger, LOG_LEVEL_FATAL,                                  \
+                     __FILE__, __LINE__, __func__, __VA_ARGS__);               \
+    }                                                                          \
+} while(0)
+/*==============================================================================
+    PUBLIC FUNCTION
+==============================================================================*/
+/*------------------------------------------------------------------------------
+    Log_IsLevelSet()
+------------------------------------------------------------------------------*/
+_Bool Log_IsLevelSet(const struct Logger * const logger, enum LogLevel level);
+/*==============================================================================
+    PRIVATE FUNCTION
+==============================================================================*/
+/*------------------------------------------------------------------------------
+    logger_write()
+------------------------------------------------------------------------------*/
+void logger_write
+(
+    const struct Logger * const logger,
+    enum LogLevel level               ,
+    const char * const file           ,
+    size_t line                       ,
+    const char * const function       ,
+    const char * const message        , ...
+);
+/*==============================================================================
+    GUARD
+==============================================================================*/
+#endif // LOG_H_20190119152151
diff --git a/makefile b/makefile
index b0f983fb0c28b6324ccf270871215182809e163c..b26b8b615649177f97a8897a4cfc8e68790a6e87 100644
--- a/makefile
+++ b/makefile
@@ -199,11 +199,13 @@ LFLAGS += -o ./$@.out
 ################################################################################
 SPARSE2IMG_DEP :=                                                              \
     sparse2img.o \
-    sparse.o
+    sparse.o \
+    log.o
 
 IMG2SPARSE_DEP :=                                                              \
     img2sparse.o \
-    sparse.o
+    sparse.o \
+    log.o
 
 SPARSE2IMG_OBJ_LIST_PATH := $(addprefix $(OBJECT_PATH)/, $(SPARSE2IMG_DEP))
 IMG2SPARSE_OBJ_LIST_PATH := $(addprefix $(OBJECT_PATH)/, $(IMG2SPARSE_DEP))
@@ -213,7 +215,10 @@ S2I_DEP :=                                                                     \
 I2S_DEP :=                                                                     \
     $(SOURCE_FOLDER)/img2sparse.c
 SPARSE_DEP :=                                                                  \
-    $(SOURCE_FOLDER)/sparse.c
+    $(SOURCE_FOLDER)/sparse.c                                                  \
+    $(HEADER_FOLDER)/log.h
+LOG_DEP :=                                                                     \
+    $(SOURCE_FOLDER)/log.c
 ################################################################################
 # OBJECT TARGET
 ################################################################################
@@ -229,6 +234,8 @@ img2sparse.o: $(I2S_DEP)
 	$(CFLAGS)
 sparse.o: $(SPARSE_DEP)
 	$(CFLAGS)
+log.o: $(LOG_DEP)
+	$(CFLAGS)
 
 .PHONY: all
 all: sparse2img img2sparse
diff --git a/src/log.c b/src/log.c
new file mode 100644
index 0000000000000000000000000000000000000000..72be1970e5f297107e364fc99d36351a4ea81d46
--- /dev/null
+++ b/src/log.c
@@ -0,0 +1,119 @@
+/*!
+    @file
+    @date 18.01.2019
+    @author Raphael Bach
+    @copyright
+
+The MIT License (MIT)
+
+Copyright (c) 2019 Raphael Bach
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+    @brief
+    @details
+*/
+/*==============================================================================
+    INCLUDE
+==============================================================================*/
+// Own header
+#include "log.h"
+// C Standard Library
+#include <assert.h>
+#include <stdarg.h>  // vsprintf(), va_list, va_start(), va_end()
+#include <stdbool.h>
+#include <stdio.h>   // sprintf(), fprintf(), NULL, FILE
+#include <time.h>    // time(), localtime(), time_t, struct tm
+/*==============================================================================
+    DEFINE
+==============================================================================*/
+#define LOG_MESSAGE_MAX_LENGTH 512
+#define LOG_MAX_LENGTH 1024
+/*==============================================================================
+    STATIC
+==============================================================================*/
+static const char * const s_level_name[] =
+{
+    [LOG_LEVEL_TRACE]   = "TRACE"  ,
+    [LOG_LEVEL_DEBUG]   = "DEBUG"  ,
+    [LOG_LEVEL_INFO]    = "INFO"   ,
+    [LOG_LEVEL_WARNING] = "WARNING",
+    [LOG_LEVEL_ERROR]   = "ERROR"  ,
+    [LOG_LEVEL_FATAL]   = "FATAL"  ,
+};
+/*==============================================================================
+    PUBLIC FUNCTION DEFINITION
+==============================================================================*/
+/*------------------------------------------------------------------------------
+    Log_IsLevelSet()
+------------------------------------------------------------------------------*/
+_Bool Log_IsLevelSet(const struct Logger * const logger, enum LogLevel level)
+{
+    assert(logger != NULL);
+    _Bool result = false;
+    if((logger->level_flag & level) == level) {
+        result = true;
+    }
+    return result;
+}
+/*==============================================================================
+    PRIVATE FUNCTION DEFINITION
+==============================================================================*/
+/*------------------------------------------------------------------------------
+    logger_write()
+------------------------------------------------------------------------------*/
+void logger_write
+(
+    const struct Logger * const logger,
+    enum LogLevel level               ,
+    const char * const file           ,
+    size_t line                       ,
+    const char * const function       ,
+    const char * const message        , ...
+)
+{
+    assert(logger   != NULL);
+    assert(file     != NULL);
+    assert(function != NULL);
+    assert(message  != NULL);
+
+    char message_buffer[LOG_MESSAGE_MAX_LENGTH];
+
+    va_list args;
+    va_start(args, message);
+    vsprintf(message_buffer, message, args);
+    va_end(args);
+
+    struct tm *actual_time;
+    time_t raw_time;
+    time(&raw_time);
+    actual_time = localtime(&raw_time);
+
+    char log[LOG_MAX_LENGTH];
+    sprintf(log, "%02d:%02d:%02d - %s:%zu:%s() - [%s] : %s",
+        actual_time->tm_hour, actual_time->tm_min, actual_time->tm_sec,
+        file, line, function, s_level_name[level], message_buffer);
+
+    FILE * output = NULL;
+    if(logger->output == LOG_OUTPUT_STDERR) {
+        output = stderr;
+    } else if(logger->output == LOG_OUTPUT_STDOUT) {
+        output = stdout;
+    }
+    fprintf(output, "%s", log);
+}