mirror of https://github.com/sysown/proxysql
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
222 lines
7.0 KiB
222 lines
7.0 KiB
#ifndef __CLASS_LOG_UTILS_H
|
|
#define __CLASS_LOG_UTILS_H
|
|
|
|
#include <string>
|
|
#include <cstdint>
|
|
#include <random>
|
|
#include <mutex>
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
#include <fstream>
|
|
#include <functional>
|
|
#include <pthread.h>
|
|
|
|
namespace prometheus {
|
|
class Counter;
|
|
}
|
|
|
|
/**
|
|
* @brief Manages a string buffer and a flush timestamp for logging.
|
|
*
|
|
* Used to accumulate log data in memory before writing to a file.
|
|
*/
|
|
class LogBuffer {
|
|
private:
|
|
std::string buffer;
|
|
uint64_t last_flush_time;
|
|
|
|
public:
|
|
LogBuffer();
|
|
|
|
/**
|
|
* @brief Stream insertion operator for appending strings to the buffer.
|
|
* @param value The string to append to the buffer.
|
|
* @return Reference to this LogBuffer for method chaining.
|
|
*/
|
|
LogBuffer& operator<<(const std::string& value);
|
|
|
|
/**
|
|
* @brief Stream insertion operator for appending C-strings to the buffer.
|
|
* @param value The C-string to append to the buffer.
|
|
* @return Reference to this LogBuffer for method chaining.
|
|
*/
|
|
LogBuffer& operator<<(const char* value);
|
|
|
|
/**
|
|
* @brief Stream insertion operator for appending characters to the buffer.
|
|
* @param value The character to append to the buffer.
|
|
* @return Reference to this LogBuffer for method chaining.
|
|
*/
|
|
LogBuffer& operator<<(char value);
|
|
|
|
/**
|
|
* @brief Appends a string to the buffer.
|
|
* @param str The string to append to the buffer.
|
|
* @return Reference to this LogBuffer for method chaining.
|
|
*/
|
|
LogBuffer& append(const std::string& str);
|
|
|
|
/**
|
|
* @brief Appends a C-string to the buffer.
|
|
* @param str The C-string to append to the buffer.
|
|
* @return Reference to this LogBuffer for method chaining.
|
|
*/
|
|
LogBuffer& append(const char* str);
|
|
|
|
/**
|
|
* @brief Appends a character sequence to the buffer.
|
|
* @param str Pointer to the character sequence.
|
|
* @param len Length of the character sequence.
|
|
* @return Reference to this LogBuffer for method chaining.
|
|
*/
|
|
LogBuffer& append(const char* str, size_t len);
|
|
|
|
/**
|
|
* @brief Writes a string to the buffer (alias for append).
|
|
* @param str The string to write to the buffer.
|
|
* @return Reference to this LogBuffer for method chaining.
|
|
*/
|
|
LogBuffer& write(const std::string& str);
|
|
|
|
/**
|
|
* @brief Writes a character sequence to the buffer.
|
|
* @param str Pointer to the character sequence.
|
|
* @param len Length of the character sequence.
|
|
* @return Reference to this LogBuffer for method chaining.
|
|
*/
|
|
LogBuffer& write(const char* str, size_t len);
|
|
|
|
/**
|
|
* @brief Resets the buffer for next use.
|
|
*
|
|
* Clears the buffer content and updates the last flush time.
|
|
*
|
|
* @param flush_time The timestamp at which the buffer was flushed.
|
|
*/
|
|
void reset(uint64_t flush_time);
|
|
|
|
/**
|
|
* @brief Sets the last flush time explicitly.
|
|
*
|
|
* @param flush_time The timestamp to set.
|
|
*/
|
|
void set_last_flush_time(uint64_t flush_time);
|
|
|
|
/**
|
|
* @brief Returns the last flush time.
|
|
*/
|
|
uint64_t get_last_flush_time() const;
|
|
|
|
/**
|
|
* @brief Returns true if the buffer is empty.
|
|
*/
|
|
bool empty() const;
|
|
|
|
/**
|
|
* @brief Returns the size of the buffer.
|
|
*/
|
|
size_t size() const;
|
|
|
|
/**
|
|
* @brief Returns a pointer to the buffer data.
|
|
*/
|
|
const char* data() const;
|
|
|
|
/**
|
|
* @brief Flushes the buffer to an output file stream.
|
|
*
|
|
* Writes the entire contents of the buffer to the provided file stream.
|
|
* The caller is responsible for resetting the buffer after flushing.
|
|
*
|
|
* @param logfile The output file stream to write to.
|
|
*/
|
|
void flush_to_file(std::fstream* logfile);
|
|
};
|
|
|
|
/**
|
|
* @brief Class to hold per-thread logging context for both event and audit logging.
|
|
*
|
|
* This class encapsulates all per-thread state needed for logging operations:
|
|
* - events: Buffer and timestamp state for event logging
|
|
* - audit: Buffer and timestamp state for audit logging
|
|
* - rng: Thread-local Mersenne Twister random number generator for log sampling
|
|
* - dist: Uniform real distribution [0.0, 1.0) for sampling
|
|
*
|
|
* Each thread gets its own instance to avoid race conditions and lock contention.
|
|
*/
|
|
class LogBufferThreadContext {
|
|
private:
|
|
std::mt19937 rng; ///< Mersenne Twister random number generator (per-thread)
|
|
std::uniform_real_distribution<double> dist; ///< Uniform distribution [0.0, 1.0)
|
|
|
|
public:
|
|
std::mutex buffer_lock; ///< Protects cross-thread flush operations on thread-local buffers.
|
|
LogBuffer events; ///< Event log buffer and timestamp
|
|
LogBuffer audit; ///< Audit log buffer and timestamp
|
|
|
|
/**
|
|
* @brief Constructor that initializes the thread logging context with random seed.
|
|
*
|
|
* Seeds the RNG using a combination of hardware entropy, high-resolution time,
|
|
* and thread ID for maximum uniqueness and unpredictability.
|
|
*/
|
|
LogBufferThreadContext();
|
|
|
|
/**
|
|
* @brief Determines if an event should be logged based on the rate limit.
|
|
*
|
|
* Calculates whether a random sample falls within the acceptance threshold
|
|
* determined by the rate limit.
|
|
*
|
|
* @param rate_limit The sampling rate limit. 1 means log all, N means log approx 1/N.
|
|
* @return true if the event should be logged, false otherwise.
|
|
*/
|
|
bool should_log(int rate_limit);
|
|
};
|
|
|
|
/**
|
|
* @brief Retrieves or creates the LogBufferThreadContext for the current thread.
|
|
*
|
|
* This helper function checks if a context for the current thread exists in the provided map.
|
|
* If found, it returns the existing context. Otherwise, it creates a new one, initializes
|
|
* it with the current time, and adds it to the map.
|
|
*
|
|
* @param log_thread_contexts The map of thread contexts.
|
|
* @param log_thread_contexts_lock The mutex protecting access to the map.
|
|
* @param current_time The current time to initialize last_flush_time (e.g. monotonic_time()).
|
|
* @return LogBufferThreadContext* Pointer to the thread's logging context.
|
|
*/
|
|
LogBufferThreadContext* GetLogBufferThreadContext(std::unordered_map<pthread_t, std::unique_ptr<LogBufferThreadContext>>& log_thread_contexts, std::mutex& log_thread_contexts_lock, uint64_t current_time);
|
|
|
|
/**
|
|
* @brief Helper function to flush buffer to file stream and rotate file if required.
|
|
*
|
|
* @param buffer The LogBuffer to flush
|
|
* @param logfile Pointer to the logfile stream
|
|
* @param current_log_size Reference to current log size counter
|
|
* @param max_log_file_size Maximum log file size before rotation
|
|
* @param lock_fn Function to acquire write lock
|
|
* @param unlock_fn Function to release write lock
|
|
* @param rotate_fn Function to rotate the log file
|
|
* @param reset_time Timestamp to use when resetting the buffer after flush
|
|
* @return true if buffer was flushed, false otherwise
|
|
*/
|
|
bool flush_and_rotate(
|
|
LogBuffer& buffer,
|
|
std::fstream*& logfile,
|
|
unsigned int& current_log_size,
|
|
unsigned int max_log_file_size,
|
|
std::function<void()> lock_fn,
|
|
std::function<void()> unlock_fn,
|
|
std::function<void()> rotate_fn,
|
|
uint64_t reset_time = 0);
|
|
|
|
/**
|
|
* @brief Returns the protocol-scoped query logger counter.
|
|
* @param protocol Protocol label (e.g. "mysql" or "pgsql").
|
|
* @return Counter pointer or nullptr if Prometheus registry isn't available.
|
|
*/
|
|
prometheus::Counter* get_logger_queries_logged_counter(const std::string& protocol);
|
|
|
|
#endif /* __CLASS_LOG_UTILS_H */
|