singlog/source/singlog.d

224 lines
6.0 KiB
D
Raw Normal View History

2023-03-23 09:20:46 +00:00
module singlog;
2023-04-27 18:08:12 +00:00
version(Windows)
import core.sys.windows.windows;
else
import core.sys.posix.syslog;
import std.string;
2023-03-23 09:20:46 +00:00
import std.stdio;
import std.conv;
import std.file;
import std.datetime;
import datefmt;
alias log = Log.msg;
2023-03-29 12:53:00 +00:00
2023-03-23 09:20:46 +00:00
/++
Singleton for simple logging
---
2023-04-27 20:53:45 +00:00
// Setting the name of the logged program
2023-06-05 21:17:56 +00:00
log.program("My program");
// Setting the status of color text output
log.color(true);
2023-03-23 09:20:46 +00:00
// Setting the error output level
2023-05-30 16:32:09 +00:00
log.level(log.DEBUGGING);
2023-03-29 12:53:00 +00:00
log.level(log.ALERT);
2023-05-30 16:32:09 +00:00
log.level(log.CRITICAL);
log.level(log.ERROR);
2023-03-29 12:53:00 +00:00
log.level(log.WARNING);
log.level(log.NOTICE);
2023-05-30 16:32:09 +00:00
log.level(log.INFORMATION);
2023-03-23 09:20:46 +00:00
// Assigning a target output
2023-03-29 12:53:00 +00:00
log.output(log.SYSLOG);
log.output(log.STDOUT);
log.output(log.FILE);
2023-03-23 09:20:46 +00:00
// Setup and allowing writing to a file
2023-03-29 12:53:00 +00:00
log.file("./file.log");
2023-03-23 09:20:46 +00:00
// Output of messages to the log
2023-05-30 16:32:09 +00:00
log.debugging("Debugging message");
2023-03-29 12:53:00 +00:00
log.alert("Alert message");
log.critical("Critical message");
log.error("Error message");
log.warning("Warning message");
log.notice("Notice message");
log.informations("Information message");
2023-03-23 09:20:46 +00:00
---
+/
2023-04-27 18:08:12 +00:00
class Log {
private:
2023-06-05 21:17:56 +00:00
static Log _log;
string _path;
string _name = "singlog";
bool _writeToFile = true;
bool _ccolor = false;
2023-04-27 18:08:12 +00:00
this() {}
version(Windows) {
2023-06-05 21:17:56 +00:00
int[] _sysLevel = [0, 1, 1, 1, 2, 3, 4];
WORD[] _sysLevelOS = [
2023-04-27 18:08:12 +00:00
EVENTLOG_SUCCESS,
EVENTLOG_ERROR_TYPE,
EVENTLOG_WARNING_TYPE,
EVENTLOG_INFORMATION_TYPE
];
void syslog(WORD priority, LPCSTR message) {
HANDLE handleEventLog = RegisterEventSourceA(NULL, this.nameProgram.toStringz());
if (handleEventLog == NULL)
return;
ReportEventA(handleEventLog, priority, 0, 0, NULL, 1, 0, &message, NULL);
DeregisterEventSource(handleEventLog);
}
} else version(Posix) {
2023-06-05 21:17:56 +00:00
int[] _sysLevel = [0, 1, 2, 3, 4, 5, 6];
int[] _sysLevelOS = [
2023-04-27 18:08:12 +00:00
LOG_DEBUG,
LOG_ALERT,
LOG_CRIT,
LOG_ERR,
LOG_WARNING,
LOG_NOTICE,
LOG_INFO
];
2023-06-05 21:17:56 +00:00
string[] _color = [
"\x1b[1;32m%s\x1b[0;32m %s\x1b[0;0m", // green
"\x1b[1;34m%s\x1b[0;34m %s\x1b[0;0m", // blue
"\x1b[1;35m%s\x1b[0;35m %s\x1b[0;0m", // magenta
"\x1b[1;31m%s\x1b[0;31m %s\x1b[0;0m", // red
"\x1b[1;33m%s\x1b[0;33m %s\x1b[0;0m", // yellow
"\x1b[1;36m%s\x1b[0;36m %s\x1b[0;0m", // cyan
"\x1b[1;97m%s\x1b[0;97m %s\x1b[0;0m", // white
];
void writestdout(string time, string message, int level) {
writeln("%s %s".format(time,
this._ccolor ?
this._color[level].format(this._type[level], message) :
"%s %s".format(this._type[level], message)
)
);
}
2023-04-27 18:08:12 +00:00
}
2023-06-05 21:17:56 +00:00
public enum {
DEBUGGING = 0,
ALERT = 1,
CRITICAL = 2,
ERROR = 3,
WARNING = 4,
NOTICE = 5,
INFORMATION = 6
}
string[] _type = [
"[DEBUG]:",
"[ALERT]:",
"[CRITICAL]:",
"[ERROR]:",
"[WARNING]:",
"[NOTICE]:",
"[INFO]:"
2023-06-05 18:33:02 +00:00
];
2023-04-27 18:08:12 +00:00
public enum {
2023-03-29 12:53:00 +00:00
SYSLOG = 1,
STDOUT = 2,
FILE = 4
}
2023-03-23 09:20:46 +00:00
2023-06-05 21:17:56 +00:00
int _output = STDOUT;
int _level = INFORMATION;
2023-03-23 09:20:46 +00:00
2023-06-05 21:17:56 +00:00
void writeLog(string message, int level) {
string time;
if (this._level > level)
2023-03-23 09:20:46 +00:00
return;
2023-06-05 21:17:56 +00:00
if (this._output & 1)
syslog(_sysLevelOS[_sysLevel[level]], message.toStringz());
if (this._output & 6)
time = Clock.currTime().format("%Y.%m.%d %H:%M:%S");
if (this._output & 2)
writestdout(time, message, level);
if (this._output & 4)
writeFile(time, message, level);
2023-03-23 09:20:46 +00:00
}
2023-06-05 21:17:56 +00:00
void writeFile(string time, string message, int level) {
if (!this._writeToFile)
2023-03-23 09:20:46 +00:00
return;
2023-06-05 21:17:56 +00:00
if (!this._path.exists) {
this._writeToFile = false;
this.warning("The log file does not exist: " ~ this._path);
2023-03-23 09:20:46 +00:00
}
File file;
try {
2023-06-05 21:17:56 +00:00
file = File(this._path, "a+");
this._writeToFile = true;
2023-03-23 09:20:46 +00:00
} catch (Exception e) {
2023-06-05 21:17:56 +00:00
this._writeToFile = false;
this.error("Unable to open the log file " ~ this._path);
2023-04-27 18:08:12 +00:00
this.information(e);
2023-03-23 09:20:46 +00:00
return;
}
try {
2023-06-05 21:17:56 +00:00
file.writeln("%s %s %s".format(time, this._type[level], message));
2023-03-23 09:20:46 +00:00
} catch (Exception e) {
2023-06-05 21:17:56 +00:00
this._writeToFile = false;
this.error("Unable to write to the log file " ~ this._path);
2023-04-27 18:08:12 +00:00
this.information(e);
2023-03-23 09:20:46 +00:00
return;
}
try {
file.close();
} catch (Exception e) {
2023-06-05 21:17:56 +00:00
this._writeToFile = false;
this.error("Unable to close the log file " ~ this._path);
2023-04-27 18:08:12 +00:00
this.information(e);
2023-03-23 09:20:46 +00:00
return;
}
}
2023-04-27 18:08:12 +00:00
public:
@property static Log msg() {
2023-06-05 21:17:56 +00:00
if (this._log is null)
this._log = new Log;
2023-03-23 09:20:46 +00:00
2023-06-05 21:17:56 +00:00
return this._log;
2023-03-23 09:20:46 +00:00
}
2023-06-05 21:17:56 +00:00
Log output(int outs) { this._output = outs; return this._log; }
Log program(string name) { this._name = name; return this._log; }
Log file(string path) { this._path = path; return this._log; }
Log level(int lvl) { this._level = lvl; return this._log; }
Log color(bool condition) { this._ccolor = condition; return this._log; }
2023-04-27 18:08:12 +00:00
2023-06-05 18:33:02 +00:00
void alert(T)(T message) { writeLog(message.to!string, ALERT); }
void critical(T)(T message) { writeLog(message.to!string, CRITICAL); }
void error(T)(T message) { writeLog(message.to!string, ERROR); }
void warning(T)(T message) { writeLog(message.to!string, WARNING); }
void notice(T)(T message) { writeLog(message.to!string, NOTICE); }
void information(T)(T message) { writeLog(message.to!string, INFORMATION); }
void debugging(T)(T message) { writeLog(message.to!string, DEBUGGING); }
alias a = alert;
alias c = critical;
alias e = error;
alias w = warning;
alias n = notice;
alias i = information;
alias d = debugging;
2023-03-23 09:20:46 +00:00
}