-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: logging in separate module
- Loading branch information
Showing
12 changed files
with
169 additions
and
176 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package technology.idlab.log | ||
|
||
import technology.idlab.log.pretty.PrettyLog | ||
|
||
abstract class Log( | ||
// The current log level. Messages with a level lower than this will not be printed. | ||
private val level: LogLevel | ||
) { | ||
/** | ||
* Print a message to the output using a given level. | ||
* | ||
* @param message The message to print. | ||
* @param level The level of the message. | ||
*/ | ||
abstract fun log(message: String, level: LogLevel) | ||
|
||
/** | ||
* Print a message if and only if the debug flag is set. Note that the message will not be | ||
* evaluated lazily. | ||
* | ||
* @param message The message to print. | ||
*/ | ||
fun debug(message: String) { | ||
log(message, LogLevel.DEBUG) | ||
} | ||
|
||
/** | ||
* Print a message if and only if the debug flag is set. Note that the message will be evaluated | ||
* lazily only if the debug flag is set. | ||
* | ||
* @param message A function determining the message to print. | ||
*/ | ||
fun debug(message: () -> String) { | ||
if (level == LogLevel.DEBUG) { | ||
val computedMessage = message() | ||
log(computedMessage, LogLevel.DEBUG) | ||
} | ||
} | ||
|
||
/** | ||
* Print a general info message. Will get outputted in all modes. | ||
* | ||
* @param message The message to print. | ||
*/ | ||
fun info(message: String) { | ||
log(message, LogLevel.INFO) | ||
} | ||
|
||
/** | ||
* Print a command message, which will be colored yellow in the console. The location, i.e. the | ||
* file and line number, will be determined by the caller. | ||
* | ||
* @param message The message to print. | ||
*/ | ||
fun command(message: String) { | ||
log(message, LogLevel.CMD) | ||
} | ||
|
||
/** | ||
* Print a severe message, which will be colored red in the console. | ||
* | ||
* @param message The message to print. | ||
*/ | ||
fun severe(message: String) { | ||
log(message, LogLevel.SEVERE) | ||
} | ||
|
||
companion object { | ||
/** | ||
* A globally available instance of the logger. Note that at its creation, the logger will | ||
* output the header to the console, which is why we only allow a single instance. | ||
*/ | ||
val shared = PrettyLog(LogLevel.INFO) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package technology.idlab.log | ||
|
||
enum class LogLevel { | ||
CMD, | ||
DEBUG, | ||
INFO, | ||
SEVERE, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package technology.idlab.log.pretty | ||
|
||
import java.time.format.DateTimeFormatter | ||
import java.util.* | ||
import technology.idlab.log.Log | ||
import technology.idlab.log.LogLevel | ||
|
||
private const val TIME_PADDING = 15 | ||
private const val LEVEL_PADDING = 10 | ||
private const val FILE_PADDING = 39 | ||
private const val MESSAGE_PADDING = 87 | ||
|
||
/** | ||
* A simple logging class that prints messages to the console. The class is a singleton, and all | ||
* messages are outputted to the console. The class has three levels of logging: DEBUG, INFO, and | ||
* FATAL. DEBUG is for debugging information, INFO is for general information, and FATAL is for | ||
* errors that will cause the program to exit. At the moment of writing, all levels are outputted to | ||
* the console regardless of the debug flag. | ||
*/ | ||
class PrettyLog(level: LogLevel) : Log(level) { | ||
init { | ||
val builder = StringBuilder() | ||
builder.append("\u001B[1m") | ||
builder.append("TIME".padEnd(TIME_PADDING, ' ')) | ||
builder.append("LEVEL".padEnd(LEVEL_PADDING, ' ')) | ||
builder.append("FILE".padEnd(FILE_PADDING, ' ')) | ||
builder.append("MESSAGE".padEnd(MESSAGE_PADDING, ' ')) | ||
builder.append("\n") | ||
builder.append("\u001B[0m") | ||
builder.append("----".padEnd(TIME_PADDING, ' ')) | ||
builder.append("-----".padEnd(LEVEL_PADDING, ' ')) | ||
builder.append("----".padEnd(FILE_PADDING, ' ')) | ||
builder.append("-------\n") | ||
|
||
synchronized(System.out) { print(builder) } | ||
} | ||
|
||
override fun log(message: String, level: LogLevel) { | ||
// Get the current time. | ||
val instant = Date().toInstant() | ||
val tz = instant.atZone(TimeZone.getDefault().toZoneId()) | ||
val iso = DateTimeFormatter.ISO_LOCAL_TIME | ||
|
||
val time = tz.format(iso) | ||
val levelCode = level.name | ||
|
||
val stack = Throwable().stackTrace[4] | ||
val file = "${stack.fileName ?: "Unknown"}:${stack.lineNumber}" | ||
|
||
// Build the message. | ||
val builder = StringBuilder() | ||
|
||
// If the message is of level debug, set color to gray. | ||
if (level == LogLevel.DEBUG) { | ||
builder.append("\u001B[37m") | ||
} | ||
|
||
// If the message is of level command, set color to muted yellow. | ||
if (level == LogLevel.CMD) { | ||
builder.append("\u001B[38;5;180m") | ||
} | ||
|
||
// The actual message. | ||
builder.append(time.padEnd(TIME_PADDING, ' ')) | ||
builder.append(levelCode.padEnd(LEVEL_PADDING, ' ')) | ||
builder.append(file.padEnd(FILE_PADDING, ' ')) | ||
builder.append(message) | ||
builder.append("\n") | ||
|
||
// Reset coloring. | ||
builder.append("\u001B[0m") | ||
|
||
// Print to the console, thread safe. | ||
synchronized(System.out) { print(builder) } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.