Initial commit

This commit is contained in:
Tristan B. Velloza Kildaire 2021-12-23 12:14:36 +02:00
commit 5eb73a3fbc
6 changed files with 292 additions and 0 deletions

91
README.md Normal file
View File

@ -0,0 +1,91 @@
dlog
====
**Simple and modular logging library**
<center>
`[2021-Dec-23 11:17:35.3527637] (source/dlog/testing/thing.d:12): This is a log message`
</center>
---
## Usage
We recommend you use [dub](http://code.dlang.org) to add dlog to your project as follows:
```
dub add dlog
```
### Components
dlog is formed out of two main components:
1. `Logger`
* The logger contains the needed barebones for facilitating the actual logging of text
2. `MessageTransform`
* A MessageTransform is attached to a logger and performs manipulation on the text input into the logger for logging
* They may be chained as to perform multiple transformations in a stream-like fashion
### Quick start
If you want to immediately begin logging text usin the defaults and don't care about implementing your own transformations then you can
simply use the defaulkt logger as follows:
```d
import dlog;
Logger logger = new DefaultLogger();
logger.log("This is a log message");
logger.log(1);
logger.log(1==1);
logger.log([1,2,3]);
```
This will output the following:
```
[2021-Dec-23 11:17:35.3527637] (source/dlog/testing/thing.d:12): This is a log message
[2021-Dec-23 11:17:35.3527717] (source/dlog/testing/thing.d:13): 1
[2021-Dec-23 11:17:35.3527789] (source/dlog/testing/thing.d:14): true
[2021-Dec-23 11:17:35.3527871] (source/dlog/testing/thing.d:15): [1, 2, 3]
```
As you can see file and line numbering of where the `log()` function is called appears in the log message which can be quite helpful
for debugging.
### Custom loggers
Perhaps the default transformation, `DefaultTransform`, may not be what you want. Maybe you want the module name included in the logged
messages or perhaps don't want the date-and-timestamp included at all. All of this can be up to you if you choose to implement your own
message transform.
You will need to start off with a class that inherits from the `MessageTransform` class and then which overrides the `transform` method as shown below:
```d
import dlog;
public class CustomTranform : MessageTransform
{
public override string transform(string text, string[] context)
{
string transformed;
return transformed;
}
}
```
Additional information, besides the text being logged itself (this is the `string text` argument), comes in the form of a string array as `string[] context`
the contents of which are described below:
1. `context[0]`
TODO
## License
LGPLv2

10
dub.json Normal file
View File

@ -0,0 +1,10 @@
{
"authors": [
"Tristan B. Kildaire"
],
"copyright": "Copyright © 2021, Tristan B. Kildaire",
"description": "Simple and modular logging library",
"license": "LGPLv2",
"name": "dlog",
"targetType": "library",
}

148
source/dlog/core.d Normal file
View File

@ -0,0 +1,148 @@
module dlog.core;
import std.conv : to;
import dlog.defaults;
/**
* DefaultTransform
*
* Provides a transformation of the kind
*
* [date+time] (srcFile:lineNumber): message `\n`
*/
public final class DefaultTransform : MessageTransform
{
/**
* Our transformation
*/
public override string transform(string text, string[] context)
{
string message;
/* Date and time */
import std.datetime.systime : Clock, SysTime;
SysTime currTime = Clock.currTime();
import std.conv : to;
string timestamp = to!(string)(currTime);
message = "["~timestamp~"]";
/* Module information */
message = message ~ "\t(";
message = message ~ context[1]~":"~context[2];
message = message ~ "): "~text;
/* Add trailing newline */
message = message ~ '\n';
return message;
}
}
/**
* Logger
*
* Represents a logger instance
*/
public class Logger
{
/* Starting transformation */
private MessageTransform messageTransform;
/**
* Constructs a new Logger with the default
* MessageTransform, see TODO (ref module)
*/
this()
{
this(new DefaultTransform());
}
/**
* Constructs a new Logger with the given
* MessageTransform
*/
this(MessageTransform messageTransform)
{
this.messageTransform = messageTransform;
}
/**
* Log a message
*/
public final void log(TextType)(TextType message, string c1 = __FILE_FULL_PATH__,
string c2 = __FILE__, ulong c3 = __LINE__,
string c4 = __MODULE__, string c5 = __FUNCTION__,
string c6 = __PRETTY_FUNCTION__, string[] contextExtras = null)
{
/* Construct context array */
string[] context = [c1, c2, to!(string)(c3), c4, c5, c6]~contextExtras;
/* Apply the transformation on the message */
string transformedMesage = messageTransform.execute(to!(string)(message), context);
/* Call the underlying logger implementation */
logImpl(transformedMesage);
}
/**
* Logging implementation, this is where the fina
* transformed text will be transferred to and finally
* logged
*/
protected abstract void logImpl(string message);
}
/**
* MessageTransform
*
* A message transform takes in text, applies
* a transformation to it and outputs said text
*
* Transforms may be chained
*/
public abstract class MessageTransform
{
/* Next transformation (if any) */
private MessageTransform chainedTransform;
/* Transformation (implement this) */
public abstract string transform(string text, string[] context);
/* Chain a transform */
public final void chain(MessageTransform transform)
{
chainedTransform = transform;
}
/* Perform the transformation */
public final string execute(string text, string[] context)
{
/* Perform the transformation */
string transformedText = transform(text, context);
/* If there is a chained transformation */
if(chainedTransform)
{
transformedText = chainedTransform.execute(transformedText, context);
}
return transformedText;
}
}
/**
* Tests the DefaultLogger
*/
unittest
{
Logger logger = new DefaultLogger();
logger.log("This is a log message");
logger.log(1);
logger.log(1.1);
logger.log(true);
logger.log([1,2,3]);
logger.log('f');
logger.log(logger);
}

22
source/dlog/defaults.d Normal file
View File

@ -0,0 +1,22 @@
module dlog.defaults;
import dlog.core : Logger;
/**
* DefaultLogger
*
* The default logger logs to standard output (fd 0)
*/
public final class DefaultLogger : Logger
{
this()
{
/* Use the DefaultTransform */
}
protected override void logImpl(string message)
{
import std.stdio : write;
write(message);
}
}

5
source/dlog/package.d Normal file
View File

@ -0,0 +1,5 @@
module dlog;
/* TODO: Add imports */
public import dlog.core;
public import dlog.defaults;

View File

@ -0,0 +1,16 @@
module dlog.testing.thing;
import dlog;
/**
* Tests the DefaultLogger
*/
unittest
{
Logger logger = new DefaultLogger();
logger.log("This is a log message");
logger.log(1);
logger.log(true);
logger.log([1,2,3]);
}