Как сделать что бы эта программа красивее выводила логи:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <windows.h>

using namespace std;

// Функция для установки цвета текста и фона
void SetColor(int textColor, int bgColor) {
    HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(h, (bgColor << 4) | textColor);
}

// Функция для сброса цвета к стандартным
void ResetColor() {
    SetColor(7, 0); // Белый текст на черном фоне
}

// Функция для вывода текста с заданными цветами
void PrintWithColor(const string& text, int textColor, int bgColor) {
    SetColor(textColor, bgColor);
    cout << text;
    // Не сбрасываем цвет здесь, чтобы позволить фону продолжаться
}

// Функция для обработки и вывода одной строки лога с учетом максимальной длины
void ProcessLogLine(const string& line, size_t maxLength) {
    size_t pos = 0;
    size_t printedLength = 0;

    // Окрашиваем дату и время в более темный фон с белым текстом
    if (line.size() >= 24 && line[4] == '-' && line[10] == ' ' && line[13] == ':' && line[16] == ':') {
        string datetime = line.substr(0, 24) + " ";
        PrintWithColor(datetime, 15, 8); // Белый текст, темно-серый фон для даты
        pos = 24;
        printedLength += datetime.size();
    }

    while (pos < line.size()) {
        // Ищем позиции ключевых слов
        size_t infoPos = line.find("[INFO]", pos);
        size_t debugPos = line.find("[DEBUG]", pos);
        size_t errorPos = line.find("[ERROR]", pos);

        // Находим ближайшую позицию ключевого слова
        size_t nextPos = line.size();
        if (infoPos != string::npos) nextPos = min(nextPos, infoPos);
        if (debugPos != string::npos) nextPos = min(nextPos, debugPos);
        if (errorPos != string::npos) nextPos = min(nextPos, errorPos);

        // Если есть текст перед ключевым словом, выводим его с фоном по умолчанию
        if (nextPos > pos) {
            string text = line.substr(pos, nextPos - pos);
            PrintWithColor(text, 15, 8); // Белый текст, темно-серый фон для остальной части строки
            printedLength += text.size();
        }

        // Окрашивание ключевых слов
        if (nextPos == infoPos) {
            PrintWithColor("[INFO]", 15, 2); // Белый текст, зеленый фон
            pos = infoPos + 6;
            printedLength += 6;
        }
        else if (nextPos == debugPos) {
            PrintWithColor("[DEBUG]", 15, 1); // Белый текст, синий фон
            pos = debugPos + 7;
            printedLength += 7;
        }
        else if (nextPos == errorPos) {
            PrintWithColor("[ERROR]", 15, 4); // Белый текст, красный фон
            pos = errorPos + 7;
            printedLength += 7;
        }
        else {
            // Нет больше ключевых слов
            pos = line.size();
        }
    }

    // Если длина текущей строки меньше максимальной, дополняем пробелами с тем же фоном
    if (printedLength < maxLength) {
        size_t paddingLength = maxLength - printedLength;
        string padding(paddingLength, ' ');
        PrintWithColor(padding, 15, 8); // Белый текст (пробелы не видны), темно-серый фон
    }

    ResetColor(); // Сброс цвета в стандартный
    cout << endl;
}

int main() {
    ifstream logFile("emulator.log");
    if (!logFile.is_open()) {
        cerr << "Error opening log file." << endl;
        system("pause");
        return 1;
    }

    // Читаем все строки в вектор
    vector<string> lines;
    string line;
    size_t maxLength = 0;
    while (getline(logFile, line)) {
        lines.push_back(line);
        if (line.length() > maxLength) {
            maxLength = line.length();
        }
    }
    logFile.close();

    // Опционально: добавить дополнительные символы для окрашивания дат и ключевых слов
    // Например, если даты всегда занимают 24 символа + пробел, можно обновить maxLength
    // Но в этом примере предполагается, что maxLength уже учтен

    // Обрабатываем каждую строку с учетом максимальной длины
    for (const auto& logLine : lines) {
        ProcessLogLine(logLine, maxLength);
    }

    system("pause");
    return 0;
}