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;
|
|
|
|
|
2023-03-29 15:13:56 +00:00
|
|
|
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
|
|
|
|
log.name("My program");
|
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:
|
|
|
|
static Log log;
|
|
|
|
string path;
|
|
|
|
string nameProgram = "singlog";
|
|
|
|
bool writeToFile = true;
|
|
|
|
|
|
|
|
this() {}
|
|
|
|
|
|
|
|
version(Windows) {
|
|
|
|
public enum {
|
|
|
|
DEBUGGING = 0,
|
|
|
|
ALERT = 1,
|
|
|
|
CRITICAL = 1,
|
|
|
|
ERROR = 1,
|
|
|
|
WARNING = 2,
|
|
|
|
NOTICE = 3,
|
|
|
|
INFORMATION = 3,
|
|
|
|
}
|
|
|
|
WORD[] sysLevel = [
|
|
|
|
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) {
|
|
|
|
public enum {
|
|
|
|
DEBUGGING = 0,
|
|
|
|
ALERT = 1,
|
|
|
|
CRITICAL = 2,
|
|
|
|
ERROR = 3,
|
|
|
|
WARNING = 4,
|
|
|
|
NOTICE = 5,
|
|
|
|
INFORMATION = 6
|
|
|
|
}
|
|
|
|
int[] sysLevel = [
|
|
|
|
LOG_DEBUG,
|
|
|
|
LOG_ALERT,
|
|
|
|
LOG_CRIT,
|
|
|
|
LOG_ERR,
|
|
|
|
LOG_WARNING,
|
|
|
|
LOG_NOTICE,
|
|
|
|
LOG_INFO
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
public enum {
|
2023-03-29 12:53:00 +00:00
|
|
|
SYSLOG = 1,
|
|
|
|
STDOUT = 2,
|
|
|
|
FILE = 4
|
|
|
|
}
|
2023-03-23 09:20:46 +00:00
|
|
|
|
|
|
|
int msgOutput = STDOUT;
|
2023-04-27 18:08:12 +00:00
|
|
|
int msgLevel = INFORMATION;
|
2023-03-23 09:20:46 +00:00
|
|
|
|
2023-04-27 18:08:12 +00:00
|
|
|
void writeLog(string message, int msgLevel) {
|
2023-03-23 09:20:46 +00:00
|
|
|
if (this.msgLevel > msgLevel)
|
|
|
|
return;
|
2023-03-29 12:53:00 +00:00
|
|
|
if (this.msgOutput & 1)
|
2023-04-27 18:08:12 +00:00
|
|
|
syslog(sysLevel[msgLevel], message.toStringz());
|
2023-03-29 12:53:00 +00:00
|
|
|
if (this.msgOutput & 2)
|
|
|
|
writeln(message);
|
|
|
|
if (this.msgOutput & 4)
|
|
|
|
writeFile(message);
|
2023-03-23 09:20:46 +00:00
|
|
|
}
|
|
|
|
|
2023-04-27 18:08:12 +00:00
|
|
|
void writeFile(string message) {
|
2023-03-29 12:53:00 +00:00
|
|
|
if (!this.writeToFile)
|
2023-03-23 09:20:46 +00:00
|
|
|
return;
|
|
|
|
|
2023-04-28 08:32:15 +00:00
|
|
|
if (!this.path.exists) {
|
2023-03-29 12:53:00 +00:00
|
|
|
this.writeToFile = false;
|
2023-03-23 09:20:46 +00:00
|
|
|
this.warning("The log file does not exist: " ~ this.path);
|
|
|
|
}
|
|
|
|
|
|
|
|
File file;
|
|
|
|
|
|
|
|
try {
|
|
|
|
file = File(this.path, "a+");
|
2023-03-29 12:53:00 +00:00
|
|
|
this.writeToFile = true;
|
2023-03-23 09:20:46 +00:00
|
|
|
} catch (Exception e) {
|
2023-03-29 12:53:00 +00:00
|
|
|
this.writeToFile = false;
|
2023-03-23 09:20:46 +00:00
|
|
|
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-04-27 18:08:12 +00:00
|
|
|
file.writeln(Clock.currTime().format("%Y.%m.%d %H:%M:%S: ") ~ message);
|
2023-03-23 09:20:46 +00:00
|
|
|
} catch (Exception e) {
|
2023-03-29 12:53:00 +00:00
|
|
|
this.writeToFile = false;
|
2023-03-23 09:20:46 +00:00
|
|
|
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-03-29 12:53:00 +00:00
|
|
|
this.writeToFile = false;
|
2023-03-23 09:20:46 +00:00
|
|
|
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-03-23 09:20:46 +00:00
|
|
|
if (this.log is null)
|
|
|
|
this.log = new Log;
|
|
|
|
|
|
|
|
return this.log;
|
|
|
|
}
|
|
|
|
|
2023-04-27 18:08:12 +00:00
|
|
|
Log output(int msgOutput) { this.msgOutput = msgOutput; return this.log; }
|
|
|
|
Log name(string nameProgram) { this.nameProgram = nameProgram; return this.log; }
|
|
|
|
Log file(string path) { this.path = path; return this.log; }
|
|
|
|
Log level(int msgLevel) { this.msgLevel = msgLevel; return this.log; }
|
|
|
|
|
|
|
|
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); }
|
2023-05-30 16:32:09 +00:00
|
|
|
void debugging(T)(T message) { writeLog(message.to!string, DEBUGGING); }
|
2023-03-29 15:13:56 +00:00
|
|
|
|
|
|
|
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
|
|
|
}
|