~aleteoryx/muditaos

e7776f6c1790f3064d47c7a3a95e5a71119e9a52 — Marek Niepieklo 4 years ago d31e1c2
[CP-228] Force flushing of logs before getting log files

Moved flushing function to Logger class
Decreased flushing time to 2 min
Added EM event to request flushing from ServiceDesktop
M module-services/service-desktop/ServiceDesktop.cpp => module-services/service-desktop/ServiceDesktop.cpp +21 -0
@@ 18,6 18,8 @@
#include <application-desktop/Constants.hpp>
#include <service-db/service-db/Settings.hpp>
#include <service-db/QueryMessage.hpp>
#include <service-evtmgr/EventManager.hpp>
#include <service-evtmgr/EVMessages.hpp>
#include <purefs/filesystem_paths.hpp>
#include <module-sys/SystemManager/SystemManager.hpp>
#include <module-sys/Timers/TimerFactory.hpp>


@@ 81,6 83,25 @@ auto ServiceDesktop::getSerialNumber() const -> std::string
    return settings->getValue(std::string("factory_data/serial"), settings::SettingsScope::Global);
}

auto ServiceDesktop::requestLogsFlush() -> void
{
    int response = 0;
    auto ret     = bus.sendUnicastSync(
        std::make_shared<sevm::FlushLogsRequest>(), service::name::evt_manager, DefaultLogFlushTimeoutInMs);

    if (ret.first == sys::ReturnCodes::Success) {
        auto responseMsg = std::dynamic_pointer_cast<sevm::FlushLogsResponse>(ret.second);
        if ((responseMsg != nullptr) && (responseMsg->retCode == true)) {
            response = responseMsg->data;

            LOG_DEBUG("Respone data: %d", response);
        }
    }
    if (ret.first == sys::ReturnCodes::Failure || response < 0) {
        throw std::runtime_error("Logs flush failed");
    }
}

sys::ReturnCodes ServiceDesktop::InitHandler()
{


M module-services/service-desktop/endpoints/filesystem/FilesystemEndpoint.cpp => module-services/service-desktop/endpoints/filesystem/FilesystemEndpoint.cpp +19 -0
@@ 38,10 38,29 @@ static bool isWritable(const fs::path &file)
    return static_cast<bool>(sf);
}

auto FilesystemEndpoint::requestLogsFlush() const -> void
{
    auto owner = dynamic_cast<ServiceDesktop *>(ownerServicePtr);
    if (owner) {
        owner->requestLogsFlush();
    }
}

auto FilesystemEndpoint::startGetFile(Context &context) const -> sys::ReturnCodes
{
    std::filesystem::path filePath = context.getBody()[parserFSM::json::fileName].string_value();

    try {
        requestLogsFlush();
    }
    catch (const std::runtime_error &e) {
        LOG_ERROR("Logs flush exception: %s", e.what());

        context.setResponseStatus(parserFSM::http::Code::InternalServerError);
        context.setResponseBody(json11::Json::object({{json::reason, std::string(e.what())}}));
        return sys::ReturnCodes::Failure;
    }

    if (!std::filesystem::exists(filePath)) {
        LOG_ERROR("file not found");


M module-services/service-desktop/endpoints/filesystem/FilesystemEndpoint.hpp => module-services/service-desktop/endpoints/filesystem/FilesystemEndpoint.hpp +2 -0
@@ 31,5 31,7 @@ class FilesystemEndpoint : public parserFSM::Endpoint
    auto startSendFile(parserFSM::Context &context) const -> sys::ReturnCodes;
    auto sendFileChunk(parserFSM::Context &context) const -> sys::ReturnCodes;

    auto requestLogsFlush() const -> void;

    FileOperations &fileOps;
};

M module-services/service-desktop/service-desktop/ServiceDesktop.hpp => module-services/service-desktop/service-desktop/ServiceDesktop.hpp +4 -0
@@ 109,12 109,16 @@ class ServiceDesktop : public sys::Service
        return usbSecurityModel.get();
    }

    auto requestLogsFlush() -> void;

  private:
    auto getSerialNumber() const -> std::string;
    std::unique_ptr<sdesktop::USBSecurityModel> usbSecurityModel;
    std::unique_ptr<settings::Settings> settings;
    sys::TimerHandle transferTimer;
    std::unique_ptr<sdesktop::bluetooth::BluetoothMessagesHandler> btMsgHandler;

    static constexpr unsigned int DefaultLogFlushTimeoutInMs = 1000U;
};

namespace sys

M module-services/service-evtmgr/EventManager.cpp => module-services/service-evtmgr/EventManager.cpp +16 -9
@@ 45,11 45,12 @@
#include <EventStore.hpp>
#include <SystemManager/messages/PhoneModeRequest.hpp>
#include <vibra/Vibra.hpp>
#include <ticks.hpp>

namespace
{
    constexpr auto loggerDelayMs   = 1000 * 60 * 5;
    constexpr auto loggerTimerName = "Logger";
    constexpr auto loggerDelayMs        = 1000 * 60 * 5;
    constexpr auto loggerTimerName      = "Logger";
    constexpr std::array sliderKeyCodes = {
        bsp::KeyCodes::SSwitchUp, bsp::KeyCodes::SSwitchMid, bsp::KeyCodes::SSwitchDown};



@@ 281,6 282,13 @@ sys::ReturnCodes EventManager::InitHandler()
        processTimezoneRequest(message->getTimezone());
        return sys::MessageNone{};
    });

    connect(typeid(sevm::FlushLogsRequest), [&]([[maybe_unused]] sys::Message *msg) {
        if (auto ret = dumpLogsToFile(); ret >= 0) {
            return std::make_shared<sevm::FlushLogsResponse>(true, ret);
        }
        return std::make_shared<sevm::FlushLogsResponse>(false);
    });
    // initialize keyboard worker
    EventWorker = std::make_unique<WorkerEvent>(this);



@@ 376,15 384,14 @@ void EventManager::handleKeyMoveEvent(RawKey key)
    }
}

void EventManager::dumpLogsToFile()
int EventManager::dumpLogsToFile()
{
    const auto logPath = purefs::dir::getUserDiskPath() / LOG_FILE_NAME;
    const bool dumpLog = !(std::filesystem::exists(logPath) && std::filesystem::file_size(logPath) > MAX_LOG_FILE_SIZE);
    if (dumpLog) {
        const auto &logs = Log::Logger::get().getLogs();
        std::fstream logFile(logPath, std::fstream::out | std::fstream::app);
        logFile.write(logs.data(), logs.size());
    }
    const auto ts      = cpp_freertos::Ticks::TicksToMs(cpp_freertos::Ticks::GetTicks());

    LOG_DEBUG("Log flush timestamp: %d", static_cast<unsigned>(ts));

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

void EventManager::handleMinuteUpdate(time_t timestamp)

M module-services/service-evtmgr/service-evtmgr/EVMessages.hpp => module-services/service-evtmgr/service-evtmgr/EVMessages.hpp +14 -0
@@ 138,4 138,18 @@ namespace sevm
        std::chrono::milliseconds repetitionTime;
    };

    class FlushLogsRequest : public sys::DataMessage
    {};

    class FlushLogsResponse : public sys::ResponseMessage
    {
      public:
        FlushLogsResponse(bool retCode, int retData = 0)
            : sys::ResponseMessage(sys::ReturnCodes::Success, MessageType::MessageTypeUninitialized), retCode(retCode),
              data(retData){};

        const bool retCode{};
        const int data{};
    };

} /* namespace sevm*/

M module-services/service-evtmgr/service-evtmgr/EventManager.hpp => module-services/service-evtmgr/service-evtmgr/EventManager.hpp +4 -1
@@ 79,7 79,10 @@ class EventManager : public sys::Service

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

    void dumpLogsToFile();
    /// @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

M module-utils/log/Logger.cpp => module-utils/log/Logger.cpp +38 -0
@@ 118,4 118,42 @@ namespace Log

        return loggerBufferCurrentPos;
    }

    /// @param logPath: file path to store the log
    /// @return: < 0 - error occured during log flush
    /// @return:   0 - log flush did not happen
    /// @return:   1 - log flush successflul
    auto Logger::dumpToFile(std::filesystem::path logPath) -> int
    {
        int status = 0;
        const bool dumpLog =
            !(std::filesystem::exists(logPath) && std::filesystem::file_size(logPath) > MAX_LOG_FILE_SIZE);
        if (!dumpLog) {
            LOG_DEBUG("Flush skipped");
            return 0;
        }

        {
            status = 1;

            const auto &logs = getLogs();

            LockGuard lock(mutex);
            std::fstream logFile(logPath, std::fstream::out | std::fstream::app);

            if (!logFile.good()) {
                status = -EIO;
            }

            logFile.write(logs.data(), logs.size());
            if (logFile.bad()) {
                status = -EIO;
            }
        }

        LOG_DEBUG("Flush ended with status: %d", status);

        return status;
    }

}; // namespace Log

M module-utils/log/Logger.hpp => module-utils/log/Logger.hpp +2 -0
@@ 11,6 11,7 @@
#include <map>
#include <mutex.hpp>
#include <string>
#include <filesystem>

namespace Log
{


@@ 35,6 36,7 @@ namespace Log
        auto log(logger_level level, const char *file, int line, const char *function, const char *fmt, va_list args)
            -> int;
        auto logAssert(const char *fmt, va_list args) -> int;
        auto dumpToFile(std::filesystem::path logPath) -> int;

        static constexpr auto CRIT_STR = "CRIT";
        static constexpr auto IRQ_STR  = "IRQ";

M test/harness => test/harness +1 -1
@@ 1,1 1,1 @@
Subproject commit b1ae209e9c257f8f62b3023ca30a361bd4d01e21
Subproject commit eecee32772ba2f7ad838535bc1fc99e707205d8e