Skip to content

Instantly share code, notes, and snippets.

@TheFlash2k
Last active June 19, 2023 13:44
Show Gist options
  • Save TheFlash2k/c9e311b118b2b2927078d6b48b5a12fe to your computer and use it in GitHub Desktop.
Save TheFlash2k/c9e311b118b2b2927078d6b48b5a12fe to your computer and use it in GitHub Desktop.
/*
logger.hpp - A Single Logging solution.
Author: @TheFlash2k
*/
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <conio.h>
#include <ctime>
#include <stdarg.h>
#include <map>
#include <fstream>
#define BUFFER_SIZE 4096
char LastError[BUFFER_SIZE];
#ifndef ZeroMemory
#define ZeroMemory(buffer, size) memset(buffer, 0, size)
#endif
enum COLOR {
NONE = -1,
RESET = 0,
RED = 31,
GREEN = 32,
YELLOW = 33,
BLUE = 34,
MAGENTA = 35,
CYAN = 36,
WHITE = 37
};
const std::map<std::string, COLOR> colorMap = {
{ "LOG", GREEN },
{ "ERROR", RED },
{ "WARNING", YELLOW },
{ "INFO", BLUE },
{ "MESSAGE", MAGENTA }
};
namespace Logger {
bool globalStore = false;
namespace __base__ {
std::string colorize(const char* str, COLOR color) {
char* buffer = new char[BUFFER_SIZE];
ZeroMemory(buffer, BUFFER_SIZE);
sprintf(buffer, "\x1b[%dm%s\x1b[0m", color, str);
return buffer;
}
std::string getTime(bool colored = false) {
const int T_SIZE = 25;
time_t currTime;
struct tm* infoBuffer;
char timeBuffer[T_SIZE];
ZeroMemory(timeBuffer, T_SIZE);
time(&currTime);
infoBuffer = localtime(&currTime);
strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %H:%M:%S", infoBuffer);
return ((colored) ? colorize(timeBuffer, CYAN) : timeBuffer);
}
std::string getPrepend(const char* type, COLOR color = WHITE) {
const int LONGEST = 7;
std::string prepend;
std::string time = getTime(color != WHITE);
prepend = "[" + time + "] ";
std::string _type = ((color != WHITE) ? colorize(type, color) : type);
prepend += "[" + _type + "] ";
int diff = LONGEST - strlen(type);
for (int i = 0; i < diff; i++) {
prepend += " ";
}
return prepend;
}
const char* __base__(const char* prepend, const char* data, va_list args) {
char* buffer = new char[BUFFER_SIZE];
ZeroMemory(buffer, BUFFER_SIZE);
vsprintf(buffer, prepend, NULL);
vsprintf(buffer + strlen(buffer), data, args);
return buffer;
}
std::string printer(const char* _type, const char* data, va_list args, bool colored = false) {
std::string prepend = getPrepend(_type, (colored) ? colorMap.at(_type) : WHITE);
std::string ret = __base__(prepend.c_str(), data, args);
return ret;
}
bool __writer(std::string buffer, std::string fileName) {
std::ofstream file;
file.open(fileName, std::ios::app);
if (file.is_open()) {
file << buffer << std::endl;
file.close();
}
else {
return false;
}
return true;
}
}
namespace Store {
void __base(std::string fileName, const char* _type, const char* data, va_list args) {
std::string buffer = __base__::printer(_type, data, args);
std::string colored = __base__::printer(_type, data, args, true);
// Only single logs file..
if (!__base__::__writer(buffer, fileName)) {
printf("[!] Unable to write to file [%s]", fileName.c_str());
return;
}
// Global logs
if (!__base__::__writer(buffer, "full.log")) {
printf("[!] Unable to write to file [full.log]");
return;
}
printf("%s\n", colored.c_str());
}
void Log(const char* data, ...) {
const std::string fileName = "logs.txt";
va_list args;
va_start(args, data);
__base(fileName, "LOG", data, args);
va_end(args);
}
void Error(const char* data, ...) {
const std::string fileName = "errors.txt";
va_list args;
va_start(args, data);
__base(fileName, "ERROR", data, args);
va_end(args);
}
void Warning(const char* data, ...) {
const std::string fileName = "warnings.txt";
va_list args;
va_start(args, data);
__base(fileName, "WARNING", data, args);
va_end(args);
}
void Info(const char* data, ...) {
const std::string fileName = "info.txt";
va_list args;
va_start(args, data);
__base(fileName, "INFO", data, args);
va_end(args);
}
void Message(const char* data, ...) {
const std::string fileName = "messages.txt";
va_list args;
va_start(args, data);
__base(fileName, "MESSAGE", data, args);
va_end(args);
}
}
void Log(const char* data, ...) {
va_list args;
va_start(args, data);
if (globalStore) {
Store::Log(data, args);
return;
}
std::string buffer = __base__::printer("LOG", data, args, true);
va_end(args);
printf("%s\n", buffer.c_str());
}
void Error(const char* data, ...) {
va_list args;
va_start(args, data);
if (globalStore) {
Store::Error(data, args);
return;
}
std::string buffer = __base__::printer("ERROR", data, args, true);
va_end(args);
printf("%s\n", buffer.c_str());
}
void Warning(const char* data, ...) {
va_list args;
va_start(args, data);
if (globalStore) {
Store::Warning(data, args);
return;
}
std::string buffer = __base__::printer("WARNING", data, args, true);
va_end(args);
printf("%s\n", buffer.c_str());
}
void Info(const char* data, ...) {
va_list args;
va_start(args, data);
if (globalStore) {
Store::Info(data, args);
return;
}
std::string buffer = __base__::printer("INFO", data, args, true);
va_end(args);
printf("%s\n", buffer.c_str());
}
void Message(const char* data, ...) {
va_list args;
va_start(args, data);
if (globalStore) {
Store::Message(data, args);
return;
}
std::string buffer = __base__::printer("MESSAGE", data, args, true);
va_end(args);
printf("%s\n", buffer.c_str());
}
}
/*
Usage:
```c
#include "logger.hpp"
int main() {
// Set this flag to true if you want to store all logs to the files...
Logger::globalStore = true;
// Since the flag is set to true, this will be stored in logs.txt and full.log files."
Logger::Log("Welcome! @TheFlash2k");
// If the globalStore flag wasn't set, in order to store the logs as well, we'd use:
Logger::Store::Log("Welcome! @TheFlash2k");
return 0;
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment