std.experimental.logger formal review round 3
Martin Nowak via Digitalmars-d
digitalmars-d at puremagic.com
Tue Oct 28 15:03:06 PDT 2014
On 10/28/2014 07:22 PM, Martin Nowak wrote:
> On Tuesday, 28 October 2014 at 12:02:16 UTC, Robert burner Schadek wrote:
>> It is a design goal to disable certain LogLevel at CT of a compile
>> unit (CU).
>> e.g. make all logs to trace function template do nothing
>
> One idea to make this working is to use prefixed version identifiers.
> Obviously this is all boilerplate so it could be done in a mixin
> template in std.log.
2nd iteration of that idea.
cat > main.d << CODE
import std_logger;
LoggerCT!"MyApp" appLogger = new StdoutLogger(LogLevel.info);
LoggerCT!"MyLib" libLogger = new StdoutLogger(LogLevel.trace);
void main()
{
appLogger.log!(LogLevel.info)("app");
appLogger.log!(LogLevel.warning)("app");
libLogger.log!(LogLevel.info)("lib");
libLogger.log!(LogLevel.warning)("lib");
Logger rtLogger = appLogger;
rtLogger.log!(LogLevel.info)("rt");
rtLogger.log!(LogLevel.warning)("rt");
}
CODE
cat > std_logger.d << CODE
enum LogLevel { all, info, trace, warning, error, none }
template minLogLevel(string prefix)
{
mixin("
version ("~prefix~"LogAll)
enum minLogLevel = LogLevel.all;
else version ("~prefix~"LogInfo)
enum minLogLevel = LogLevel.info;
else version ("~prefix~"LogTrace)
enum minLogLevel = LogLevel.trace;
else version ("~prefix~"LogWarning)
enum minLogLevel = LogLevel.warning;
else version ("~prefix~"LogError)
enum minLogLevel = LogLevel.error;
else version ("~prefix~"LogNone)
enum minLogLevel = LogLevel.none;
else
enum minLogLevel = LogLevel.all;
");
}
interface Logger
{
@property LogLevel logLevel();
void write(LogLevel ll, string msg);
}
class StdoutLogger : Logger
{
this(LogLevel l) { _logLevel = l; }
LogLevel _logLevel;
@property LogLevel logLevel() { return _logLevel; }
void write(LogLevel ll, string msg) { import std.stdio; writeln(ll,
": ", msg); }
}
/// used for library/app specific version prefixes
struct LoggerCT(string prefix)
{
this(Logger logger) { impl = logger; }
enum versionPrefix = prefix;
Logger impl;
alias impl this;
}
void log(LogLevel ll)(Logger logger, string msg)
{
if (ll >= logger.logLevel) // runtime check
logger.write(ll, msg);
}
/// when using a logger with prefix
void log(LogLevel ll, L:LoggerCT!pfx, string pfx)(auto ref L logger,
string msg)
if (ll < minLogLevel!pfx)
{
}
void log(LogLevel ll, L:LoggerCT!pfx, string pfx)(auto ref L logger,
string msg)
if (ll >= minLogLevel!pfx)
{
if (ll >= logger.logLevel) // additional runtime check, because
logger might require a higher log level
logger.write(ll, msg);
}
CODE
dmd std_logger -run main
dmd -version=MyAppLogWarning std_logger.d -run main
dmd -version=MyAppLogError -version=MyLibLogNone std_logger.d -run main
More information about the Digitalmars-d
mailing list