сделай новый параметр для просмотра логов, принцип просмотра логов есть в ориг код 2. Ориг код:
#include "Logger.h"
Logger& Logger::get_instance() {
    static Logger instance;
    return instance;
}
Logger::Logger()
    : current_level(LogLevel::DEBUG), file_logging_enabled(false) {}
Logger::~Logger() {
    if (log_file.is_open()) {
        log_file.close();
    }
}
void Logger::set_log_level(LogLevel level) {
    current_level = level;
}
void Logger::enable_file_logging(const std::string& filename) {
    std::lock_guard<std::mutex> lock(log_mutex);
    if (log_file.is_open()) {
        log_file.close();
    }
    log_file.open(filename, std::ios::out | std::ios::app);
    if (log_file.is_open()) {
        file_logging_enabled = true;
    }
    else {
        std::cerr << "Failed to open log file: " << filename << "\n";
    }
}
void Logger::disable_file_logging() {
    std::lock_guard<std::mutex> lock(log_mutex);
    if (log_file.is_open()) {
        log_file.close();
    }
    file_logging_enabled = false;
}
std::string get_current_timestamp() {
    auto now = std::chrono::system_clock::now();
    auto now_time_t = std::chrono::system_clock::to_time_t(now);
    std::tm tm;
    bool success = false;
#if defined(_WIN32) || defined(_WIN64)
    errno_t err = localtime_s(&tm, &now_time_t); // WINDOWS
    success = (err == 0);
#else
    success = (localtime_r(&now_time_t, &tm) != nullptr); // POSIX
#endif
    if (!success) {
        return "1970-01-01 00:00:00.000";
    }
    auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
        now.time_since_epoch()) % 1000;
    std::ostringstream ss;
    ss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S") << '.'
        << std::setw(3) << std::setfill('0') << now_ms.count();
    return ss.str();
}
void Logger::log(LogLevel level, const std::string& message) {
    if (static_cast<int>(level) < static_cast<int>(current_level)) {
        return;
    }
    std::lock_guard<std::mutex> lock(log_mutex);
    std::string timestamp = get_current_timestamp();
    std::string level_str;
    switch (level) {
    case LogLevel::DEBUG:   level_str = "[DEBUG] "; break;
    case LogLevel::INFO:    level_str = "[INFO] "; break;
    case LogLevel::WARNING: level_str = "[WARNING] "; break;
    case LogLevel::ERROR:   level_str = "[ERROR] "; break;
    }
    std::string formatted_message = timestamp + " " + level_str + message;
    //std::cout << formatted_message << std::endl;
    if (file_logging_enabled && log_file.is_open()) {
        log_file << formatted_message << std::endl;
    }
}
#ifndef LOGGER_H
#define LOGGER_H
#include <chrono>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <mutex>
#include <fstream>
#include <ctime>
enum class LogLevel {
    DEBUG = 0,
    INFO,
    WARNING,
    ERROR
};
class Logger {
public:
    // Singleton pattern to ensure a single logger instance
    static Logger& get_instance();
    // Set the minimum log level
    void set_log_level(LogLevel level);
    // Enable or disable logging to a file
    void enable_file_logging(const std::string& filename);
    void disable_file_logging();
    // Logging methods
    void log(LogLevel level, const std::string& message);
private:
    Logger(); // Private constructor for singleton
    ~Logger();
    Logger(const Logger&) = delete;
    Logger& operator=(const Logger&) = delete;
    LogLevel current_level;
    bool file_logging_enabled;
    std::ofstream log_file;
    std::mutex log_mutex; // To make logging thread-safe
};
#endif // LOGGER_H
// main.cpp
#include "elf_loader.h"
#include "file_utils.h"
#include "Emulator.h"
#include "elf_structs.h"
#include "Logger.h"
#include "utils.h"
#include <iostream>
#include <vector>
#include <cstdint>
#include <string>
bool run_program_from_elf(const std::string& filename) {
    Emulator emulator(0);
    bool load_result = load_elf(filename, emulator);
    if (!load_result) {
        Logger::get_instance().log(LogLevel::ERROR, "Failed to load ELF file.");
        return false;
    }
    emulator.run();
    if (!emulator.has_error()) {
        Logger::get_instance().log(LogLevel::INFO, "ELF program executed successfully.");
    }
    else {
        Logger::get_instance().log(LogLevel::ERROR, "ELF program execution failed.");
    }
    return !emulator.has_error();
}
int main(int argc, char* argv[]) {
    Logger::get_instance().set_log_level(LogLevel::DEBUG);
    Logger::get_instance().enable_file_logging("emulator.log");
    if (argc > 1) {
        std::string program_filename = argv[1];
        if (program_filename.size() >= 4 &&
            program_filename.substr(program_filename.size() - 4) == ".elf") {
            Logger::get_instance().log(LogLevel::INFO, "Running ELF file: " + program_filename);
            run_program_from_elf(program_filename);
        }
        else {
            Logger::get_instance().log(LogLevel::INFO, "Running flat binary file: " + program_filename);
            Emulator emulator(0);
            std::vector<uint8_t> program = load_program_from_file(program_filename);
            if (program.empty()) {
                Logger::get_instance().log(LogLevel::ERROR, "Failed to load program from file: " + program_filename);
                return -1;
            }
            emulator.load_program(program, 0, 0, true);
            emulator.run();
            if (!emulator.has_error()) {
                Logger::get_instance().log(LogLevel::INFO, "Program executed successfully!");
            }
            else {
                Logger::get_instance().log(LogLevel::ERROR, "Program execution failed.");
            }
        }
    }
    else {
        std::cout << "Usage " + std::string(argv[0]) + " <filename.(elf|bin)>";
    }
    return 0;
}
Ориг код 2:
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
#include <cstdio>
using namespace std;
struct LogType {
    string keyword;
    int textColor;
    int bgColor;
    size_t count = 0;
} logs[] = { {"[INFO]", 15, 2}, {"[DEBUG]", 15, 1}, {"[ERROR]", 15, 4} };
void SetColor(int tc, int bc) {
    HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
    if (h != INVALID_HANDLE_VALUE)
        SetConsoleTextAttribute(h, (bc << 4) | (tc & 0x0F));
}
void PrintC(const string& s, int tc, int bc) {
    SetColor(tc, bc);
    cout << s;
    SetColor(7, 0);
}
int main() {
    ifstream f("emulator.log");
    if (!f) {
        cerr << "Error while opening log file.\n";
        system("pause"); return 1;
    }
    string line; size_t maxL = 23;
    while (getline(f, line)) if (line.length() > maxL) maxL = line.length();
    f.clear(); f.seekg(0);
    while (getline(f, line)) {
        size_t pos = 0;
        if (line.size() >= 23 && line[4] == '-' && line[7] == '-' && line[10] == ' '
            && line[13] == ':' && line[16] == ':' && line[19] == '.') {
            PrintC(line.substr(0, 23), 8, 0); pos = 23;
        }
        size_t k;
        while ((k = line.find('[', pos)) != string::npos) {
            if (k > pos) cout << line.substr(pos, k - pos);
            bool found = false;
            for (auto& log : logs) {
                if (line.compare(k, log.keyword.size(), log.keyword) == 0) {
                    PrintC(log.keyword, log.textColor, log.bgColor);
                    log.count++; pos = k + log.keyword.size(); found = true; break;
                }
            }
            if (!found) { cout << '['; pos = k + 1; }
        }
        if (pos < line.size()) cout << line.substr(pos);
        if (line.length() < maxL) cout << string(maxL - line.length(), ' ');
        cout << '\n';
    }
    f.close();
    for (auto& log : logs)
        cout << log.keyword.substr(1, log.keyword.size() - 2) << ": ", PrintC(to_string(log.count), log.textColor, log.bgColor), cout << '\n';
    if (remove("emulator.log") != 0) { perror("Error while deleting log file"); }
    else { cout << "File log succesfully deleted.\n"; }
    system("pause");
    return 0;
}