Skip to main content
added 4679 characters in body
Source Link

I did an internship test project (source: https://github.com/SynI20N/VKInfo). I'm lookingLooking for some middle or senior devs to rate it and point out potential problems with my code. Follow up: How would you test my code like people do it in production?

metrics_logger.h:


    #ifndef METRICS_LOGGER_H_
    #define METRICS_LOGGER_H_
    
    #include <string>
    #include <atomic>
    #include <thread>
    
    #include "metrics_registry.h"
    
    namespace VkInfo {
    
    /**
     * @brief Periodically logs metric values to a file.
     * 
     * MetricsLogger runs in a background thread, collecting metric values from a MetricsRegistry
     * at fixed intervals and writing them to a log file with timestamps. After logging, each metric
     * is reset. This logger is thread-safe and non-blocking for metric producers.
     */
    class VKINFO_API MetricsLogger {
    public:
        /**
         * @brief Constructs a MetricsLogger instance.
         * 
         * @param registry Reference to the MetricsRegistry containing all metrics to log.
         * @param filename Name of the file to write log entries to.
         * @param interval Logging interval (e.g., every second).
         */
        MetricsLogger(MetricsRegistry& registry, const std::string& filename, std::chrono::milliseconds interval);
    
        /**
         * @brief Destructor for MetricsLogger.
         * 
         * Ensures the background thread is stopped before destruction.
         */
        ~MetricsLogger();
    
        /**
         * @brief Starts the background logging thread.
         * 
         * Logs metric data to the file at the specified interval.
         */
        void start();
    
        /**
         * @brief Stops the background logging thread safely.
         */
        void stop();
    
        /**
         * @brief Retrieves all currently registered metrics from the registry.
         * 
         * @return A vector of shared pointers to IMetric instances.
         */
        std::vector<std::shared_ptr<IMetric>> get_all_metrics();
    
    private:
        MetricsRegistry& registry_;                 ///< Reference to the metric registry.
        std::string filename_;                      ///< Output log file name.
        std::chrono::milliseconds interval_;        ///< Logging frequency.
        std::atomic<bool> running_;                 ///< Indicates if the logger is running.
        std::thread worker_;                        ///< Background thread for logging.
    
        /**
         * @brief Main logging loop executed in a background thread.
         * 
         * Gathers metrics, writes them to the file, and resets them.
         */
        void run();
    
        /**
         * @brief Gets the current system time as a formatted timestamp string.
         * 
         * @return Timestamp in the format "YYYY-MM-DD HH:MM:SS.mmm".
         */
        std::string get_current_timestamp() const;
    };
    
    } // namespace VkInfo
    
    #endif // METRICS_LOGGER_H_

    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <chrono>
    #include <iomanip>
    
    #include "../include/metrics_logger.h"
    
    namespace VkInfo {
    
    MetricsLogger::MetricsLogger(MetricsRegistry& registry,
                                const std::string& filename,
                                std::chrono::milliseconds interval)
    : registry_(registry),
        filename_(filename),
        interval_(interval),
        running_(false) {}
    
    MetricsLogger::~MetricsLogger() {
        stop();
    }
    
    void MetricsLogger::start() {
        if (running_) return;
        running_ = true;
        worker_ = std::thread(&MetricsLogger::run, this);
    }
    
    void MetricsLogger::stop() {
        if (!running_) return;
        running_ = false;
        if (worker_.joinable()) {
            worker_.join();
        }
    }
    
    std::vector<std::shared_ptr<IMetric>> MetricsLogger::get_all_metrics() {
        return registry_.get_all_metrics();
    }
    
    std::string MetricsLogger::get_current_timestamp() const {
        using namespace std::chrono;
    
        auto now = system_clock::now();
        auto time = system_clock::to_time_t(now);
        auto ms = duration_cast<milliseconds>(now.time_since_epoch()) % 1000;
    
        std::ostringstream oss;
        oss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S")
            << "." << std::setw(3) << std::setfill('0') << ms.count();
        return oss.str();
    }
    
    void MetricsLogger::run() {
        std::ofstream out(filename_, std::ios::app);
        while (running_) {
            auto now = get_current_timestamp();
            std::ostringstream line;
            line << now;
    
            for (auto& metric : registry_.get_all_metrics()) {
                line << " \"" << metric->get_name() << "\" " << metric->get_value_and_reset();
            }
    
            out << line.str() << std::endl;
            out.flush();
            std::this_thread::sleep_for(interval_);
        }
    }
    
    } // namespace VkInfo 

metrics_registry.h:


    #ifndef METRICS_REGISTRY_H_
    #define METRICS_REGISTRY_H_
    
    #include <vector>
    #include <memory>
    #include <mutex>
    
    #include "metric.h"
    
    namespace VkInfo {
    
    /**
     * @brief Registry for managing and storing metrics.
     *
     * MetricsRegistry maintains a thread-safe collection of metrics.
     * It allows registration of new metrics and provides access to all registered metrics.
     */
    class VKINFO_API MetricsRegistry {
    public:
        /**
         * @brief Registers a new metric.
         *
         * Thread-safe method to add a metric to the registry.
         *
         * @param metric Shared pointer to the metric to register.
         */
        void register_metric(std::shared_ptr<IMetric> metric);
    
        /**
         * @brief Retrieves all registered metrics.
         *
         * Thread-safe method to get a snapshot of all metrics currently registered.
         *
         * @return Vector of shared pointers to all registered metrics.
         */
        std::vector<std::shared_ptr<IMetric>> get_all_metrics();
    
    private:
        std::vector<std::shared_ptr<IMetric>> metrics_; ///< Container holding registered metrics.
        std::mutex mutex_;                              ///< Mutex to protect access to metrics_.
    };
    
    } // namespace VkInfo
    
    #endif // METRICS_REGISTRY_H_
    #include "../include/metrics_registry.h"
    
    namespace VkInfo {
    
    void MetricsRegistry::register_metric(std::shared_ptr<IMetric> metric) {
        std::lock_guard<std::mutex> lock(mutex_);
        metrics_.push_back(std::move(metric));
    }
    
    std::vector<std::shared_ptr<IMetric>> MetricsRegistry::get_all_metrics() {
        std::lock_guard<std::mutex> lock(mutex_);
        return metrics_;
    }
    
    } // namespace VkInfo 

I did an internship test project (source: https://github.com/SynI20N/VKInfo). I'm looking for some middle or senior devs to rate it and point out potential problems with my code. Follow up: How would you test my code like people do it in production?

#include <iostream>
#include <fstream>
#include <sstream>
#include <chrono>
#include <iomanip>

#include "../include/metrics_logger.h"

namespace VkInfo {

MetricsLogger::MetricsLogger(MetricsRegistry& registry,
                            const std::string& filename,
                            std::chrono::milliseconds interval)
: registry_(registry),
    filename_(filename),
    interval_(interval),
    running_(false) {}

MetricsLogger::~MetricsLogger() {
    stop();
}

void MetricsLogger::start() {
    if (running_) return;
    running_ = true;
    worker_ = std::thread(&MetricsLogger::run, this);
}

void MetricsLogger::stop() {
    if (!running_) return;
    running_ = false;
    if (worker_.joinable()) {
        worker_.join();
    }
}

std::vector<std::shared_ptr<IMetric>> MetricsLogger::get_all_metrics() {
    return registry_.get_all_metrics();
}

std::string MetricsLogger::get_current_timestamp() const {
    using namespace std::chrono;

    auto now = system_clock::now();
    auto time = system_clock::to_time_t(now);
    auto ms = duration_cast<milliseconds>(now.time_since_epoch()) % 1000;

    std::ostringstream oss;
    oss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S")
        << "." << std::setw(3) << std::setfill('0') << ms.count();
    return oss.str();
}

void MetricsLogger::run() {
    std::ofstream out(filename_, std::ios::app);
    while (running_) {
        auto now = get_current_timestamp();
        std::ostringstream line;
        line << now;

        for (auto& metric : registry_.get_all_metrics()) {
            line << " \"" << metric->get_name() << "\" " << metric->get_value_and_reset();
        }

        out << line.str() << std::endl;
        out.flush();
        std::this_thread::sleep_for(interval_);
    }
}

} // namespace VkInfo
#include "../include/metrics_registry.h"

namespace VkInfo {

void MetricsRegistry::register_metric(std::shared_ptr<IMetric> metric) {
    std::lock_guard<std::mutex> lock(mutex_);
    metrics_.push_back(std::move(metric));
}

std::vector<std::shared_ptr<IMetric>> MetricsRegistry::get_all_metrics() {
    std::lock_guard<std::mutex> lock(mutex_);
    return metrics_;
}

} // namespace VkInfo

I did an internship test project (source: https://github.com/SynI20N/VKInfo). Looking for some middle or senior devs to rate it and point out potential problems with my code. Follow up: How would you test my code like people do it in production?

metrics_logger.h:


    #ifndef METRICS_LOGGER_H_
    #define METRICS_LOGGER_H_
    
    #include <string>
    #include <atomic>
    #include <thread>
    
    #include "metrics_registry.h"
    
    namespace VkInfo {
    
    /**
     * @brief Periodically logs metric values to a file.
     * 
     * MetricsLogger runs in a background thread, collecting metric values from a MetricsRegistry
     * at fixed intervals and writing them to a log file with timestamps. After logging, each metric
     * is reset. This logger is thread-safe and non-blocking for metric producers.
     */
    class VKINFO_API MetricsLogger {
    public:
        /**
         * @brief Constructs a MetricsLogger instance.
         * 
         * @param registry Reference to the MetricsRegistry containing all metrics to log.
         * @param filename Name of the file to write log entries to.
         * @param interval Logging interval (e.g., every second).
         */
        MetricsLogger(MetricsRegistry& registry, const std::string& filename, std::chrono::milliseconds interval);
    
        /**
         * @brief Destructor for MetricsLogger.
         * 
         * Ensures the background thread is stopped before destruction.
         */
        ~MetricsLogger();
    
        /**
         * @brief Starts the background logging thread.
         * 
         * Logs metric data to the file at the specified interval.
         */
        void start();
    
        /**
         * @brief Stops the background logging thread safely.
         */
        void stop();
    
        /**
         * @brief Retrieves all currently registered metrics from the registry.
         * 
         * @return A vector of shared pointers to IMetric instances.
         */
        std::vector<std::shared_ptr<IMetric>> get_all_metrics();
    
    private:
        MetricsRegistry& registry_;                 ///< Reference to the metric registry.
        std::string filename_;                      ///< Output log file name.
        std::chrono::milliseconds interval_;        ///< Logging frequency.
        std::atomic<bool> running_;                 ///< Indicates if the logger is running.
        std::thread worker_;                        ///< Background thread for logging.
    
        /**
         * @brief Main logging loop executed in a background thread.
         * 
         * Gathers metrics, writes them to the file, and resets them.
         */
        void run();
    
        /**
         * @brief Gets the current system time as a formatted timestamp string.
         * 
         * @return Timestamp in the format "YYYY-MM-DD HH:MM:SS.mmm".
         */
        std::string get_current_timestamp() const;
    };
    
    } // namespace VkInfo
    
    #endif // METRICS_LOGGER_H_

    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <chrono>
    #include <iomanip>
    
    #include "../include/metrics_logger.h"
    
    namespace VkInfo {
    
    MetricsLogger::MetricsLogger(MetricsRegistry& registry,
                                const std::string& filename,
                                std::chrono::milliseconds interval)
    : registry_(registry),
        filename_(filename),
        interval_(interval),
        running_(false) {}
    
    MetricsLogger::~MetricsLogger() {
        stop();
    }
    
    void MetricsLogger::start() {
        if (running_) return;
        running_ = true;
        worker_ = std::thread(&MetricsLogger::run, this);
    }
    
    void MetricsLogger::stop() {
        if (!running_) return;
        running_ = false;
        if (worker_.joinable()) {
            worker_.join();
        }
    }
    
    std::vector<std::shared_ptr<IMetric>> MetricsLogger::get_all_metrics() {
        return registry_.get_all_metrics();
    }
    
    std::string MetricsLogger::get_current_timestamp() const {
        using namespace std::chrono;
    
        auto now = system_clock::now();
        auto time = system_clock::to_time_t(now);
        auto ms = duration_cast<milliseconds>(now.time_since_epoch()) % 1000;
    
        std::ostringstream oss;
        oss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S")
            << "." << std::setw(3) << std::setfill('0') << ms.count();
        return oss.str();
    }
    
    void MetricsLogger::run() {
        std::ofstream out(filename_, std::ios::app);
        while (running_) {
            auto now = get_current_timestamp();
            std::ostringstream line;
            line << now;
    
            for (auto& metric : registry_.get_all_metrics()) {
                line << " \"" << metric->get_name() << "\" " << metric->get_value_and_reset();
            }
    
            out << line.str() << std::endl;
            out.flush();
            std::this_thread::sleep_for(interval_);
        }
    }
    
    } // namespace VkInfo 

metrics_registry.h:


    #ifndef METRICS_REGISTRY_H_
    #define METRICS_REGISTRY_H_
    
    #include <vector>
    #include <memory>
    #include <mutex>
    
    #include "metric.h"
    
    namespace VkInfo {
    
    /**
     * @brief Registry for managing and storing metrics.
     *
     * MetricsRegistry maintains a thread-safe collection of metrics.
     * It allows registration of new metrics and provides access to all registered metrics.
     */
    class VKINFO_API MetricsRegistry {
    public:
        /**
         * @brief Registers a new metric.
         *
         * Thread-safe method to add a metric to the registry.
         *
         * @param metric Shared pointer to the metric to register.
         */
        void register_metric(std::shared_ptr<IMetric> metric);
    
        /**
         * @brief Retrieves all registered metrics.
         *
         * Thread-safe method to get a snapshot of all metrics currently registered.
         *
         * @return Vector of shared pointers to all registered metrics.
         */
        std::vector<std::shared_ptr<IMetric>> get_all_metrics();
    
    private:
        std::vector<std::shared_ptr<IMetric>> metrics_; ///< Container holding registered metrics.
        std::mutex mutex_;                              ///< Mutex to protect access to metrics_.
    };
    
    } // namespace VkInfo
    
    #endif // METRICS_REGISTRY_H_
    #include "../include/metrics_registry.h"
    
    namespace VkInfo {
    
    void MetricsRegistry::register_metric(std::shared_ptr<IMetric> metric) {
        std::lock_guard<std::mutex> lock(mutex_);
        metrics_.push_back(std::move(metric));
    }
    
    std::vector<std::shared_ptr<IMetric>> MetricsRegistry::get_all_metrics() {
        std::lock_guard<std::mutex> lock(mutex_);
        return metrics_;
    }
    
    } // namespace VkInfo 

added 4 characters in body
Source Link
toolic
  • 15.7k
  • 5
  • 29
  • 216

I did an internship test project (source: https://github.com/SynI20N/VKInfo). LookingI'm looking for some middle or senior devs to rate it and point out potential problems with my code. Follow up: How would you test my code like people do it in production?

I did an internship test project (source: https://github.com/SynI20N/VKInfo). Looking for some middle or senior devs to rate it and point out potential problems with my code. Follow up: How would you test my code like people do it in production?

I did an internship test project (source: https://github.com/SynI20N/VKInfo). I'm looking for some middle or senior devs to rate it and point out potential problems with my code. Follow up: How would you test my code like people do it in production?

Source Link

Small library for metrics scraping in C++

I did an internship test project (source: https://github.com/SynI20N/VKInfo). Looking for some middle or senior devs to rate it and point out potential problems with my code. Follow up: How would you test my code like people do it in production?

metrics_logger.cc:

#include <iostream>
#include <fstream>
#include <sstream>
#include <chrono>
#include <iomanip>

#include "../include/metrics_logger.h"

namespace VkInfo {

MetricsLogger::MetricsLogger(MetricsRegistry& registry,
                            const std::string& filename,
                            std::chrono::milliseconds interval)
: registry_(registry),
    filename_(filename),
    interval_(interval),
    running_(false) {}

MetricsLogger::~MetricsLogger() {
    stop();
}

void MetricsLogger::start() {
    if (running_) return;
    running_ = true;
    worker_ = std::thread(&MetricsLogger::run, this);
}

void MetricsLogger::stop() {
    if (!running_) return;
    running_ = false;
    if (worker_.joinable()) {
        worker_.join();
    }
}

std::vector<std::shared_ptr<IMetric>> MetricsLogger::get_all_metrics() {
    return registry_.get_all_metrics();
}

std::string MetricsLogger::get_current_timestamp() const {
    using namespace std::chrono;

    auto now = system_clock::now();
    auto time = system_clock::to_time_t(now);
    auto ms = duration_cast<milliseconds>(now.time_since_epoch()) % 1000;

    std::ostringstream oss;
    oss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S")
        << "." << std::setw(3) << std::setfill('0') << ms.count();
    return oss.str();
}

void MetricsLogger::run() {
    std::ofstream out(filename_, std::ios::app);
    while (running_) {
        auto now = get_current_timestamp();
        std::ostringstream line;
        line << now;

        for (auto& metric : registry_.get_all_metrics()) {
            line << " \"" << metric->get_name() << "\" " << metric->get_value_and_reset();
        }

        out << line.str() << std::endl;
        out.flush();
        std::this_thread::sleep_for(interval_);
    }
}

} // namespace VkInfo

metrics_registry.cc:

#include "../include/metrics_registry.h"

namespace VkInfo {

void MetricsRegistry::register_metric(std::shared_ptr<IMetric> metric) {
    std::lock_guard<std::mutex> lock(mutex_);
    metrics_.push_back(std::move(metric));
}

std::vector<std::shared_ptr<IMetric>> MetricsRegistry::get_all_metrics() {
    std::lock_guard<std::mutex> lock(mutex_);
    return metrics_;
}

} // namespace VkInfo

For complete project, refer to GitHub.