mirror of https://github.com/deavmi/dlog.git
Initial commit
This commit is contained in:
commit
5eb73a3fbc
|
@ -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
|
|
@ -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",
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
module dlog;
|
||||
|
||||
/* TODO: Add imports */
|
||||
public import dlog.core;
|
||||
public import dlog.defaults;
|
|
@ -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]);
|
||||
}
|
Loading…
Reference in New Issue