Skip to content

Instantly share code, notes, and snippets.

@jaforsgren
Forked from gtvfx/Logger.ms
Created June 16, 2017 06:56
Show Gist options
  • Save jaforsgren/5385922ad9db49cec3d6055b12742c4b to your computer and use it in GitHub Desktop.
Save jaforsgren/5385922ad9db49cec3d6055b12742c4b to your computer and use it in GitHub Desktop.
Maxscript Logger object for formatting differing levels of information to the console. Inspired by the Python Logger module.
/***************************************************************************************************
Copyright (C) 2013 - 2017 Gavyn Thompson
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. if not, see <http://www.gnu.org/licenses/>.
***************************************************************************************************/
/***************************************************************************************************
Author: Gavyn Thompson
Company: GTVFX
Website: https://github.com/gtvfx
Email: gftvfx@gmail.com
ScriptVersion:
Updated:
[Purpose]
***************************************************************************************************/
/*
__HELP__
Constructor: Logger
Instantiated Global: Logger
Methods:
<Void> SetLevel lvl
-- Set the logger level ( #none, #info, #debug )
<Void> SetVerbosity v
-- Set the verbosity of the debugger
<Bool> IsEnabledFor lvl
-- Returns true if the supplied log level is enabled, otherwise false
<Array> GetEffectiveLevel
-- Returns an array where index 1 is the current log level enumeratoin and index 2 is the current log level integer
<Int> GetVerbosity
-- returns the current verbosity level
Debug msg args:#() kwargsDict: verbosity:1 cls:
-- if #debug level is enabled then prints a DEBUG message
-- the args array is used with the Format method of this class. Expects the msg to comply with the required syntax.
-- The kwargsDict is an optional supplied hashTable to the logger will print out the Keys and Values for along witht eh msg
-- verbosity is an integer value. Default is 1, higher numbers require a higher verbosity level in order to execute.
-- cls is the instance of the class the Logger is being run from. Either leave unsupplied or supply the 'this' expression
Info msg args:#() kwargsDict: cls:
-- if #info or #debug level is enabled then prints an INFO message
-- the args array is used with the Format method of this class. Expects the msg to comply with the required syntax.
-- The kwargsDict is an optional supplied hashTable to the logger will print out the Keys and Values for along witht eh msg
-- cls is the instance of the class the Logger is being run from. Either leave unsupplied or supply the 'this' expression
Warning msg args:#() kwargsDict: cls:
-- prints a WARNING message. This is not affected by log level
-- the args array is used with the Format method of this class. Expects the msg to comply with the required syntax.
-- The kwargsDict is an optional supplied hashTable to the logger will print out the Keys and Values for along witht eh msg
-- cls is the instance of the class the Logger is being run from. Either leave unsupplied or supply the 'this' expression
Error msg args:#() kwargsDict: cls:
-- prints an ERROR message. This is not affected by log level
-- the args array is used with the Format method of this class. Expects the msg to comply with the required syntax.
-- The kwargsDict is an optional supplied hashTable to the logger will print out the Keys and Values for along witht eh msg
-- cls is the instance of the class the Logger is being run from. Either leave unsupplied or supply the 'this' expression
Critical msg args:#() kwargsDict: cls:
-- prints an CRITICAL message. This is not affected by log level
-- the args array is used with the Format method of this class. Expects the msg to comply with the required syntax.
-- The kwargsDict is an optional supplied hashTable to the logger will print out the Keys and Values for along witht eh msg
-- Performs a THROW operation which ends all running threads with a Runtime Error
-- cls is the instance of the class the Logger is being run from. Either leave unsupplied or supply the 'this' expression
Log msg statement:"LOG" lvl:( ::Enum_LoggerLevel.info ) args:#() kwargsDict: cls:
-- A custom log
-- you can set the custom statement. This will appear inplace of 'INFO' or 'DEBUG'
-- you can set the lvl you wish. Either #info or #debug
-- the args array is used with the Format method of this class. Expects the msg to comply with the required syntax.
-- The kwargsDict is an optional supplied hashTable to the logger will print out the Keys and Values for along witht eh msg
-- cls is the instance of the class the Logger is being run from. Either leave unsupplied or supply the 'this' expression
Format msg args:#()
-- Allows you to format a string in place
-- Uses more similar to Python sintax where arg variables in the string must be in format: {<index>}
-- where <index> matches the arguments index in the args array
-- Example: tstStr = Logger.format "This {1} a {2} to {3} if {4} works" args:#("is", "test", "see", "this")
__END__
*/
mxs.Load "HashTableMethods"
struct Enum_LoggerLevel
(
none = #none,
info = #info,
debug = #debug
)
struct Enum_LevelVal
(
none = 0,
info = 1,
debug = 2
)
Enum_LoggerLevel = Enum_LoggerLevel()
Enum_LevelVal = Enum_LevelVal()
struct Logger
(
public
fn SetLevel lvl =
(
local vals = this.GetLevelValues lvl
if ( vals != undefined ) then
(
this.level = vals[1]
level_val = vals[2]
)
vals
),
fn SetVerbosity v =
(
if ( v > this._maxVerbosity ) then
(
this.error "Maximum verbosity is {1}" args:#( (this._maxVerbosity as string) ) cls:this
)
else
(
this.verbosity = v
)
),
fn IsEnabledFor lvl =
(
local lvlVals = this.GetLevelValues lvl
if ( lvlVals == undefined ) then return undefined
lvl = lvlVals[1]
case lvl of
(
( ::Enum_LoggerLevel.none ):
(
this.level == lvl
)
( ::Enum_LoggerLevel.info ):
(
if ( this.level == lvl ) or ( this.level == ( ::Enum_LoggerLevel.debug ) ) then
(
true
)
else
(
false
)
)
( ::Enum_LoggerLevel.debug ):
(
this.level == lvl
)
)
),
fn GetEffectiveLevel =
(
#(this.level, this.level_val)
),
fn GetVerbosity =
(
this.verbosity
),
fn Debug msg args:#() kwargsDict: verbosity:1 cls: =
(
if ( verbosity <= this.verbosity ) then
(
if ( this.GetEffectiveLevel() )[1] == ( ::Enum_LoggerLevel.debug ) then
(
if ( args.count != 0 ) then
(
msg = this.format msg args:args
)
local extraStr = ""
if ( kwargsDict != unsupplied ) and ( ClassOf kwargsDict == dotNetObject ) then
(
extraStr = " " + this.ConcatStrFromHashtable kwargsDict
)
if ( cls != unsupplied ) then cls = ( this.GetClassTitle cls ) else cls = ""
format "DEBUG :: [%] *----- % -----*\n" cls ( msg + extraStr )
)
)
),
fn Info msg args:#() kwargsDict: cls: =
(
if ( this.GetEffectiveLevel() )[2] != ( ::Enum_LoggerLevel.none ) then
(
if ( args.count != 0 ) then
(
msg = this.format msg args:args
)
local extraStr = ""
if ( kwargsDict != unsupplied ) and ( ClassOf kwargsDict == dotNetObject ) then
(
extraStr = " " + this.ConcatStrFromHashtable kwargsDict
)
if ( cls != unsupplied ) then cls = ( this.GetClassTitle cls ) else cls = ""
format "INFO :: [%] ***** % *****\n" cls ( msg + extraStr )
)
),
fn Warning msg args:#() kwargsDict: cls: =
(
if ( args.count != 0 ) then
(
msg = this.format msg args:args
)
local extraStr = ""
if ( kwargsDict != unsupplied ) and ( ClassOf kwargsDict == dotNetObject ) then
(
extraStr = " " + this.ConcatStrFromHashtable kwargsDict
)
if ( cls != unsupplied ) then cls = ( this.GetClassTitle cls ) else cls = ""
format "WARNING :: [%] !!---------- % ----------!!\n" cls ( msg + extraStr )
),
fn Error msg args:#() kwargsDict: cls: =
(
if ( args.count != 0 ) then
(
msg = this.format msg args:args
)
local extraStr = ""
if ( kwargsDict != unsupplied ) and ( ClassOf kwargsDict == dotNetObject ) then
(
extraStr = " " + this.ConcatStrFromHashtable kwargsDict
)
if ( cls != unsupplied ) then cls = ( this.GetClassTitle cls ) else cls = ""
format "ERROR :: [%] !-!-!-!-!-! % !-!-!-!-!-!\n" cls ( msg + extraStr )
),
fn Critical msg args:#() kwargsDict: cls: =
(
if ( args.count != 0 ) then
(
msg = this.format msg args:args
)
local extraStr = ""
if ( kwargsDict != unsupplied ) and ( ClassOf kwargsDict == dotNetObject ) then
(
extraStr = " " + this.ConcatStrFromHashtable kwargsDict
)
if ( cls != unsupplied ) then cls = ( this.GetClassTitle cls ) else cls = ""
format "Critical :: [%] !-!-!-!-!-! % !-!-!-!-!-!\n" cls ( msg + extraStr )
throw "LOGGER::CRITICAL"
),
fn Log msg statement:"LOG" lvl:( ::Enum_LoggerLevel.info ) args:#() kwargsDict: cls: =
(
local logLevel = this.GetLevelValues lvl
if ( logLevel != undefined ) and ( this.level == logLevel[1] ) then
(
if ( args.count != 0 ) then
(
msg = this.format msg args:args
)
local extraStr = ""
if ( kwargsDict != unsupplied ) and ( ClassOf kwargsDict == dotNetObject ) then
(
extraStr = " " + this.ConcatStrFromHashtable kwargsDict
)
if ( cls != unsupplied ) then cls = ( this.GetClassTitle cls ) else cls = ""
format "% :: [%] ========== % ==========\n" statement cls ( msg + extraStr )
)
),
fn Format msg args:#() =
(
local str = msg
for i = 1 to args.count do
(
str = SubstituteString str ( "{" + ( i as string ) + "}" ) ( args[i] as string )
)
str
),
fn GetModule =
(
( GetSourceFileName() )
),
fn Help =
(
::_ilmLibrary.GetScriptHelp ( GetSourceFileName() )
),
private
level = ::Enum_LoggerLevel.info,
level_val = ( GetProperty ::Enum_LevelVal this.level ),
_maxVerbosity = 4,
verbosity = 1,
fn ConcatStrFromHashtable dict =
(
local str = StringStream ""
local dictKeys = ::_hash.GetDicKeys dict
for k in dictKeys do
(
format "| % :: % " k dict.item[k] to:str
)
( str as string ) + "|"
),
fn InvalidLevel lvl =
(
if ( ClassOf lvl ) == Integer then
(
lvl = lvl as string
this.Error ( lvl + " is not a valid level value, expected one of: " + (#(0, 1, 2) as string ))
)
else
(
this.Error ( lvl + " is not a valid level, expected one of: " + (( GetPropNames ::Enum_LoggerLevel ) as string ))
)
),
fn GetLevelValues lvl =
(
local out = #()
if ( ClassOf lvl ) == Integer then
(
if ( lvl > 2 ) then
(
this.InvalidLevel lvl
return undefined
)
local prps = ( GetPropNames ::Enum_LevelVal )
prp = ( for p in prps where ( GetProperty ::Enum_LevelVal p ) == lvl collect p )[1]
out = #(prp, ( GetProperty ::Enum_LevelVal prp ))
)
else if ( IsProperty ::Enum_LoggerLevel lvl ) then
(
local prp = ( GetProperty ::Enum_LoggerLevel lvl )
out = #(prp, ( GetProperty ::Enum_LevelVal prp ))
)
else
(
this.InvalidLevel lvl
)
out
),
fn GetClassTitle cls =
(
local str = ( cls as string )
local classTitle = ( trimLeft ( FilterString str " " )[1] "(" )
),
fn _init =
(
-- Pass
),
__init__ = _init()
)
Logger = Logger()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment