DLT context is like not initialized

25 Views Asked by At

I have a dlt logger. I created a singleton so I have only once instance of the logger. The header:

#pragma once

#include <dlt/dlt.h>
#include <string>
#include <mutex>
#include <thread>
#include <memory>


enum LevelImportance : int
{
    DEBUG = 0,
    INFO,
    WARN,
    ERROR,
    FATAL
};

class DltLogger
{
public:

    /**
     * Singletons should not be cloneable.
     */
    DltLogger(DltLogger &other) = delete;
    
    /**
     * Singletons should not be assignable.
     */
    void operator=(const DltLogger &) = delete;

    /**
     * This is the static method that controls the access to the singleton
     * instance. On the first run, it creates a singleton object and places it
     * into the static field. On subsequent runs, it returns the client existing
     * object stored in the static field.
     */
    static DltLogger* GetInstance();

    /**
     * @brief It logs a message depending on the level of importance.
     * @param [in] level the level of importance
     * @param [in] name_function The name of the function it has came from.
     * @param [in] message message to log.
    */
    void logMessage(const LevelImportance &level,const std::string &name_function, const std::string &message);
    
    /**
     * @brief It logs a debug message.
     * @param [in] name_function The name of the function it has came from.
     * @param [in] message message to log.
    */
    void logDebug(const std::string &name_function, const std::string &message);
    
    /**
     * @brief It logs an informative message.
     * @param [in] name_function The name of the function it has came from.
     * @param [in] message message to log.
    */
    void logInfo(const std::string &name_function, const std::string &message);
        
    /**
     * @brief It logs a warning message.
     * @param [in] name_function The name of the function it has came from.
     * @param [in] message message to log.
    */
    void logWarn(const std::string &name_function, const std::string &message);
      
    /**
     * @brief It logs an error message.
     * @param [in] name_function The name of the function it has came from.
     * @param [in] message message to log.
    */
    void logError(const std::string &name_function, const std::string &message);
    
    /**
     * @brief It logs a fatal error message.
     * @param [in] name_function The name of the function it has came from.
     * @param [in] message message to log.
    */
    void logFatal(const std::string &name_function, const std::string &message);
    
    /**
     * @brief It starts the dlt-receiver process and initialice the context
    */
    void startLog();
    
    /**
     * @brief It stops the dlt-receiver process
    */
    void stopLog();
    
    /**
     * @brief It returns if the the dlt-receiver process is running.
    */
    bool isStarted();

    /**
     * @brief It set the context of the dlt.
     * @param [in] context the context
    */
    //void setContext(DltContext &context);
    
protected:

    /**
     * @brief It starts the dlt-receiver (it calls startLog)
    */
    DltLogger();

    /**
     * @brief It stops the dlt-receiver (it calls stopLog)
    */
    ~DltLogger();

private:
    /**
     * @brief It reads the configuration file and gets the ouput path.
    */
    std::string getOutputPath();
    
    static DltLogger* instance_;
    static std::mutex mutex_;
    DltContext context_;
    std::thread receiver_thread_;

    bool started_ {false};
    int dltReceiverPID_ {0};
};

The cpp:

#include "DltLogger.h"

#include "IniFileReader.h"

#include <filesystem>
#include <chrono>
#include <ctime>
#include <iomanip>
#include <cstdio>


std::mutex DltLogger::mutex_;
DltLogger* DltLogger::instance_ = nullptr;

DltLogger *DltLogger::GetInstance()
{
    std::lock_guard<std::mutex> lock(mutex_);
    if (instance_ == nullptr)
    {
        instance_ = new DltLogger();
    }
    return instance_;
}

void DltLogger::logMessage(const LevelImportance &level,const std::string &name_function, const std::string &message)
{
    switch(level)
    {
        case DEBUG:
        {
            logDebug(name_function, message);
            break;
        }
        case INFO:
        {
            logInfo(name_function, message);
            break;
        }
        case WARN:
        {
            logWarn(name_function, message);
            break;
        }
        case ERROR:
        {
            logError(name_function, message);
            break;
        }
        case FATAL:
        {
            logFatal(name_function, message);
            break;
        }
        default:
            logWarn("DltLogger::logMessage", "Level of importance doesn't exist");
    }
}


void DltLogger::logDebug(const std::string &name_function, const std::string &message)
{
    std::string msg = name_function + ". " + message;
    DLT_LOG(context_, DLT_LOG_DEBUG, DLT_CSTRING(msg.c_str()));
}

void DltLogger::logInfo(const std::string &name_function, const std::string &message)
{
    std::string msg = name_function + ". " + message;
    DLT_LOG(context_, DLT_LOG_INFO, DLT_CSTRING(msg.c_str()));
}

void DltLogger::logWarn(const std::string &name_function, const std::string &message)
{
    std::string msg = name_function + ". " + message;
    DLT_LOG(context_, DLT_LOG_WARN, DLT_CSTRING(msg.c_str()));
}

void DltLogger::logError(const std::string &name_function, const std::string &message)
{
    std::string msg = name_function + ". " + message;
    DLT_LOG(context_, DLT_LOG_ERROR, DLT_CSTRING(msg.c_str()));
}

void DltLogger::logFatal(const std::string &name_function, const std::string &message)
{
    std::string msg = name_function + ". " + message;
    DLT_LOG(context_, DLT_LOG_FATAL, DLT_CSTRING(msg.c_str()));
}
    
void DltLogger::startLog()
{
    if(started_)
    {
        return;
    }

    std::string out_path = getOutputPath();
    // Get the current time point
    auto currentTime = std::chrono::system_clock::now();

    // Convert the time point to a time_t object
    std::time_t currentTime_t = std::chrono::system_clock::to_time_t(currentTime);

    // Convert time_t to a tm structure (broken down time)
    std::tm* currentTimeInfo = std::localtime(&currentTime_t);

    // Format the time as a string
    std::ostringstream oss;
    oss << std::put_time(currentTimeInfo, "%d-%m-%Y_%H-%M-%S");

    std::string timestampString = oss.str();

    std::string out_name = "Middleware-" + timestampString + ".dlt";

        std::string command {"dlt-receive -o "+ out_path+"/"+ out_name + " localhost & echo $!"};

        FILE* p = popen(command.c_str(), "r");
        if (p) {
            char buf[128];
            if (fgets(buf, sizeof(buf), p) != nullptr) {
                dltReceiverPID_ = atoi(buf);
            }
            pclose(p);
        }

        if (dltReceiverPID_ > 0) {
            started_ = true;

                DLT_REGISTER_APP("MiddlewareApp", "Middelware");
                DLT_DECLARE_CONTEXT(context_); /* declare context */
                DLT_REGISTER_CONTEXT(context_, "Mid", "Middleware Context for Logging");

        } else {
            std::cerr << "DltLogger::startLog. Error starting dlt-receive." << std::endl;
        }

}

void DltLogger::stopLog()
{
    if(!started_)
    {
        return;
    }
    if(context_.contextID == "Mid")
    {
      // if I don't put this check, it has a segmentation fault

        DLT_UNREGISTER_CONTEXT(context_); 
    }
    DLT_UNREGISTER_APP();

    int result = std::system(("kill " + std::to_string(dltReceiverPID_)).c_str());
    if(result != 0)
    {
        std::cerr << "DltLogger:~DltLogger. Error stopping dlt-receive." << std::endl;
    }
    else
    {
        started_ = false;
    }

    
}

bool DltLogger::isStarted()
{
    return started_;
}

// void DltLogger::setContext(DltContext &context)
// {
//     context_ = context;
// }

DltLogger::DltLogger()
{
    startLog();

}

DltLogger::~DltLogger()
{
    stopLog();
    if (instance_ != nullptr)
    {
        instance_ = nullptr;
    }
}

std::string DltLogger::getOutputPath()
{
    std::string out_path{};
    try
    {
        //The path is where it is the binary.
        std::filesystem::path currentPath = std::filesystem::current_path();
        std::string path = currentPath.string() + "/configurationFiles/loggerConfig.ini";
        auto data_of_section = getValuesOfSection(path, "dltlogger");
        out_path = getValueFromKey<std::string>(data_of_section, "out_path", currentPath.string());
    
    }
    catch(const std::exception& e)
    {
        std::cerr << "ServerManager::getPort(). " << e.what() << std::endl;
    }

    return out_path;
}

As you can see I have a DltContext variable in my class. I use it as the context to register and unregister the dlt context for the logger. The problem is that when it reaches at the stopLog() the line to unregister, the context is not initialized so it doesn't unregister it and the dlt file is not completed (some messages are missing).

How can I do the dlt process to register the context?

Thanks in advance.

0

There are 0 best solutions below