lcpex enhancements - initial commit

This commit is contained in:
2025-08-04 15:20:11 +05:30
parent 879f07ec4b
commit 08c9d5bf07
6 changed files with 597 additions and 103 deletions

View File

@@ -19,6 +19,13 @@
*/
#include "Logger.h"
#include <string>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <unistd.h> // For FdGuard
#include <fcntl.h> // For O_RDONLY, O_WRONLY, open()
#include "../lcpex/FileHandle.h" // Include the FdGuard header
Logger::Logger( int LOG_LEVEL, std::string mask )
{
@@ -26,6 +33,11 @@ Logger::Logger( int LOG_LEVEL, std::string mask )
this->mask = mask;
}
// Destructor added in the update
Logger::~Logger() {
}
void Logger::log( int LOG_LEVEL, std::string msg )
{
std::string ERR = "XXXX";
@@ -42,7 +54,7 @@ void Logger::log( int LOG_LEVEL, std::string msg )
std::string s_msg = "[" + ERR + "] " + msg;
if ( LOG_LEVEL == E_FATAL | LOG_LEVEL == E_WARN )
if ( LOG_LEVEL == E_FATAL || LOG_LEVEL == E_WARN )
{
std::cerr << "[" << get_8601() << "] [" << ERR << "] " << "[" << this->mask << "] " << msg.c_str() << std::endl;
} else {
@@ -53,6 +65,138 @@ void Logger::log( int LOG_LEVEL, std::string msg )
void Logger::log_task( int LOG_LEVEL, std::string task_name, std::string msg )
{
std::string final_msg = "[" + task_name + "] " + msg;
this->log( LOG_LEVEL, final_msg );
// Added memory management from the updated file
size_t task_msg_len = task_name.length() + msg.length() + 4;
char* task_msg = (char*)malloc(task_msg_len);
if (task_msg) {
snprintf(task_msg, task_msg_len, "[%s] %s", task_name.c_str(), msg.c_str());
log(LOG_LEVEL, task_msg);
free(task_msg);
}
}
// JSON logging method
void Logger::create_json_log_entry(char* buffer, size_t buffer_size,
const char* log_level, const char* message,
const char* user, const char* group,
const char* command)
{
std::string timestamp = get_current_timestamp();
snprintf(buffer, buffer_size,
"{\n"
" \"timestamp\": \"%s\",\n"
" \"log_level\": \"%s\",\n"
" \"message\": \"%s\",\n"
" \"context\": {\n"
" \"user\": \"%s\",\n"
" \"group\": \"%s\",\n"
" \"command\": \"%s\"\n"
" }\n"
"}",
timestamp.c_str(), log_level, message, user, group, command);
}
// Add methods for user/group name and timestamp
std::string Logger::get_user_name()
{
struct passwd* pw = getpwuid(getuid());
if (pw) {
return std::string(pw->pw_name);
}
return "unknown";
}
std::string Logger::get_group_name()
{
struct group* grp = getgrgid(getgid());
if (grp) {
return std::string(grp->gr_name);
}
return "unknown";
}
std::string Logger::get_current_timestamp()
{
time_t now = time(NULL);
struct tm* timeinfo = localtime(&now);
char buffer[64];
strftime(buffer, sizeof(buffer), "%Y-%m-%d_%H:%M:%S", timeinfo);
return std::string(buffer);
}
//Log to JSON file
void Logger::log_to_json_file(const std::string& log_level, const std::string& message,
const std::string& user, const std::string& group,
const std::string& command, bool log_to_console)
{
// Log to console if requested
const char* log_level_str = "UNKNOWN";
if (log_level == "E_INFO") log_level_str = "INFO";
else if (log_level == "E_FATAL") log_level_str = "FATAL";
else if (log_level == "E_WARN") log_level_str = "WARN";
else if (log_level == "E_DEBUG") log_level_str = "DEBUG";
if (log_to_console && (log_level_str == "INFO" || log_level_str == "FATAL")) {
std::string timestamp = get_current_timestamp();
printf("[%s] [%s] [%s] %s\n", timestamp.c_str(), log_level_str, this->mask.c_str(), message.c_str());
fflush(stdout);
}
// 2. Create JSON log entry
char json_log[2048];
create_json_log_entry(json_log, sizeof(json_log), log_level_str, message.c_str(), user.c_str(), group.c_str(), command.c_str());
// 3. Generate filename
std::string timestamp = get_current_timestamp();
std::string filename = "log_" + timestamp + ".json";
// 4. Use FdGuard for file handling (to manage file opening and closing)
FdGuard check_file(open(filename.c_str(), O_RDONLY));
bool file_empty = true;
if (check_file.get() != -1) {
off_t file_size = lseek(check_file.get(), 0, SEEK_END);
file_empty = (file_size == 0);
}
if (file_empty) {
// First entry - create new JSON array
FdGuard json_file(open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644));
if (json_file.get() != -1) {
dprintf(json_file.get(), "[\n %s\n]\n", json_log);
} else {
fprintf(stderr, "Failed to open log file for writing: %s\n", filename.c_str());
}
} else {
// Subsequent entries - handle JSON array properly
FdGuard read_file(open(filename.c_str(), O_RDONLY));
if (read_file.get() == -1) {
fprintf(stderr, "Failed to open log file for reading: %s\n", filename.c_str());
return;
}
off_t file_size = lseek(read_file.get(), 0, SEEK_END);
lseek(read_file.get(), 0, SEEK_SET);
char* content = (char*)malloc(file_size + 1);
if (!content) {
fprintf(stderr, "Failed to allocate memory for file content\n");
return;
}
read(read_file.get(), content, file_size);
content[file_size] = '\0';
// Find and remove the last ']'
char* last_bracket = strrchr(content, ']');
if (last_bracket) {
*last_bracket = '\0';
}
FdGuard write_file(open(filename.c_str(), O_WRONLY | O_TRUNC, 0644));
if (write_file.get() != -1) {
dprintf(write_file.get(), "%s,\n %s\n]\n", content, json_log);
} else {
fprintf(stderr, "Failed to open log file for writing: %s\n", filename.c_str());
}
free(content);
}
}

View File

@@ -24,8 +24,14 @@
#include <string>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <fcntl.h> // For O_RDONLY, O_WRONLY, open()
#include <ctime>
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
#include <memory>
#include <cstdarg> // for va_list in FileGuard::printf
#include "../misc/helpers.h"
enum L_LVL {
@@ -37,15 +43,28 @@ enum L_LVL {
class Logger {
public:
Logger( int LOG_LEVEL, std::string mask );
void log( int LOG_LEVEL, std::string msg );
void log_task( int LOG_LEVEL, std::string task_name, std::string msg );
// Constructor and Destructor
Logger(int LOG_LEVEL, std::string mask);
~Logger(); // Added Destructor
// Logging methods
void log(int LOG_LEVEL, std::string msg);
void log_task(int LOG_LEVEL, std::string task_name, std::string msg);
void log_to_json_file(const std::string& log_level, const std::string& message,
const std::string& user, const std::string& group,
const std::string& command, bool log_to_console = true);
// Helper methods
std::string get_current_timestamp();
std::string get_user_name();
std::string get_group_name();
private:
int LOG_LEVEL;
std::string mask;
// Internal helper methods
void create_json_log_entry(char* buffer, size_t buffer_size,
const char* log_level, const char* message,
const char* user, const char* group,
const char* command);
};
#endif //REX_LOGGER_H