log(n)

πŸ“¦
version 2.0 Β· 2 versions
, in fedora 43, fedora 44, nixos 26.05, nixpkgs unstable

πŸ’– log(n) β€” the logging facility, but make it cute πŸ’–

okay so bestie, welcome to log(n), the Tcl manual page for the log package. it's literally the glow-up your libraries and apps need when they wanna spill the tea about what they're doing internally. 🫢


✨ NAME ✨

log β€” procedures to log messages of libraries and applications. no cap, that's the whole vibe. πŸ’…


🌸 SYNOPSIS 🌸

package require Tcl 8.5 9

package require log ?1.5?

::log::levels

::log::lv2longform level

::log::lv2color level

::log::lv2priority level

::log::lv2cmd level

::log::lv2channel level

::log::lvCompare level1 level2

::log::lvSuppress level {suppress 1}

::log::lvSuppressLE level {suppress 1}

::log::lvIsSuppressed level

::log::lvCmd level cmd

::log::lvCmdForall cmd

::log::lvChannel level chan

::log::lvChannelForall chan

::log::lvColor level color

::log::lvColorForall color

::log::log level text

::log::logarray level arrayvar ?pattern?

::log::loghex level text data

::log::logsubst level msg

::log::logMsg text

::log::logError text

::log::Puts level text

πŸ¦‹ DESCRIPTION πŸ¦‹

the log package hands you a whole set of commands so libraries and applications can selectively log the tea about their internal operation and state. it's giving main character energy for your diagnostics. ✨

to use the package you literally just execute:

package require log
log::log notice "Some message"

so as you can see up there πŸ‘† every message you hand to the log facility gets matched with a level that says how important it is. then you get to pick which levels actually get logged, which commands do the logging for each level, and which channel the message gets written to. iconic. πŸ‘‘

in this next example, all the logging for messages with level debug is deactivated:

package require log
log::lvSuppress debug
log::log debug "Unseen message" ; # No output

by default, every message that's an error-level (that's emergency, alert, critical, and error) gets written to stderr. messages with any other level get written to stdout. and in this example, the log module gets reconfigured so debug messages go to stderr too:

package require log
log::lvChannel debug stderr
log::log debug "Written to stderr"

every message level also comes with a command that's used when logging a message of that level. the behaviour we just described relies on the fact that all message levels use, by default, the standard command ::log::Puts to log any message. in this next example, all messages of level notice get handed to the non-standard command toText for logging. this disables the channel setting for those messages, assuming that toText doesn't use it by itself:

package require log
log::lvCmd notice toText
log::log notice "Handled by \"toText\""

another little database this facility keeps is a map from message levels to colors 🌈. the info in that database has zero influence on how the module behaves. it's literally just there as a convenience, and in anticipation of this facility being used in tk-based applications that might wanna colorize message logs. so pretty, so harmless. πŸŽ€


πŸ’… API πŸ’…

these are the commands, bestie. all of them:

  • ::log::levels β€” returns the names of all known levels, in alphabetical order. a lil roster. ⭐
  • ::log::lv2longform level β€” converts any unique abbreviation of a level name into the full level name. glow-up for short names. ✨
  • ::log::lv2color level β€” converts any level name, unique abbreviations included, into the corresponding color. 🎨
  • ::log::lv2priority level β€” converts any level name, unique abbreviations included, into the corresponding priority.
  • ::log::lv2cmd level β€” converts any level name, unique abbreviations included, into the command prefix used to write messages with that level.
  • ::log::lv2channel level β€” converts any level name, unique abbreviations included, into the channel used by ::log::Puts to write messages with that level.
  • ::log::lvCompare level1 level2 β€” compares two levels (unique abbreviations allowed) by their priority. this one can be used by the -command option of lsort. the result is one of -1, 0 or 1, or an error. a result of -1 signals that level1 is of less priority than level2. 0 signals both levels have the same priority. 1 signals level1 has higher priority than level2. it's a whole vibe check for levels. πŸ”₯
  • ::log::lvSuppress level {suppress 1} β€” (un)suppresses the output of messages that have the specified level. unique abbreviations for the level are allowed here too. βœ‹
  • ::log::lvSuppressLE level {suppress 1} β€” (un)suppresses the output of messages that have the specified level or one of lesser priority. unique abbreviations for the level are allowed here too. so it's the "and everyone below you, sorry" option. 😭
  • ::log::lvIsSuppressed level β€” asks the package whether the specified level is currently suppressed. unique abbreviations of level names are allowed.
  • ::log::lvCmd level cmd β€” defines, for the specified level, which command writes the messages that have this level. unique abbreviations of level names are allowed. the command is actually a command prefix, and this facility will append 2 arguments before calling it: the level of the message and the message itself, in this order.
  • ::log::lvCmdForall cmd β€” same deal, but for all known levels: defines which command writes the messages that have this level. the command is actually a command prefix and this facility will append 2 arguments before calling it, the level of the message and the message itself, in this order.
  • ::log::lvChannel level chan β€” defines, for the specified level, into which channel ::log::Puts (the standard command) shall write the messages that have this level. unique abbreviations of level names are allowed. the command is actually a command prefix and this facility will append 2 arguments before calling it, the level of the message and the message itself, in this order.
  • ::log::lvChannelForall chan β€” defines, for all known levels, which channel ::log::Puts (the standard command) shall write the messages that have this level to. the command is actually a command prefix and this facility will append 2 arguments before calling it, the level of the message and the message itself, in this order.
  • ::log::lvColor level color β€” defines, for the specified level, the color to return for it in a call to ::log::lv2color. unique abbreviations of level names are allowed. 🌸
  • ::log::lvColorForall color β€” defines, for all known levels, the color to return for it in a call to ::log::lv2color. unique abbreviations of level names are allowed. 🌈
  • ::log::log level text β€” logs a message according to the specifications for commands, channels and suppression. in other words: the command does nothing if the specified level is suppressed. if it's not suppressed, the actual logging gets delegated to the specified command. if there's no command specified for the level, the message won't be logged. the standard command ::log::Puts will write the message to the channel specified for the given level. if no channel is specified for the level, the message won't be logged. unique abbreviations of level names are allowed.
⚠️ errors in the actual logging command are not caught β€” they get propagated to the caller, because they may indicate misconfigurations of the log facility or errors in the caller's own code. so like, pay attention. πŸ’€
  • ::log::logarray level arrayvar ?pattern? β€” like ::log::log, but it logs the contents of the specified array variable arrayvar, possibly restricted to entries matching the pattern. the pattern defaults to * (i.e. all entries) if none was specified.
  • ::log::loghex level text data β€” like ::log::log, but it assumes data contains binary data. it converts this into a mixed hex/ascii representation before writing them to the log. hex girl summer. πŸ”₯
  • ::log::logsubst level msg β€” like ::log::log, but msg may contain substitutions and variable references, which are evaluated in the caller scope first. the purpose of this command is to avoid overhead in the non-logging case, if the log message building is expensive. any substitution errors raise an error in the command execution. the example below shows an xml text representation that's only generated in debug mode:
log::logsubst debug {XML of node $node is '[$node toXml]'}
  • ::log::logMsg text β€” convenience wrapper around ::log::log. equivalent to ::log::log info text.
  • ::log::logError text β€” convenience wrapper around ::log::log. equivalent to ::log::log error text.
  • ::log::Puts level text β€” the standard log command: it writes messages and their levels to user-specified channels. assumes that the suppression checks were done by the caller. expects full level names β€” abbreviations are not allowed. periodt. πŸ’…

πŸ‘‘ LEVELS πŸ‘‘

the package currently defines these log levels, with the level of highest importance listed first:

  • emergency
  • alert
  • critical
  • error
  • warning
  • notice
  • info
  • debug
πŸ“’ note that by default, all messages with levels warning down to debug are suppressed. this is done intentionally, because (we believe that) in most situations debugging output is not wanted. most people only want that kind of output when they're actually debugging an application. so if you're like "where are my debug messages 😭" β€” that's why, bestie.

πŸ› BUGS, IDEAS, FEEDBACK πŸ›

this document, and the package it describes, will undoubtedly contain bugs and other problems. please report such in the category log of the Tcllib Trackers [http://core.tcl.tk/tcllib/reportlist]. please also report any ideas for enhancements you may have for either the package and/or the documentation. we wanna hear it, fr fr. 🫢

when proposing code changes, please provide unified diffs, i.e. the output of diff -u.

note further that attachments are strongly preferred over inlined patches. attachments can be made by going to the Edit form of the ticket immediately after its creation, and then using the left-most button in the secondary navigation bar. (iykyk ✨)


πŸ”‘ KEYWORDS πŸ”‘

log, log level, message, message level


🧚 CATEGORY 🧚

Programming tools


Copyright (c) 2001-2009 Andreas Kupries <andreas_kupries@users.sourceforge.net>


and that's the whole page, bestie!! this one shipped out of tcllib, version 1.5, on the log(n) page. thank you for coming to my ted talk, go forth and log responsibly πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from