include/AclLog.h

include/AclLog.h

Namespaces

Name
AclLog
A namespace for logging utilities.

Classes

Name
classAclLog::CommandLogFormatter
This class is used to format log entries for Rendering Engine commands.
classAclLog::ThreadNameFormatterFlag
classAclLog::FileLocationFormatterFlag
A custom flag formatter which logs the source file location between a par of “[]”, in case the location is provided with the log call.

Source code

// Copyright (c) 2022, Edgeware AB. All rights reserved.

#pragma once

#include <filesystem>
#include <string>

#include <spdlog/details/log_msg.h>
#include <spdlog/fmt/fmt.h>
#include <spdlog/formatter.h>
#include <spdlog/pattern_formatter.h>
#include <sys/prctl.h>

namespace AclLog {

enum class Level {
    kTrace,    // Detailed diagnostics (for development only)
    kDebug,    // Messages intended for debugging only
    kInfo,     // Messages about normal behavior (default log level)
    kWarning,  // Warnings (functionality intact)
    kError,    // Recoverable errors (functionality impaired)
    kCritical, // Unrecoverable errors (application must stop)
    kOff       // Turns off all logging
};

void init(const std::string& name);

void initCommandLog(const std::string& name);

void setLevel(Level level);

void logCommand(const std::string& origin, const std::string& command);

AclLog::Level getLogLevel();

size_t getMaxFileSize();

size_t getMaxLogRotations();

std::filesystem::path getLogFileFullPath(const std::string& name);

class CommandLogFormatter : public spdlog::formatter {
public:
    CommandLogFormatter();
    void format(const spdlog::details::log_msg& msg, spdlog::memory_buf_t& dest) override;
    [[nodiscard]] std::unique_ptr<spdlog::formatter> clone() const override;

private:
    std::unique_ptr<spdlog::pattern_formatter> mCommandLogPattern;
};

inline std::string getThreadName() {
    static const size_t RECOMMENDED_BUFFER_SIZE = 20;
    static thread_local std::string name;

    if (name.empty()) {
        char buffer[RECOMMENDED_BUFFER_SIZE];
        int retval = prctl(PR_GET_NAME, buffer);
        if (retval == -1) {
            throw spdlog::spdlog_ex("Failed to get thread name: ", errno);
        }
        name = std::string(buffer);
    }
    return name;
}

class ThreadNameFormatterFlag : public spdlog::custom_flag_formatter {
public:
    void format(const spdlog::details::log_msg&, const std::tm&, spdlog::memory_buf_t& dest) override {
        std::string threadName = getThreadName();
        dest.append(threadName.data(), threadName.data() + threadName.size());
    }

    [[nodiscard]] std::unique_ptr<custom_flag_formatter> clone() const override {
        return spdlog::details::make_unique<ThreadNameFormatterFlag>();
    }
};

class FileLocationFormatterFlag : public spdlog::custom_flag_formatter {
public:
    void format(const spdlog::details::log_msg& msg, const std::tm&, spdlog::memory_buf_t& dest) override {
        if (!msg.source.empty()) {
            using namespace spdlog::details;

            dest.push_back('[');
            const char* filename = short_filename_formatter<null_scoped_padder>::basename(msg.source.filename);
            fmt_helper::append_string_view(filename, dest);
            dest.push_back(':');
            fmt_helper::append_int(msg.source.line, dest);
            dest.push_back(']');
        }
    }

    [[nodiscard]] std::unique_ptr<custom_flag_formatter> clone() const override {
        return spdlog::details::make_unique<FileLocationFormatterFlag>();
    }
};

} // namespace AclLog

Updated on 2024-01-25 at 12:02:05 +0100