Jump to content
jvanegmond

Simple Logging UDF - Log.au3 based on log4j / NLog

Recommended Posts

jvanegmond

This is a logging library for AutoIt. This library allows you to log messages with different log levels. The log levels are $LOG_TRACE, $LOG_DEBUG, $LOG_INFO, $LOG_WARN, $LOG_ERROR, $LOG_FATAL. These levels are described on the Log4j Wikipedia page. Each message is logged to the console (ConsoleWriteError for $LOG_ERROR and $LOG_FATAL and ConsoleWrite for all other levels) and to a file.

You can choose the filename and a directory (see LogFile), but if you don't the log file will be in the same directory as the program and called @ScriptName & ".log". You can also choose to disable logs below a certain log level (see LogLevel). You can also completely customize the format of the log text (see LogFormat).

log.au3
 
Here's an example on how to use this library:

#include <log.au3>

LogTrace("This is an example trace message")
LogDebug("This is an example debug message")
LogInfo("This is an example info message")
LogWarn("This is an example warning message")
LogError("This is an example error message")
LogFatal("This is an example fatal message")

The output looks like this:

[2014-08-13 21:06:50.582 TRACE] This is an example trace message
[2014-08-13 21:06:50.582 DEBUG] This is an example debug message
[2014-08-13 21:06:50.582 INFO ] This is an example info message
[2014-08-13 21:06:50.582 WARN ] This is an example warning message
[2014-08-13 21:06:50.591 ERROR] This is an example error message
[2014-08-13 21:06:50.591 FATAL] This is an example fatal message

Additionally, these functions are available for your convenience:

LogFile($sFileName)

#include <log.au3>

LogFile("C:\example.log")

LogInfo("This is an example info message")

and the output will appear on the C: drive in a file called example.log.
 
LogLevel($iMinLevel)

#include <log.au3>

LogLevel($LOG_INFO)

LogTrace("This is an example trace message and it will not appear in the logs")
LogInfo("This is an example info message and it will appear in the logs")
LogFatal("This is an example fatal message and it will appear in the logs")

The LogTrace call will have no effect. Only the LogInfo and LogFatal message will appear in the log.
 
LogStart()
 

#include <log.au3>

LogStart()

LogInfo("This is an example info message")

Output:

[2014-08-13 21:14:42.886 INFO ] C:\Users\jvanegmond\Desktop\example.au3 started.

[2014-08-13 21:14:42.888 INFO ] This is an example info message

LogFormat($fFormatFunc)


#include <log.au3>

LogFormat(MyLogFormat)

LogTrace("This is an example trace message")
LogDebug("This is an example debug message")
LogInfo("This is an example info message")
LogWarn("This is an example warning message")
LogError("This is an example error message")
LogFatal("This is an example fatal message")

Func MyLogFormat($sLevel, $sMessage)
    Return @HOUR & ":" & @MIN & ":" & @SEC & " " & StringStripWS($sLevel, 8) & " " & $sMessage
EndFunc

Shows the output:

11:39:52 TRACE This is an example trace message
11:39:52 DEBUG This is an example debug message
11:39:52 INFO This is an example info message
11:39:52 WARN This is an example warning message
11:39:52 ERROR This is an example error message
11:39:52 FATAL This is an example fatal message
 

 
Please let me know what I can remove from this library so that it can fit your use-case better.
 

Edit: Changes:

v1.2 Support for log format

v1.1 Create directory structure for log file

v1.0 Initial release

Edited by Manadar
  • Like 1

Share this post


Link to post
Share on other sites
jvanegmond

Migration path for existing scripts which use ConsoleWrite and ConsoleWriteError for logging.

  • Open your script in SciTe editor
  • Open the Replace menu, or press Ctrl+H on your keyboard
  • Enable regular expressions and wrap around options, disable others. It should look like this:

    tyrMfoO.png

  • Replace ConsoleWriteError((.*) *& *@CRLF *?) with LogError(1) by hitting replace all*
  • Replace ConsoleWrite((.*) *& *@CRLF *?) with LogInfo(1) by hitting replace all*
  • Check for any remaining occurrences of ConsoleWriteError and ConsoleWrite manually and fix where appropriate
* Be careful not to copy any additional spaces around the search phrases. Edited by Manadar

Share this post


Link to post
Share on other sites
czardas

Nice, simple and useful! I often thought ConsoleWrite could do with some functionality with compiled scripts, but this is even better. :thumbsup:

Edited by czardas

Share this post


Link to post
Share on other sites
jvanegmond

Thanks, czardas. This certainly isn't going to win any beauty prize, but it's extremely simple and solves the problem domain.

For completeness, I should mention log4a which is similar but with slightly more features and slightly more complex:

Edited by jvanegmond

Share this post


Link to post
Share on other sites
mmoalem

Hi - thanks for this - very useful for my needs - just one question - is there a way to delete old line (so the file doesnt get to gigantic)? maybe limit the size?

Share this post


Link to post
Share on other sites
jvanegmond
On 4/17/2016 at 8:28 PM, mmoalem said:

Hi - thanks for this - very useful for my needs - just one question - is there a way to delete old line (so the file doesnt get to gigantic)? maybe limit the size?

I feel like that should be part of the library - but it currently is not. You should be able to create a new log file based on size by running this occasional:

If FileSize(logfile) > SomeLimit Then
  LogClose()
  Zip or FileMove -or- FileDelete
  LogFile(logfile)
EndIf

You might not want to immediately delete your last log, so you can make a simple log rotation going by:

FileDelete("log3.log")
FileMove("log2.log", "log3.log")
FileMove("log1.log", "log2.log")
FileMove("log.log", "log1.log")

Or by going a step further and putting the date in the file name.

Share this post


Link to post
Share on other sites
Bowmore

The following is a method I use to trim data from the beginning of log files. Just call as often as required.

NOTE: If you keep a handle to your log while you script is running then you will need to close the file before closing this function and reopen it after it has been trimmed.

#include <FileConstants.au3>

TrimLogFile($sFilename, 20000)

Func TrimLogFile($sFilename, $iMaxSize = 50000)
    Local $iSize = FileGetSize($sFilename)
    Local $hFile = -1
    Local $sData = ''

    If $oSize > $iMaxSize Then
        $hFile = FileOpen($sFilename)
        If @error Then Return SetError(1, 0, 0)
        FileSetPos($h, -$iMaxSize, $FILE_END)
        If @error Then Return SetError(2, 0, 0)
        $sData = FileRead($hFile)
        If @error Then Return SetError(2, 0, 0)
        FileClose($hFile)
        $hFile = FileOpen($sFilename, $FO_OVERWRITE)
        FileWrite($hFile, $sData)
        FileClose($hFile)
    EndIf
    Return FileGetSize($sFilename)

EndFunc   ;==>TrimLogFile

 

  • Like 1

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×