diff --git a/source/dlog/nu/basic.d b/source/dlog/basic.d similarity index 88% rename from source/dlog/nu/basic.d rename to source/dlog/basic.d index 77ab8e6..49fe6bc 100644 --- a/source/dlog/nu/basic.d +++ b/source/dlog/basic.d @@ -1,6 +1,6 @@ -module dlog.nu.basic; +module dlog.basic; -import dlog.nu.core; +import dlog.core; public class BasicMessage : Message { @@ -64,11 +64,29 @@ public class FileHandler : Handler } } +/** + * Logging level + */ public enum Level { + /** + * Error message + */ ERROR, - WARNING, + + /** + * Informative message + */ INFO, + + /** + * Warning message + */ + WARN, + + /** + * Debugging message + */ DEBUG } diff --git a/source/dlog/context.d b/source/dlog/context.d deleted file mode 100644 index 6e3a465..0000000 --- a/source/dlog/context.d +++ /dev/null @@ -1,161 +0,0 @@ -/** - * Context for logging - */ - -module dlog.context; - -import std.conv : to; - -/** - * Debugging trace level - */ -public enum Level -{ - /** - * Informative message - */ - INFO, - - /** - * Warning message - */ - WARN, - - /** - * Error message - */ - ERROR, - - /** - * Debugging message - */ - DEBUG -} - -/** - * Context that is passed in with the call to log - */ -public class Context -{ - private CompilationInfo lineInfo; - private Level level; - - /** - * Constructs a new Context - */ - this() - { - - } - - /** - * Set the line information - * - * Params: - * lineInfo = the CompilationInfo struct to use - */ - public final void setLineInfo(CompilationInfo lineInfo) - { - this.lineInfo = lineInfo; - } - - /** - * Obtain the line information generated at compilation - * time - * - * Returns: the CompilationInfo struct - */ - public final CompilationInfo getLineInfo() - { - return lineInfo; - } - - /** - * Returns the current tarce level - * - * Returns: the Level - */ - public final Level getLevel() - { - return level; - } - - /** - * Set the trace level - * - * Params: - * level = the Level to use - */ - public final void setLevel(Level level) - { - this.level = level; - } -} - -/** - * Information obtained during compilation time (if any) - */ -public struct CompilationInfo -{ - /** - * compile time usage file - */ - public string fullFilePath; - - /** - * compile time usage file (relative) - */ - public string file; - - /** - * compile time usage line number - */ - public ulong line; - - /** - * compile time usage module - */ - public string moduleName; - - /** - * compile time usage function - */ - public string functionName; - - /** - * compile time usage function (pretty) - */ - public string prettyFunctionName; - - /** - * Constructs the compilation information with the provided - * parameters - * - * Params: - * __FILE_FULL_PATH__ = compile time usage file - * __FILE__ = compile time usage file (relative) - * __LINE__ = compile time usage line number - * __MODULE__ = compile time usage module - * __FUNCTION__ = compile time usage function - * __PRETTY_FUNCTION__ = compile time usage function (pretty) - */ - this(string fullFilePath, string file, ulong line, string moduleName, string functionName, string prettyFunctionName) - { - this.fullFilePath = fullFilePath; - this.file = file; - this.line = line; - this.moduleName = moduleName; - this.functionName = functionName; - this.prettyFunctionName = prettyFunctionName; - } - - /** - * Flattens the known compile-time information into a string array - * - * Returns: a string[] - */ - public string[] toArray() - { - return [fullFilePath, file, to!(string)(line), moduleName, functionName, prettyFunctionName]; - } -} \ No newline at end of file diff --git a/source/dlog/core.d b/source/dlog/core.d index a00bb66..395d9aa 100644 --- a/source/dlog/core.d +++ b/source/dlog/core.d @@ -1,441 +1,150 @@ -/** - * Core logging services - */ module dlog.core; -import std.conv : to; -import std.range : join; -import dlog.transform : MessageTransform; -import dlog.defaults; -import dlog.context : Context, CompilationInfo, Level; -import dlog.utilities : flatten; - -/** -* Logger -* -* Represents a logger instance -*/ -public class Logger +public class Message { - /* Starting transformation */ - private MessageTransform messageTransform; - - /** - * The multiple argument joiner - */ - protected string multiArgJoiner; - /** - * Constructs a new Logger with the default - * MessageTransform - * - * Params: - * multiArgJoiner = optional joiner for segmented prints (default is " ") - */ - this(string multiArgJoiner = " ") - { - this(new DefaultTransform(), multiArgJoiner); - } - - /** - * Constructs a new Logger with the provided - * custom message transform - * Params: - * messageTransform = the message transform to use - * multiArgJoiner = optional joiner for segmented prints (default is " ") - */ - this(MessageTransform messageTransform, string multiArgJoiner = " ") - { - this.messageTransform = messageTransform; - this.multiArgJoiner = multiArgJoiner; - } - - /** - * Given an arbitrary amount of arguments, convert each to a string - * and return it as an array joined by the joiner - * - * Params: - * segments = alias sequence - * Returns: a string of the argumnets - */ - public string args(TextType...)(TextType segments) - { - /* The flattened components */ - string[] components = flatten(segments); - - /* Join all `components` into a single string */ - string joined = join(components, multiArgJoiner); - - return joined; - } - - - /** - * Logs the given string using the default context - * - * Params: - * text = the string to log - * __FILE_FULL_PATH__ = compile time usage file - * __FILE__ = compile time usage file (relative) - * __LINE__ = compile time usage line number - * __MODULE__ = compile time usage module - * __FUNCTION__ = compile time usage function - * __PRETTY_FUNCTION__ = compile time usage function (pretty) - */ - public final void log(string text, string c1 = __FILE_FULL_PATH__, - string c2 = __FILE__, ulong c3 = __LINE__, - string c4 = __MODULE__, string c5 = __FUNCTION__, - string c6 = __PRETTY_FUNCTION__) - { - /* Use the default context `Context` */ - Context defaultContext = new Context(); - - /* Build up the line information */ - CompilationInfo compilationInfo = CompilationInfo(c1, c2, c3, c4, c5, c6); - - /* Set the line information in the context */ - defaultContext.setLineInfo(compilationInfo); - - /* Call the log */ - logc(defaultContext, text, c1, c2, c3, c4, c5, c6); - } - - /** - * Logs using the default context an arbitrary amount of arguments - * - * Params: - * segments = the arbitrary argumnets (alias sequence) - * __FILE_FULL_PATH__ = compile time usage file - * __FILE__ = compile time usage file (relative) - * __LINE__ = compile time usage line number - * __MODULE__ = compile time usage module - * __FUNCTION__ = compile time usage function - * __PRETTY_FUNCTION__ = compile time usage function (pretty) - */ - public final void log(TextType...)(TextType segments, string c1 = __FILE_FULL_PATH__, - string c2 = __FILE__, ulong c3 = __LINE__, - string c4 = __MODULE__, string c5 = __FUNCTION__, - string c6 = __PRETTY_FUNCTION__) - { - /** - * Grab at compile-time all arguments and generate runtime code to add them to `components` - */ - string[] components = flatten(segments); - - /* Join all `components` into a single string */ - string messageOut = join(components, multiArgJoiner); - - /* Call the log (with text and default context) */ - log(messageOut, c1, c2, c3, c4, c5, c6); - } - - /** - * Logs the given string using the provided context - * - * Params: - * context = the custom context to use - * text = the string to log - * __FILE_FULL_PATH__ = compile time usage file - * __FILE__ = compile time usage file (relative) - * __LINE__ = compile time usage line number - * __MODULE__ = compile time usage module - * __FUNCTION__ = compile time usage function - * __PRETTY_FUNCTION__ = compile time usage function (pretty) - */ - public final void logc(Context context, string text, string c1 = __FILE_FULL_PATH__, - string c2 = __FILE__, ulong c3 = __LINE__, - string c4 = __MODULE__, string c5 = __FUNCTION__, - string c6 = __PRETTY_FUNCTION__) - { - /* Build up the line information */ - CompilationInfo compilationInfo = CompilationInfo(c1, c2, c3, c4, c5, c6); - - /* Set the line information in the context */ - context.setLineInfo(compilationInfo); - - /* Apply the transformation on the message */ - string transformedMesage = messageTransform.execute(text, context); - - /* Call the underlying logger implementation */ - logImpl(transformedMesage); - } - - /** - * Logs using the default context an arbitrary amount of arguments - * specifically setting the context's level to ERROR - * - * Params: - * segments = the arbitrary argumnets (alias sequence) - * __FILE_FULL_PATH__ = compile time usage file - * __FILE__ = compile time usage file (relative) - * __LINE__ = compile time usage line number - * __MODULE__ = compile time usage module - * __FUNCTION__ = compile time usage function - * __PRETTY_FUNCTION__ = compile time usage function (pretty) - */ - public void error(TextType...)(TextType segments, - string c1 = __FILE_FULL_PATH__, - string c2 = __FILE__, ulong c3 = __LINE__, - string c4 = __MODULE__, string c5 = __FUNCTION__, - string c6 = __PRETTY_FUNCTION__) - { - /* Use the default context `Context` */ - Context defaultContext = new Context(); - - /* Build up the line information */ - CompilationInfo compilationInfo = CompilationInfo(c1, c2, c3, c4, c5, c6); - - /* Set the line information in the context */ - defaultContext.setLineInfo(compilationInfo); - - /* Set the level to ERROR */ - defaultContext.setLevel(Level.ERROR); - - /** - * Grab at compile-time all arguments and generate runtime code to add them to `components` - */ - string[] components = flatten(segments); - - /* Join all `components` into a single string */ - string messageOut = join(components, multiArgJoiner); - - /* Call the log */ - logc(defaultContext, messageOut, c1, c2, c3, c4, c5, c6); - } - - /** - * Logs using the default context an arbitrary amount of arguments - * specifically setting the context's level to INFO - * - * Params: - * segments = the arbitrary argumnets (alias sequence) - * __FILE_FULL_PATH__ = compile time usage file - * __FILE__ = compile time usage file (relative) - * __LINE__ = compile time usage line number - * __MODULE__ = compile time usage module - * __FUNCTION__ = compile time usage function - * __PRETTY_FUNCTION__ = compile time usage function (pretty) - */ - public void info(TextType...)(TextType segments, - string c1 = __FILE_FULL_PATH__, - string c2 = __FILE__, ulong c3 = __LINE__, - string c4 = __MODULE__, string c5 = __FUNCTION__, - string c6 = __PRETTY_FUNCTION__) - { - /* Use the default context `Context` */ - Context defaultContext = new Context(); - - /* Build up the line information */ - CompilationInfo compilationInfo = CompilationInfo(c1, c2, c3, c4, c5, c6); - - /* Set the line information in the context */ - defaultContext.setLineInfo(compilationInfo); - - /* Set the level to INFO */ - defaultContext.setLevel(Level.INFO); - - /** - * Grab at compile-time all arguments and generate runtime code to add them to `components` - */ - string[] components = flatten(segments); - - /* Join all `components` into a single string */ - string messageOut = join(components, multiArgJoiner); - - /* Call the log */ - logc(defaultContext, messageOut, c1, c2, c3, c4, c5, c6); - } - - /** - * Logs using the default context an arbitrary amount of arguments - * specifically setting the context's level to WARN - * - * Params: - * segments = the arbitrary argumnets (alias sequence) - * __FILE_FULL_PATH__ = compile time usage file - * __FILE__ = compile time usage file (relative) - * __LINE__ = compile time usage line number - * __MODULE__ = compile time usage module - * __FUNCTION__ = compile time usage function - * __PRETTY_FUNCTION__ = compile time usage function (pretty) - */ - public void warn(TextType...)(TextType segments, - string c1 = __FILE_FULL_PATH__, - string c2 = __FILE__, ulong c3 = __LINE__, - string c4 = __MODULE__, string c5 = __FUNCTION__, - string c6 = __PRETTY_FUNCTION__) - { - /* Use the default context `Context` */ - Context defaultContext = new Context(); - - /* Build up the line information */ - CompilationInfo compilationInfo = CompilationInfo(c1, c2, c3, c4, c5, c6); - - /* Set the line information in the context */ - defaultContext.setLineInfo(compilationInfo); - - /* Set the level to WARN */ - defaultContext.setLevel(Level.WARN); - - /** - * Grab at compile-time all arguments and generate runtime code to add them to `components` - */ - string[] components = flatten(segments); - - /* Join all `components` into a single string */ - string messageOut = join(components, multiArgJoiner); - - /* Call the log */ - logc(defaultContext, messageOut, c1, c2, c3, c4, c5, c6); - } - - /** - * Logs using the default context an arbitrary amount of arguments - * specifically setting the context's level to DEBUG - * - * Params: - * segments = the arbitrary argumnets (alias sequence) - * __FILE_FULL_PATH__ = compile time usage file - * __FILE__ = compile time usage file (relative) - * __LINE__ = compile time usage line number - * __MODULE__ = compile time usage module - * __FUNCTION__ = compile time usage function - * __PRETTY_FUNCTION__ = compile time usage function (pretty) - */ - public void debug_(TextType...)(TextType segments, - string c1 = __FILE_FULL_PATH__, - string c2 = __FILE__, ulong c3 = __LINE__, - string c4 = __MODULE__, string c5 = __FUNCTION__, - string c6 = __PRETTY_FUNCTION__) - { - /* Use the default context `Context` */ - Context defaultContext = new Context(); - - /* Build up the line information */ - CompilationInfo compilationInfo = CompilationInfo(c1, c2, c3, c4, c5, c6); - - /* Set the line information in the context */ - defaultContext.setLineInfo(compilationInfo); - - /* Set the level to DEBUG */ - defaultContext.setLevel(Level.DEBUG); - - /** - * Grab at compile-time all arguments and generate runtime code to add them to `components` - */ - string[] components = flatten(segments); - - /* Join all `components` into a single string */ - string messageOut = join(components, multiArgJoiner); - - /* Call the log */ - logc(defaultContext, messageOut, c1, c2, c3, c4, c5, c6); - } - - /** - * Alias for debug_ - */ - public alias dbg = debug_; - - /** - * Logging implementation, this is where the final - * transformed text will be transferred to and finally - * logged - * - * Params: - * message = the message to log - */ - protected abstract void logImpl(string message); } - -version(unittest) +public interface Filter { - import std.meta : AliasSeq; - import std.stdio : writeln; + public bool filter(Message message); } -/** -* Tests the DefaultLogger -*/ -unittest +public interface Transform { - Logger logger = new DefaultLogger(); - - alias testParameters = AliasSeq!("This is a log message", 1.1, true, [1,2,3], 'f', logger); - - - // Test various types one-by-one - static foreach(testParameter; testParameters) - { - logger.log(testParameter); - } - - // Test various parameters (of various types) all at once - logger.log(testParameters); - - // Same as above but with a custom joiner set - logger = new DefaultLogger("(-)"); - logger.log(testParameters); - - writeln(); + public Message transform(Message message); } -/** - * Printing out some mixed data-types, also using a DEFAULT context - */ -unittest +public interface Handler { - Logger logger = new DefaultLogger(); - - // Create a default logger with the default joiner - logger = new DefaultLogger(); - logger.log(["a", "b", "c", "d"], [1, 2], true); - - writeln(); + public void handle(Message message); } -/** - * Printing out some mixed data-types, also using a CUSTOM context - */ -unittest +import std.container.slist : SList; +// import std.range : in; +import core.sync.mutex : Mutex; + +public abstract class Logger { - Logger logger = new DefaultLogger(); + private SList!(Transform) transforms; + private SList!(Filter) filters; + private SList!(Handler) handlers; + private Mutex lock; // Lock for attached handlers, filters and transforms - // Create a default logger with the default joiner - logger = new DefaultLogger(); + this() + { + this.lock = new Mutex(); + } - // Create a custom context - Context customContext = new Context(); + // TODO: Handle duplicate? + public final void addTransform(Transform transform) + { + scope(exit) + { + this.lock.unlock(); + } - // Log with the custom context - logger.logc(customContext, logger.args(["an", "array"], 1, "hello", true)); + this.lock.lock(); - writeln(); -} + this.transforms.insertAfter(this.transforms[], transform); + } -/** - * Printing out some mixed data-types, also using a DEFAULT context - * but also testing out the `error()`, `warn()`, `info()` and `debug()` - */ -unittest -{ - Logger logger = new DefaultLogger(); + // TODO: Hanmdle not found explicitly? + public final void removeTransform(Transform transform) + { + scope(exit) + { + this.lock.unlock(); + } - // Create a default logger with the default joiner - logger = new DefaultLogger(); + this.lock.lock(); - // Test out `error()` - logger.error(["woah", "LEVELS!"], 69.420); + this.transforms.linearRemoveElement(transform); + } - // Test out `info()` - logger.info(["woah", "LEVELS!"], 69.420); + // TODO: Handle duplicate? + public final void addFilter(Filter filter) + { + scope(exit) + { + this.lock.unlock(); + } - // Test out `warn()` - logger.warn(["woah", "LEVELS!"], 69.420); + this.lock.lock(); - // Test out `debug_()` - logger.debug_(["woah", "LEVELS!"], 69.420); + this.filters.insertAfter(this.filters[], filter); + } - writeln(); + // TODO: Hanmdle not found explicitly? + public final void removeFilter(Filter filter) + { + scope(exit) + { + this.lock.unlock(); + } + + this.lock.lock(); + + this.filters.linearRemoveElement(filter); + } + + // TODO: Handle duplicate? + public final void addHandler(Handler handler) + { + scope(exit) + { + this.lock.unlock(); + } + + this.lock.lock(); + + this.handlers.insertAfter(this.handlers[], handler); + } + + // TODO: Hanmdle not found explicitly? + public final void removeHandler(Handler handler) + { + scope(exit) + { + this.lock.unlock(); + } + + this.lock.lock(); + + this.handlers.linearRemoveElement(handler); + } + + // Logs an actual message + // + // This first passes it over all filters + // then to a transform and then copies + // to each handler + public final void log(Message message) + { + scope(exit) + { + this.lock.unlock(); + } + + this.lock.lock(); + + foreach(Filter filter; this.filters) + { + if(!filter.filter(message)) + { + return; + } + } + + Message curMessage = message; + foreach(Transform transform; this.transforms) + { + curMessage = transform.transform(curMessage); + } + + foreach(Handler handler; this.handlers) + { + handler.handle(curMessage); + } + } } \ No newline at end of file diff --git a/source/dlog/defaults.d b/source/dlog/defaults.d index f11d5b9..2e41b13 100644 --- a/source/dlog/defaults.d +++ b/source/dlog/defaults.d @@ -3,10 +3,12 @@ */ module dlog.defaults; -import dlog.core : Logger; -import dlog.transform : MessageTransform; -import dlog.context : Context, CompilationInfo; +import dlog.core; +import dlog.basic : BasicMessage, FileHandler, Level; +import std.stdio : stdout; import std.conv : to; +import dlog.utilities : flatten; +import std.array :join; /** * DefaultLogger @@ -15,6 +17,12 @@ import std.conv : to; */ public final class DefaultLogger : Logger { + /** + * The joiner for multi-argument + * log messages + */ + private string multiArgJoiner; + /** * Constructs a new default logger * @@ -23,18 +31,93 @@ public final class DefaultLogger : Logger */ this(string multiArgJoiner = " ") { - /* Use the DefaultTransform */ - super(multiArgJoiner); + this.multiArgJoiner = multiArgJoiner; + + addTransform(new DefaultTransform()); + addHandler(new FileHandler(stdout)); } /** - * Our logging implementation + * Logs the given message of an arbitrary amount of + * arguments and specifically sets the level to ERROR + * + * Params: + * segments = the arbitrary argumnets (alias sequence) */ - protected override void logImpl(string message) + public void error(TextType...)(TextType segments) { - import std.stdio : write; - write(message); + doLog(segments, Level.ERROR); } + + /** + * Logs the given message of an arbitrary amount of + * arguments and specifically sets the level to INFO + * + * Params: + * segments = the arbitrary argumnets (alias sequence) + */ + public void info(TextType...)(TextType segments) + { + doLog(segments, Level.INFO); + } + + /** + * Logs the given message of an arbitrary amount of + * arguments and specifically sets the level to WARN + * + * Params: + * segments = the arbitrary argumnets (alias sequence) + */ + public void warn(TextType...)(TextType segments) + { + doLog(segments, Level.WARN); + } + + /** + * Logs the given message of an arbitrary amount of + * arguments and specifically sets the level to DEBUG + * + * Params: + * segments = the arbitrary argumnets (alias sequence) + */ + public void debug_(TextType...)(TextType segments) + { + doLog(segments, Level.DEBUG); + } + + /** + * Performs the actual logging + * by packing up everything before + * sending it to the `log(Message)` + * method + * + * Params: + * segments = the compile-time segments + * level = the log level to use + */ + private void doLog(TextType...)(TextType segments, Level level) + { + /* Create a new basic message */ + BasicMessage message = new BasicMessage(); + + /* Set the level */ + message.setLevel(level); + + /** + * Grab all compile-time arguments and make them + * into an array, then join them together and + * set that text as the message's text + */ + message.setText(join(flatten(segments), multiArgJoiner)); + + /* Log this message */ + log(message); + } + + /** + * Alias for debug_ + */ + public alias dbg = debug_; } /** @@ -44,38 +127,115 @@ public final class DefaultLogger : Logger * * [date+time] (srcFile:lineNumber): message `\n` */ -public final class DefaultTransform : MessageTransform +public final class DefaultTransform : Transform { /** * Performs the default transformation - * - * Params: - * text = text input to transform - * context = the context (if any) - * Returns: the transformed text */ - public override string transform(string text, Context ctx) - { - /* Extract the context */ - string[] context = ctx.getLineInfo().toArray(); - string message; + + + public Message transform(Message message) + { + // Only handle BasicMessage(s) + BasicMessage bmesg = cast(BasicMessage)message; + if(bmesg is null) + { + return message; + } + + string text; /* Date and time */ import std.datetime.systime : Clock, SysTime; SysTime currTime = Clock.currTime(); import std.conv : to; string timestamp = to!(string)(currTime); - message = "["~timestamp~"]"; + text = "["~timestamp~"]"; - /* Module information */ - message = message ~ "\t("; - message = message ~ context[1]~":"~context[2]; - message = message ~ "): "~text; + /* Level */ + text = text ~ "\t("; + text = text ~ to!(string)(bmesg.getLevel()); + text = text ~ "): "~bmesg.getText(); /* Add trailing newline */ - message = message ~ '\n'; + text = text ~ '\n'; + /* Store the updated text */ + bmesg.setText(text); + return message; } +} + +version(unittest) +{ + import std.meta : AliasSeq; + import std.stdio : writeln; +} + +/** +* Tests the DefaultLogger +*/ +unittest +{ + DefaultLogger logger = new DefaultLogger(); + + alias testParameters = AliasSeq!("This is a log message", 1.1, true, [1,2,3], 'f', logger); + + + // Test various types one-by-one + static foreach(testParameter; testParameters) + { + logger.info(testParameter); + } + + // Test various parameters (of various types) all at once + logger.info(testParameters); + + // Same as above but with a custom joiner set + logger = new DefaultLogger("(-)"); + logger.info(testParameters); + + writeln(); +} + +/** + * Printing out some mixed data-types, also using a DEFAULT context + */ +unittest +{ + DefaultLogger logger = new DefaultLogger(); + + // Create a default logger with the default joiner + logger = new DefaultLogger(); + logger.info(["a", "b", "c", "d"], [1, 2], true); + + writeln(); +} + +/** + * Printing out some mixed data-types, also using a DEFAULT context + * but also testing out the `error()`, `warn()`, `info()` and `debug()` + */ +unittest +{ + DefaultLogger logger = new DefaultLogger(); + + // Create a default logger with the default joiner + logger = new DefaultLogger(); + + // Test out `error()` + logger.error(["woah", "LEVELS!"], 69.420); + + // Test out `info()` + logger.info(["woah", "LEVELS!"], 69.420); + + // Test out `warn()` + logger.warn(["woah", "LEVELS!"], 69.420); + + // Test out `debug_()` + logger.debug_(["woah", "LEVELS!"], 69.420); + + writeln(); } \ No newline at end of file diff --git a/source/dlog/nu/core.d b/source/dlog/nu/core.d deleted file mode 100644 index c21b98d..0000000 --- a/source/dlog/nu/core.d +++ /dev/null @@ -1,150 +0,0 @@ -module dlog.nu.core; - -public class Message -{ - -} - -public interface Filter -{ - public bool filter(Message message); -} - -public interface Transform -{ - public Message transform(Message message); -} - -public interface Handler -{ - public void handle(Message message); -} - -import std.container.slist : SList; -// import std.range : in; -import core.sync.mutex : Mutex; - -public abstract class Logger -{ - private SList!(Transform) transforms; - private SList!(Filter) filters; - private SList!(Handler) handlers; - private Mutex lock; // Lock for attached handlers, filters and transforms - - this() - { - this.lock = new Mutex(); - } - - // TODO: Handle duplicate? - public final void addTransform(Transform transform) - { - scope(exit) - { - this.lock.unlock(); - } - - this.lock.lock(); - - this.transforms.insertAfter(this.transforms[], transform); - } - - // TODO: Hanmdle not found explicitly? - public final void removeTransform(Transform transform) - { - scope(exit) - { - this.lock.unlock(); - } - - this.lock.lock(); - - this.transforms.linearRemoveElement(transform); - } - - // TODO: Handle duplicate? - public final void addFilter(Filter filter) - { - scope(exit) - { - this.lock.unlock(); - } - - this.lock.lock(); - - this.filters.insertAfter(this.filters[], filter); - } - - // TODO: Hanmdle not found explicitly? - public final void removeFilter(Filter filter) - { - scope(exit) - { - this.lock.unlock(); - } - - this.lock.lock(); - - this.filters.linearRemoveElement(filter); - } - - // TODO: Handle duplicate? - public final void addHandler(Handler handler) - { - scope(exit) - { - this.lock.unlock(); - } - - this.lock.lock(); - - this.handlers.insertAfter(this.handlers[], handler); - } - - // TODO: Hanmdle not found explicitly? - public final void removeHandler(Handler handler) - { - scope(exit) - { - this.lock.unlock(); - } - - this.lock.lock(); - - this.handlers.linearRemoveElement(handler); - } - - // Logs an actual message - // - // This first passes it over all filters - // then to a transform and then copies - // to each handler - public final void log(Message message) - { - scope(exit) - { - this.lock.unlock(); - } - - this.lock.lock(); - - foreach(Filter filter; this.filters) - { - if(!filter.filter(message)) - { - return; - } - } - - Message curMessage = message; - foreach(Transform transform; this.transforms) - { - curMessage = transform.transform(curMessage); - } - - foreach(Handler handler; this.handlers) - { - handler.handle(curMessage); - } - } -} \ No newline at end of file diff --git a/source/dlog/package.d b/source/dlog/package.d index e15ebf8..6dc05fb 100644 --- a/source/dlog/package.d +++ b/source/dlog/package.d @@ -11,12 +11,12 @@ public import dlog.core; /** * Transformations */ -public import dlog.transform; +// public import dlog.transform; /** * Context for logging */ -public import dlog.context; +// public import dlog.context; /** * Default logger diff --git a/source/dlog/transform.d b/source/dlog/transform.d deleted file mode 100644 index 3e24c62..0000000 --- a/source/dlog/transform.d +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Transformations - */ -module dlog.transform; - -import dlog.context : Context; - -/** -* 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; - - /** - * The actual textual transformation. - * - * This is to be implemented by sub-classes - */ - public abstract string transform(string text, Context context); - - /** - * Chain a transform - */ - public final void chain(MessageTransform transform) - { - chainedTransform = transform; - } - - /** - * Perform the transformation - */ - public final string execute(string text, Context context) - { - /* Perform the transformation */ - string transformedText = transform(text, context); - - /* If there is a chained transformation */ - if(chainedTransform) - { - transformedText = chainedTransform.execute(transformedText, context); - } - - return transformedText; - } -} \ No newline at end of file