~aleteoryx/muditaos

65d67e2690ffc1d619b9b7ef4f8adc842f456f23 — Alek Rudnik 4 years ago 8955a23
[EGD-7948] Extend log dumping

Log are now dumped:
* on system shutdown including hard faults and aborts
* every 5 minutes

Fixed some logs
M module-db/Interface/ThreadRecord.cpp => module-db/Interface/ThreadRecord.cpp +1 -1
@@ 196,7 196,7 @@ std::unique_ptr<db::QueryResult> ThreadRecordInterface::markAsReadQuery(const st
    auto ret              = false;

    if (record.isValid()) {
        LOG_FATAL("query-read %d", static_cast<int>(localQuery->read));
        LOG_DEBUG("query-read %d", static_cast<int>(localQuery->read));
        record.unreadMsgCount = localQuery->read == db::query::MarkAsRead::Read::True ? 0 : 1;
        ret                   = Update(record);
    }

M module-os/board/rt1051/_exit.cpp => module-os/board/rt1051/_exit.cpp +5 -1
@@ 33,6 33,7 @@
#include <FreeRTOS.h>
#include <MIMXRT1051.h>
#include <log/log.hpp>
#include <logdump/logdump.h>
#include <task.h>
#include <macros.h>
#include <stdbool.h>


@@ 43,6 44,10 @@

static void __attribute__((noreturn)) stop_system(void)
{
    if (dumpLogs() != 1) {
        LOG_ERROR("Cannot dump logs");
    }
    
    const auto err = purefs::subsystem::unmount_all();
    if(err) {
        LOG_WARN("Unable unmount all filesystems with error: %i.", err);


@@ 50,7 55,6 @@ static void __attribute__((noreturn)) stop_system(void)
        LOG_INFO("Filesystems unmounted successfully...");
    }
    LOG_INFO("Restarting the system...");
    haltIfDebugging();
    vTaskEndScheduler();
    NVIC_SystemReset();
    // waiting for system reset

M module-services/service-evtmgr/EventManager.cpp => module-services/service-evtmgr/EventManager.cpp +6 -7
@@ 62,13 62,13 @@ EventManagerSentinel::~EventManagerSentinel()
    cpuSentinel->ReleaseMinimumFrequency();
}

EventManagerCommon::EventManagerCommon(const std::string &name)
EventManagerCommon::EventManagerCommon(LogDumpFunction logDumpFunction, const std::string &name)
    : sys::Service(name, "", stackDepth), loggerTimer{sys::TimerFactory::createPeriodicTimer(
                                              this,
                                              loggerTimerName,
                                              std::chrono::milliseconds{loggerDelayMs},
                                              [this](sys::Timer & /*timer*/) { dumpLogsToFile(); })},
      settings(std::make_shared<settings::Settings>())
      logDumpFunction(logDumpFunction), settings(std::make_shared<settings::Settings>())
{
    LOG_INFO("[%s] Initializing", name.c_str());
    alarmTimestamp = 0;


@@ 301,12 301,11 @@ void EventManagerCommon::handleKeyEvent(sys::Message *msg)

int EventManagerCommon::dumpLogsToFile()
{
    const auto logPath = purefs::dir::getLogsPath() / LOG_FILE_NAME;
    const auto ts      = cpp_freertos::Ticks::TicksToMs(cpp_freertos::Ticks::GetTicks());

    LOG_DEBUG("Log flush timestamp: %d", static_cast<unsigned>(ts));
    if (logDumpFunction) {
        return logDumpFunction();
    }

    return Log::Logger::get().dumpToFile(std::move(logPath));
    return 0;
}

void EventManagerCommon::handleMinuteUpdate(time_t timestamp)

M module-services/service-evtmgr/service-evtmgr/EventManagerCommon.hpp => module-services/service-evtmgr/service-evtmgr/EventManagerCommon.hpp +30 -26
@@ 35,6 35,29 @@ class EventManagerSentinel

class EventManagerCommon : public sys::Service
{
  public:
    using LogDumpFunction = std::function<int()>;

    explicit EventManagerCommon(LogDumpFunction logDumpFunction, const std::string &name = service::name::evt_manager);
    ~EventManagerCommon() override;

    sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) override;

    // Invoked during initialization
    sys::ReturnCodes InitHandler() final;

    sys::ReturnCodes DeinitHandler() override;

    void ProcessCloseReason(sys::CloseReason closeReason) override;

    sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override final;

    /**
     * @brief Sends request to application manager to switch from current application to specific window in application
     * with specified name .
     */
    static bool messageSetApplication(sys::Service *sender, const std::string &applicationName);

  private:
    static constexpr auto stackDepth = 4096;
    void handleMinuteUpdate(time_t timestamp);


@@ 45,6 68,13 @@ class EventManagerCommon : public sys::Service

    sys::TimerHandle loggerTimer;

    LogDumpFunction logDumpFunction;

    /// @return: < 0 - error occured during log flush
    /// @return:   0 - log flush did not happen
    /// @return:   1 - log flush successflul
    int dumpLogsToFile();

  protected:
    std::function<void(const time_t)> onMinuteTick;
    virtual void handleKeyEvent(sys::Message *msg);


@@ 61,30 91,4 @@ class EventManagerCommon : public sys::Service
    uint32_t alarmTimestamp;
    // ID of alarm waiting to trigger
    uint32_t alarmID;

  public:
    explicit EventManagerCommon(const std::string &name = service::name::evt_manager);
    ~EventManagerCommon();

    sys::MessagePointer DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp) override;

    // Invoked during initialization
    sys::ReturnCodes InitHandler() final;

    sys::ReturnCodes DeinitHandler() override;

    void ProcessCloseReason(sys::CloseReason closeReason) override;

    sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override final;

    /// @return: < 0 - An error occurred during log flush
    /// @return:   0 - Log file reached max size
    /// @return:   1 - Logs flushed successflully
    int dumpLogsToFile();

    /**
     * @brief Sends request to application manager to switch from current application to specific window in application
     * with specified name .
     */
    static bool messageSetApplication(sys::Service *sender, const std::string &applicationName);
};

M module-sys/SystemManager/SystemManagerCommon.cpp => module-sys/SystemManager/SystemManagerCommon.cpp +49 -22
@@ 101,6 101,47 @@ namespace sys
        LOG_DEBUG("%s", (GetName() + ":destructor").c_str());
    }

    void SystemManagerCommon::LogPowerOffReason()
    {
        // Power off system
        switch (state) {
        case SystemManagerCommon::State::Reboot:
            LOG_INFO("  --->  REBOOT <--- ");
            break;
        case SystemManagerCommon::State::ShutdownReady:
            LOG_INFO("  ---> SHUTDOWN <--- ");
            break;
        case SystemManagerCommon::State::RebootToUpdate:
            LOG_INFO("  ---> REBOOT TO UPDATER <--- ");
            break;
        case SystemManagerCommon::State::Running:
        case SystemManagerCommon::State::Suspend:
        case SystemManagerCommon::State::Shutdown:
            LOG_FATAL("State changed after reset/shutdown was requested to: %s! this is terrible failure!",
                      c_str(state));
            break;
        }
    }

    void SystemManagerCommon::PowerOff()
    {
        switch (state) {
        case State::Reboot:
            powerManager->Reboot();
            break;
        case State::ShutdownReady:
            powerManager->PowerOff();
            break;
        case State::RebootToUpdate:
            powerManager->RebootToUpdate(updateReason);
            break;
        case SystemManagerCommon::State::Running:
        case SystemManagerCommon::State::Suspend:
        case SystemManagerCommon::State::Shutdown:
            exit(1);
        }
    }

    void SystemManagerCommon::Run()
    {
        initialize();


@@ 132,34 173,19 @@ namespace sys
        }

        DestroySystemService(service::name::evt_manager, this);

        CloseService();

        EndScheduler();
        // it should be called before systemDeinit to make sure this log is dumped to the file
        LogPowerOffReason();

        if (systemDeinit) {
            systemDeinit();
        }

        EndScheduler();

        // Power off system
        switch (state) {
        case State::Reboot:
            LOG_INFO("  --->  REBOOT <--- ");
            powerManager->Reboot();
            break;
        case State::ShutdownReady:
            LOG_INFO("  ---> SHUTDOWN <--- ");
            powerManager->PowerOff();
            break;
        case State::RebootToUpdate:
            LOG_INFO("  ---> REBOOT TO UPDATER <--- ");
            powerManager->RebootToUpdate(updateReason);
            break;
        default:
            LOG_FATAL("State changed after reset/shutdown was requested to: %s! this is terrible failure!",
                      c_str(state));
            exit(1);
        }
        PowerOff();
    }

    void SystemManagerCommon::initialize()


@@ 323,11 349,12 @@ namespace sys
        auto resp = std::static_pointer_cast<ResponseMessage>(ret.second);

        if (ret.first != ReturnCodes::Success) {
            LOG_ERROR("Service to close: %s did not respond", name.c_str());
            LOG_ERROR("Service to close: %s did not respond, error code %d", name.c_str(), static_cast<int>(ret.first));
            return false;
        }
        else if (resp->retCode != ReturnCodes::Success) {
            LOG_ERROR("Service %s noticed failure at close", name.c_str());
            LOG_ERROR(
                "Service %s noticed failure at close, error code %d", name.c_str(), static_cast<int>(resp->retCode));
            return false;
        }
        return true;

M module-sys/SystemManager/include/SystemManager/SystemManagerCommon.hpp => module-sys/SystemManager/include/SystemManager/SystemManagerCommon.hpp +4 -0
@@ 148,6 148,10 @@ namespace sys

        void Run() override;

        void LogPowerOffReason();

        void PowerOff();

        void StartSystemServices();

        static bool RunService(std::shared_ptr<Service> service, Service *caller, TickType_t timeout = 5000);

M module-utils/log/CMakeLists.txt => module-utils/log/CMakeLists.txt +1 -1
@@ 2,6 2,7 @@ add_library(log STATIC)

add_subdirectory(api)
add_subdirectory(board)
add_subdirectory(logdump)

target_sources(log
    PRIVATE


@@ 16,7 17,6 @@ target_include_directories(log PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(log
    PRIVATE
        utility
        purefs-paths
    PUBLIC
        module-os
        log-api

A module-utils/log/logdump/CMakeLists.txt => module-utils/log/logdump/CMakeLists.txt +19 -0
@@ 0,0 1,19 @@
add_library(logdump STATIC)

target_sources(logdump
    PRIVATE
        logdump.cpp
    PUBLIC
        include/logdump/logdump.h
)

target_include_directories(logdump
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
)

target_link_libraries(logdump
    PRIVATE
        purefs-paths
        log
)

A module-utils/log/logdump/include/logdump/logdump.h => module-utils/log/logdump/include/logdump/logdump.h +17 -0
@@ 0,0 1,17 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#ifdef __cplusplus
extern "C"
{
#endif
    /// @return: < 0 - error occurred during log flush
    /// @return:   0 - log flush did not happen
    /// @return:   1 - log flush successful
    int dumpLogs();

#ifdef __cplusplus
}
#endif

A module-utils/log/logdump/logdump.cpp => module-utils/log/logdump/logdump.cpp +11 -0
@@ 0,0 1,11 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <logdump/logdump.h>
#include <purefs/filesystem_paths.hpp>
#include <Logger.hpp>

int dumpLogs()
{
    return Log::Logger::get().dumpToFile(purefs::dir::getLogsPath() / LOG_FILE_NAME);
}

M products/BellHybrid/BellHybridMain.cpp => products/BellHybrid/BellHybridMain.cpp +7 -3
@@ 31,13 31,14 @@

#include <Application.hpp>
#include <ApplicationLauncher.hpp>
#include <Logger.hpp>
#include <log/log.hpp>
#include <logdump/logdump.h>
#include <Logger.hpp>
#include <product/version.hpp>
#include <sys/SystemManager.hpp>
#include <time/AlarmOperations.hpp>
#include <SystemWatchdog/SystemWatchdog.hpp>
#include <thread.hpp>
#include <time/AlarmOperations.hpp>

#include <memory>
#include <vector>


@@ 66,7 67,7 @@ int main()
    }

    std::vector<std::unique_ptr<sys::BaseServiceCreator>> systemServices;
    systemServices.emplace_back(sys::CreatorFor<EventManager>());
    systemServices.emplace_back(sys::CreatorFor<EventManager>([]() { return dumpLogs(); }));
    systemServices.emplace_back(sys::CreatorFor<ServiceDB>());
    systemServices.emplace_back(sys::CreatorFor<service::Audio>());
    systemServices.emplace_back(sys::CreatorFor<ServiceDesktop>());


@@ 116,6 117,9 @@ int main()
        [&platform] {
            try {
                LOG_DEBUG("System deinit");
                if (dumpLogs() != 1) {
                    LOG_ERROR("Cannot dump logs");
                }
                platform->deinit();
            }
            catch (const std::runtime_error &e) {

M products/BellHybrid/CMakeLists.txt => products/BellHybrid/CMakeLists.txt +1 -0
@@ 52,6 52,7 @@ target_link_libraries(BellHybrid
        bell::audio
        bell::evtmgr
        log
        logdump
        messagetype
        module-bsp
        module-vfs

M products/BellHybrid/services/evtmgr/EventManager.cpp => products/BellHybrid/services/evtmgr/EventManager.cpp +4 -3
@@ 36,8 36,9 @@ namespace
    };
}

EventManager::EventManager(const std::string &name)
    : EventManagerCommon(name), temperatureSource{hal::temperature::AbstractTemperatureSource::Factory::create()},
EventManager::EventManager(LogDumpFunction logDumpFunction, const std::string &name)
    : EventManagerCommon(logDumpFunction, name),
      temperatureSource{hal::temperature::AbstractTemperatureSource::Factory::create()},
      backlightHandler(settings, this), userActivityHandler(std::make_shared<sys::CpuSentinel>(name, this), this)
{
    buildKeySequences();


@@ 73,7 74,7 @@ void EventManager::initProductEvents()
    backlightHandler.init();

    connect(typeid(sevm::ScreenLightControlMessage), [&](sys::Message *msgl) {
        auto *m = static_cast<sevm::ScreenLightControlMessage *>(msgl);
        auto *m           = static_cast<sevm::ScreenLightControlMessage *>(msgl);
        const auto params = m->getParams();
        backlightHandler.processScreenRequest(m->getAction(), params.value_or(screen_light_control::Parameters()));
        return sys::msgHandled();

M products/BellHybrid/services/evtmgr/include/evtmgr/EventManager.hpp => products/BellHybrid/services/evtmgr/include/evtmgr/EventManager.hpp +2 -1
@@ 18,7 18,8 @@ namespace hal::temperature
class EventManager : public EventManagerCommon
{
  public:
    explicit EventManager(const std::string &name = service::name::evt_manager);
    explicit EventManager(LogDumpFunction logDumpFunction = nullptr,
                          const std::string &name         = service::name::evt_manager);

  private:
    void handleKeyEvent(sys::Message *msg) override;

M products/PurePhone/CMakeLists.txt => products/PurePhone/CMakeLists.txt +1 -0
@@ 63,6 63,7 @@ target_link_libraries(PurePhone
        db
        evtmgr
        log
        logdump
        messagetype
        module-apps
        module-bsp

M products/PurePhone/PurePhoneMain.cpp => products/PurePhone/PurePhoneMain.cpp +6 -2
@@ 60,12 60,13 @@
#include <Application.hpp>
#include <ApplicationLauncher.hpp>
#include <log/log.hpp>
#include <logdump/logdump.h>
#include <Logger.hpp>
#include <product/version.hpp>
#include <sys/SystemManager.hpp>
#include <time/AlarmOperations.hpp>
#include <SystemWatchdog/SystemWatchdog.hpp>
#include <thread.hpp>
#include <time/AlarmOperations.hpp>

#include <memory>
#include <vector>


@@ 94,7 95,7 @@ int main()
    }

    std::vector<std::unique_ptr<sys::BaseServiceCreator>> systemServices;
    systemServices.emplace_back(sys::CreatorFor<EventManager>());
    systemServices.emplace_back(sys::CreatorFor<EventManager>([]() { return dumpLogs(); }));
    systemServices.emplace_back(sys::CreatorFor<service::ServiceFileIndexer>());
    systemServices.emplace_back(sys::CreatorFor<ServiceDB>());
#if ENABLE_GSM == 0


@@ 189,6 190,9 @@ int main()
        [&platform] {
            try {
                LOG_DEBUG("System deinit");
                if (dumpLogs() != 1) {
                    LOG_ERROR("Cannot dump logs");
                }
                platform->deinit();
            }
            catch (const std::runtime_error &e) {

M products/PurePhone/services/evtmgr/include/evtmgr/EventManager.hpp => products/PurePhone/services/evtmgr/include/evtmgr/EventManager.hpp +3 -2
@@ 12,8 12,9 @@
class EventManager : public EventManagerCommon
{
  public:
    explicit EventManager(const std::string &name = service::name::evt_manager)
        : EventManagerCommon(name), vibrator(std::make_unique<vibra_handle::Vibra>(this)),
    explicit EventManager(LogDumpFunction logDumpFunction = nullptr,
                          const std::string &name         = service::name::evt_manager)
        : EventManagerCommon(logDumpFunction, name), vibrator(std::make_unique<vibra_handle::Vibra>(this)),
          backlightHandler(settings, this)
    {}


M products/PurePhone/test/test-settings/test-service-db-settings-api.cpp => products/PurePhone/test/test-settings/test-service-db-settings-api.cpp +1 -2
@@ 57,8 57,7 @@ TEST_CASE("SettingsApi")
                testStart = std::make_shared<std::mutex>();
                testStart->lock();
                std::cout << "start thr_id: " << std::this_thread::get_id() << std::endl << std::flush;
                auto ret = sys::SystemManagerCommon::RunSystemService(
                    std::make_shared<EventManager>(service::name::evt_manager), manager.get());
                auto ret = sys::SystemManagerCommon::RunSystemService(std::make_shared<EventManager>(), manager.get());
                ret &= sys::SystemManagerCommon::RunSystemService(std::make_shared<ServiceDB>(), manager.get());

                varWritter = std::make_shared<settings::MyService>("writterVar");