log4ahk - Logging for AutoHotkey

Logs given String to given device. For more details see log4ahk

Authors

hoppfrosch: Original

License

WTFPL License

    DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004

Copyright (C) 2018 Johannes Kilian <hoppfrosch@gmx.de>

Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.

DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0 - You just DO WHAT THE FUCK YOU WANT TO.
log4ahk

A class that provides simple logging facilities for AutoHotkey

This log-Class supports

Loglevels

Each message has to be logged on a certain loglevel. Consider the loglevel as the severity of the message you want to log: some logmessages are used for simple debug purposes, whereas other logmessages may indicate an Error. In some situations you want to see a very detailled logging - in other situations you just want to be notified about errors ... Both can be managed via loglevel.

Layout

Layouts allow to determine the format of the messages to be logged (see layout)

Appenders

Appenders define the "channels" to be logged to. Currently following appenders can be used:

- appenderstdout

log your messages via stdout. Using Scite4AutoHotkey or VSCode, this will be logging to console

- appenderoutputdebug

log your messages via outputDebug (you might need DbgView or a similar tool to view output)

You might choose several appenders to be logged on simultaneously

Internals

log4ahk is implemented as singleton, so there is only one existing instance. Each change on loglevel, layout will be a global change and be valid from the time of change.

Example
#include log4ahk.ahk

logger := new log4ahk()
; Enable logging to STDOUT
logger.appenders.push(new logger.appender.stdout())
; Set the loglevel to be filtered upon
logger.loglevel.required := logger.loglevel.TRACE
; Show loglevel, current function, computername and log message in log protocol
logger.layout.required := "[%-5.5V] {%-15.15M}{%H} %m"
logger.trace("TRACE - Test TRACE")
logger.debug("TRACE - Test DEBUG")
logger.info("TRACE - Test INFO")

f1()
return

;########################################################
f1() {
logger := new log4ahk()
;Change the loglevel to be filtered upon
logger.loglevel.required := logger.loglevel.INFO
logger.trace("INFO - Test TRACE") ; shouldn't be logged due to required loglevel
logger.debug("INFO - Test DEBUG") ; shouldn't be logged due to required loglevel
logger.info("INFO - Test INFO")
}

; Output:
;[TRACE] {[AUTO-EXECUTE] }{XYZ-COMP} TRACE - Test TRACE
;[DEBUG] {[AUTO-EXECUTE] }{XYZ-COMP} TRACE - Test DEBUG
;[INFO ] {[AUTO-EXECUTE] }{XYZ-COMP} TRACE - Test INFO
;[INFO ] {f1 }{XYZ-COMP} INFO - Test INFO
Public Methods
trace
trace(
str
)

Logs the given string at TRACE level

Parameters
str

String to be logged

debug
debug(
str
)

Logs the given string at DEBUG level

Parameters
str

String to be logged

info
info(
str
)

Logs the given string at INFO level

Parameters
str

String to be logged

warn
warn(
str
)

Logs the given string at WARN level

Parameters
str

String to be logged

error
error(
str
)

Logs the given string at ERROR level

Parameters
str

String to be logged

fatal
fatal(
str
)

Logs the given string at TRACE level

Parameters
str

String to be logged

Private Methods
_log
_log(
str,
loglvl := 2
)

Logs the given string at the given level

Parameters
str

String to be logged

loglvl

level on which the given message is to be logged

Internals

The given loglevel is compared against the global required fixlevel (see <required>) Is the given loglevel equal or greater the required loglevel the logmessage is printed - otherwise the logmessage is suppressed.

_fillLayoutPlaceholders
_fillLayoutPlaceholders(
str := ""
)

Fills some variables needed by layout with the currently valid values.

Parameters
str

String to be logged

log4ahk.​appenderoutputdebug

Helper class for log4ahk (Implementing appender via outputdebug)

Logs messages via OutputDebug

Usage
logger.appenders.push(new logger.appenderoutputdebug())
log4ahk.​appenderstdout

Helper class for log4ahk (Implementing appender via stdout)

Logs messages via StdOut

Usage
logger.appenders.push(new logger.appenderstdout())
log4ahk.​layout

Helper class for log4ahk (Implementing layout)

Creates a pattern layout according to log4j-layout and a couple of log4ahk-specific extensions.

Placeholders

The following placeholders can be used within the layout string:

%d

Current date in yyyy/MM/dd hh:mm:ss format

%H

Hostname

%m

The message to be logged

%M

Method or function where the logging request was issued

%P

pid of the current process

%r

Number of milliseconds elapsed from logging start to current logging event

%R

Number of milliseconds elapsed from last logging event to current logging event

%s

Name of the current script

%S

Fullpath of the current script

%V

Log level

Quantify Placeholders

All placeholders can be extended with formatting instructions, just similar to format:

%20M

Reserve 20 chars for the method, right-justify and fill with blanks if it is shorter

%-20M

Same as %20c, but left-justify and fill the right side with blanks

%09r

Zero-pad the number of milliseconds to 9 digits

%.8M

Specify the maximum field with and have the formatter cut off the rest of the value

Usage

To set a layout use

logger.layout.required := "[%-5.5V] {%-15.15M}{%H} %m"
Private Methods
_expand
_expand(
ph
)

Expands the placeholders with the values from the given array

Parameters
ph

associative Array containing mapping placeholder to its replacement

_split
_split()

Splits the layout into its tokens

Internals

The layout string is separated into its separate layout elements (tokens). For example "%8V %M" consists of two tokens: "%8V" and "%M". Each token starts with "%" and ends at the next space.

The tokens are split up into its separate parts: each token consists of three parts:

Quantifier

All placeholders can be extended with formatting instructions, just similar to format

Placeholder

Placeholders are replaced with the corresponding information

Curlies

Curlies allow further manipulation of the placeholders

As a result of the function, the property tokens is filled with objects, which contain the complete token as well as its single parts.

For more information, which values are allowed for quantifiers, placeholders and curlies have a look at documentation of class layout

Properties
required [get/set]

Get/set the required layout. This layout will be used to format the logged message.

tokens [get]

Get the tokens of the current layout

For more information see _split

log4ahk.​loglevel

Helper class for log4ahk (Implementing loglevels)

Loglevels support the following needs

Internals
Private Methods
tr
tr(
lvl
)

Translate the numeric loglevel into a string

Parameters
lvl

Numerical loglevel

Returns

String describing the choosen loglevel (to be used within layout)

_limit
_limit(
lvl
)

Validate the loglevel

Parameters
lvl

loglevel to be checked

Returns

corrected loglevel

Properties
current [get/set]

get/set the current loglevel

required [get/set]

get/set the required loglevel

If a message is reuested to be logged, the current loglevel is compared against required loglevel.  If the current loglevel is greater/equal the required loglevel the message is logged - otherwise it is suppressed