dev #1
|
@ -2,3 +2,5 @@
|
||||||
.dub
|
.dub
|
||||||
*.o
|
*.o
|
||||||
lib
|
lib
|
||||||
|
bin
|
||||||
|
test.log
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [v0.3.0](https://git.zhirov.kz/dlang/singlog/compare/v0.2.1...v0.3.0) (2023.04.28)
|
||||||
|
|
||||||
|
- Minor changes
|
||||||
|
|
||||||
|
### New
|
||||||
|
|
||||||
|
- Windows OS Logging support
|
||||||
|
|
||||||
## [v0.2.1](https://git.zhirov.kz/dlang/singlog/compare/v0.2.0...v0.2.1) (2023.03.29)
|
## [v0.2.1](https://git.zhirov.kz/dlang/singlog/compare/v0.2.0...v0.2.1) (2023.03.29)
|
||||||
|
|
||||||
### New
|
### New
|
||||||
|
|
33
README.md
33
README.md
|
@ -1,9 +1,11 @@
|
||||||
# singlog
|
![singlog](singlog.png)
|
||||||
|
|
||||||
[![license](https://img.shields.io/github/license/AlexanderZhirov/singlog.svg?sort=semver&style=for-the-badge&color=green)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html)
|
[![license](https://img.shields.io/github/license/AlexanderZhirov/singlog.svg?sort=semver&style=for-the-badge&color=green)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html)
|
||||||
[![main](https://img.shields.io/badge/dynamic/json.svg?label=git.zhirov.kz&style=for-the-badge&url=https://git.zhirov.kz/api/v1/repos/dlang/singlog/tags&query=$[0].name&color=violet)](https://git.zhirov.kz/dlang/singlog)
|
[![main](https://img.shields.io/badge/dynamic/json.svg?label=git.zhirov.kz&style=for-the-badge&url=https://git.zhirov.kz/api/v1/repos/dlang/singlog/tags&query=$[0].name&color=violet)](https://git.zhirov.kz/dlang/singlog)
|
||||||
[![githab](https://img.shields.io/github/v/tag/AlexanderZhirov/singlog.svg?sort=semver&style=for-the-badge&color=blue&label=github)](https://github.com/AlexanderZhirov/singlog)
|
[![githab](https://img.shields.io/github/v/tag/AlexanderZhirov/singlog.svg?sort=semver&style=for-the-badge&color=blue&label=github)](https://github.com/AlexanderZhirov/singlog)
|
||||||
[![dub](https://img.shields.io/dub/v/singlog.svg?sort=semver&style=for-the-badge&color=orange)](https://code.dlang.org/packages/singlog)
|
[![dub](https://img.shields.io/dub/v/singlog.svg?sort=semver&style=for-the-badge&color=orange)](https://code.dlang.org/packages/singlog)
|
||||||
|
[![linux](https://img.shields.io/badge/Linux-FCC624?style=for-the-badge&logo=linux&logoColor=black)](https://www.linux.org/)
|
||||||
|
[![windows](https://img.shields.io/badge/Windows-0078D6?style=for-the-badge&logo=windows&logoColor=white)](https://support.microsoft.com/en-US/windows)
|
||||||
|
|
||||||
Singleton for simple logging
|
Singleton for simple logging
|
||||||
|
|
||||||
|
@ -12,19 +14,27 @@ Singleton for simple logging
|
||||||
```d
|
```d
|
||||||
import singlog;
|
import singlog;
|
||||||
|
|
||||||
void main()
|
void main(string[] argv) {
|
||||||
{
|
log.output(log.SYSLOG | log.STDOUT | log.FILE) // write to syslog, standard output stream and file
|
||||||
log.level(log.DEBUG);
|
.name(argv[0]) // program name as an identifier (for Windows OS)
|
||||||
// write to syslog and file
|
.level(log.DEBUGGING) // logging level
|
||||||
log.output(log.SYSLOG | log.FILE);
|
.file("./test.log"); // the path to the log file
|
||||||
log.file("./file.log");
|
|
||||||
log.warning("Hello, World!");
|
log.e("This is an error message");
|
||||||
log.w("The same thing");
|
log.error("And this is also an error message");
|
||||||
|
log.w("This is a warning message");
|
||||||
|
log.i("This is an information message");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
Setting the name of the logged program (it matters for Windows OS):
|
||||||
|
|
||||||
|
```d
|
||||||
|
log.name("My program");
|
||||||
|
```
|
||||||
|
|
||||||
Setting the error output level:
|
Setting the error output level:
|
||||||
|
|
||||||
```d
|
```d
|
||||||
|
@ -42,7 +52,6 @@ Assigning a target output:
|
||||||
```d
|
```d
|
||||||
log.output(log.SYSLOG);
|
log.output(log.SYSLOG);
|
||||||
log.output(log.STDOUT);
|
log.output(log.STDOUT);
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Setup and allowing writing to a file:
|
Setup and allowing writing to a file:
|
||||||
|
@ -64,6 +73,6 @@ log.i("Information message") => log.information("Information message");
|
||||||
log.d("Debugging message") => log.debugging("Debugging message");
|
log.d("Debugging message") => log.debugging("Debugging message");
|
||||||
```
|
```
|
||||||
|
|
||||||
## Dub
|
## DUB
|
||||||
|
|
||||||
Add a dependency on `"singlog": "~>0.2.1"`.
|
Add a dependency on `"singlog": "~>0.3.0"`.
|
||||||
|
|
17
dub.json
17
dub.json
|
@ -7,9 +7,22 @@
|
||||||
"license": "GPL-2.0",
|
"license": "GPL-2.0",
|
||||||
"copyright": "© Alexander Zhirov, 2023",
|
"copyright": "© Alexander Zhirov, 2023",
|
||||||
"description": "Singleton for simple logging",
|
"description": "Singleton for simple logging",
|
||||||
"targetType": "library",
|
|
||||||
"targetPath": "lib",
|
|
||||||
"targetName": "singlog",
|
"targetName": "singlog",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "library",
|
||||||
|
"targetType": "library",
|
||||||
|
"targetPath": "lib"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "test",
|
||||||
|
"targetType": "executable",
|
||||||
|
"targetPath": "bin",
|
||||||
|
"targetName": "app",
|
||||||
|
"importPaths": ["source","tests"],
|
||||||
|
"sourcePaths": ["tests"]
|
||||||
|
}
|
||||||
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"datefmt": "~>1.0.4"
|
"datefmt": "~>1.0.4"
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
140
source/singlog.d
140
source/singlog.d
|
@ -1,9 +1,13 @@
|
||||||
module singlog;
|
module singlog;
|
||||||
|
|
||||||
import core.sys.posix.syslog;
|
version(Windows)
|
||||||
|
import core.sys.windows.windows;
|
||||||
|
else
|
||||||
|
import core.sys.posix.syslog;
|
||||||
|
|
||||||
|
import std.string;
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
import std.meta;
|
|
||||||
import std.file;
|
import std.file;
|
||||||
import std.datetime;
|
import std.datetime;
|
||||||
import datefmt;
|
import datefmt;
|
||||||
|
@ -14,6 +18,8 @@ alias log = Log.msg;
|
||||||
Singleton for simple logging
|
Singleton for simple logging
|
||||||
|
|
||||||
---
|
---
|
||||||
|
// Setting the name of the logged program
|
||||||
|
log.name("My program");
|
||||||
// Setting the error output level
|
// Setting the error output level
|
||||||
log.level(log.DEBUG);
|
log.level(log.DEBUG);
|
||||||
log.level(log.ALERT);
|
log.level(log.ALERT);
|
||||||
|
@ -28,8 +34,6 @@ alias log = Log.msg;
|
||||||
log.output(log.FILE);
|
log.output(log.FILE);
|
||||||
// Setup and allowing writing to a file
|
// Setup and allowing writing to a file
|
||||||
log.file("./file.log");
|
log.file("./file.log");
|
||||||
log.fileOn();
|
|
||||||
log.fileOff();
|
|
||||||
// Output of messages to the log
|
// Output of messages to the log
|
||||||
log.alert("Alert message");
|
log.alert("Alert message");
|
||||||
log.critical("Critical message");
|
log.critical("Critical message");
|
||||||
|
@ -40,57 +44,87 @@ alias log = Log.msg;
|
||||||
log.debugging("Debugging message");
|
log.debugging("Debugging message");
|
||||||
---
|
---
|
||||||
+/
|
+/
|
||||||
class Log
|
class Log {
|
||||||
{
|
private:
|
||||||
private static Log log;
|
static Log log;
|
||||||
private string path;
|
string path;
|
||||||
private bool writeToFile = true;
|
string nameProgram = "singlog";
|
||||||
private static SysTime time;
|
bool writeToFile = true;
|
||||||
|
|
||||||
|
this() {}
|
||||||
|
|
||||||
// Target output
|
version(Windows) {
|
||||||
enum {
|
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 {
|
||||||
SYSLOG = 1,
|
SYSLOG = 1,
|
||||||
STDOUT = 2,
|
STDOUT = 2,
|
||||||
FILE = 4
|
FILE = 4
|
||||||
}
|
}
|
||||||
|
|
||||||
// Message output level
|
|
||||||
enum {
|
|
||||||
DEBUG = 0,
|
|
||||||
CRIT = 1,
|
|
||||||
ERR = 2,
|
|
||||||
WARNING = 3,
|
|
||||||
NOTICE = 4,
|
|
||||||
INFO = 5,
|
|
||||||
ALERT = 6
|
|
||||||
}
|
|
||||||
|
|
||||||
int msgOutput = STDOUT;
|
int msgOutput = STDOUT;
|
||||||
int msgLevel = INFO;
|
int msgLevel = INFORMATION;
|
||||||
|
|
||||||
private this() {}
|
void writeLog(string message, int msgLevel) {
|
||||||
|
|
||||||
private void writeLog(string message, int msgLevel, int priority)
|
|
||||||
{
|
|
||||||
if (this.msgLevel > msgLevel)
|
if (this.msgLevel > msgLevel)
|
||||||
return;
|
return;
|
||||||
if (this.msgOutput & 1)
|
if (this.msgOutput & 1)
|
||||||
syslog(priority, (message ~ "\0").ptr);
|
syslog(sysLevel[msgLevel], message.toStringz());
|
||||||
if (this.msgOutput & 2)
|
if (this.msgOutput & 2)
|
||||||
writeln(message);
|
writeln(message);
|
||||||
if (this.msgOutput & 4)
|
if (this.msgOutput & 4)
|
||||||
writeFile(message);
|
writeFile(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeFile(string message)
|
void writeFile(string message) {
|
||||||
{
|
|
||||||
if (!this.writeToFile)
|
if (!this.writeToFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this.path.exists)
|
if (!this.path.exists) {
|
||||||
this.writeToFile = true;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.writeToFile = false;
|
this.writeToFile = false;
|
||||||
this.warning("The log file does not exist: " ~ this.path);
|
this.warning("The log file does not exist: " ~ this.path);
|
||||||
}
|
}
|
||||||
|
@ -103,16 +137,16 @@ class Log
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
this.writeToFile = false;
|
this.writeToFile = false;
|
||||||
this.error("Unable to open the log file " ~ this.path);
|
this.error("Unable to open the log file " ~ this.path);
|
||||||
this.critical(e);
|
this.information(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
file.writeln(this.time.format("%Y.%m.%d %H:%M:%S: ") ~ message);
|
file.writeln(Clock.currTime().format("%Y.%m.%d %H:%M:%S: ") ~ message);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
this.writeToFile = false;
|
this.writeToFile = false;
|
||||||
this.error("Unable to write to the log file " ~ this.path);
|
this.error("Unable to write to the log file " ~ this.path);
|
||||||
this.critical(e);
|
this.information(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,33 +155,31 @@ class Log
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
this.writeToFile = false;
|
this.writeToFile = false;
|
||||||
this.error("Unable to close the log file " ~ this.path);
|
this.error("Unable to close the log file " ~ this.path);
|
||||||
this.critical(e);
|
this.information(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@property static Log msg()
|
public:
|
||||||
{
|
@property static Log msg() {
|
||||||
if (this.log is null)
|
if (this.log is null)
|
||||||
{
|
|
||||||
this.log = new Log;
|
this.log = new Log;
|
||||||
this.time = Clock.currTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.log;
|
return this.log;
|
||||||
}
|
}
|
||||||
|
|
||||||
void output(int msgOutput) { this.msgOutput = msgOutput; }
|
Log output(int msgOutput) { this.msgOutput = msgOutput; return this.log; }
|
||||||
void level(int msgLevel) { this.msgLevel = msgLevel; }
|
Log name(string nameProgram) { this.nameProgram = nameProgram; return this.log; }
|
||||||
void file(string path) { this.path = path; }
|
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, LOG_ALERT); }
|
void alert(T)(T message) { writeLog(message.to!string, ALERT); }
|
||||||
void critical(T)(T message) { writeLog(message.to!string, CRIT, LOG_CRIT); }
|
void critical(T)(T message) { writeLog(message.to!string, CRITICAL); }
|
||||||
void error(T)(T message) { writeLog(message.to!string, ERR, LOG_ERR); }
|
void error(T)(T message) { writeLog(message.to!string, ERROR); }
|
||||||
void warning(T)(T message) { writeLog(message.to!string, WARNING, LOG_WARNING); }
|
void warning(T)(T message) { writeLog(message.to!string, WARNING); }
|
||||||
void notice(T)(T message) { writeLog(message.to!string, NOTICE, LOG_NOTICE); }
|
void notice(T)(T message) { writeLog(message.to!string, NOTICE); }
|
||||||
void information(T)(T message) { writeLog(message.to!string, INFO, LOG_INFO); }
|
void information(T)(T message) { writeLog(message.to!string, INFORMATION); }
|
||||||
void debugging(T)(T message) {writeLog(message.to!string, DEBUG, LOG_DEBUG); }
|
void debugging(T)(T message) { writeLog(message.to!string, DEBUG); }
|
||||||
|
|
||||||
alias a = alert;
|
alias a = alert;
|
||||||
alias c = critical;
|
alias c = critical;
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
import singlog;
|
||||||
|
|
||||||
|
void main(string[] argv) {
|
||||||
|
log.output(log.SYSLOG | log.STDOUT | log.FILE) // write to syslog, standard output stream and file
|
||||||
|
.name(argv[0]) // program name as an identifier (for Windows OS)
|
||||||
|
.level(log.DEBUGGING) // logging level
|
||||||
|
.file("./test.log"); // the path to the log file
|
||||||
|
|
||||||
|
log.e("This is an error message");
|
||||||
|
log.error("And this is also an error message");
|
||||||
|
log.w("This is a warning message");
|
||||||
|
log.i("This is an information message");
|
||||||
|
}
|
Loading…
Reference in New Issue