Logger -- A unified logging tool for Magma ========================================== Alexander Kasprzyk * Summary * Requirements * How to install * First examples * Log line format * SetLoggerLineFormat * GetLoggerLineFormat * The log destinations * SetLoggerToFile * SetLoggerToGrowl * SetLoggerToMagma * SetLoggerToMMS * SetLoggerToMySQL * SetLoggerToSqlite * SetLoggerToUserProgram * Example: MMS * Example: MySQL * Example: Sqlite * Example: UserProgram * Controlling the logger Summary ------- Provides a uniform logging mechanism for Magma. Log messages can be redirected to a variety of outputs, including a file, a MySQL database, or the syslog. Requirements ------------ Requires Magma V2.18-4 or higher. Some logger interfaces require use of the Pipe intrinsic, which is not currently available on Microsoft Windows. How to install -------------- Download the "Logger.tar.gz" archive and unpack it. We will assume that you have saved it to /path/to/Logger (a sensible location might be in a "magma" directory in your home directory). From within Magma, load the files via: > AttachSpec("/path/to/Logger/logger.spec"); If you use this package regularly, you could place the AttachSpec command in your Magma startup file (usually ~/.magmarc). First examples -------------- The first example simply outputs the log messages to the Magma session: > EnableLogger(); > Logger("Hello world"); 2010-11-22 10:39:37: Hello world Logging can be disabled by calling DisableLogger: > EnableLogger(); > Logger("Hello world"); 2010-11-22 10:57:31: Hello world > DisableLogger(); > Logger("Can you hear me?"); // This produces no output Logging is disabled by default. The following example redirects the log messages to a file: > SetLoggerToFile("~/log.txt"); > Logger("Hello world"); If we now cat the contents of the file, we see: % cat log.txt 2010-11-22 10:39:37 fano.local[2146]: Hello world Log line format --------------- The log line format can be set and recovered via the intrinsics: SetLoggerLineFormat( format) -> MonStgElt Specifies the log line format used by the logger. Also gives an example log line to illustrate this format. GetLoggerLineFormat() -> MonStgElt The currently used log line format. The log line format accepts the following tokens (see the examples below): Token | Equivalent to ------+---------------------------------------------------- %s | the input log string %l | the log level %% | the % character %d | %!date "+%Y-%m-%d %H:%M:%S" %t | Cputime(); %m | printf "%.2o", 1.0 * GetMemoryUsage() / 2^20; %p | Getpid(); %u | Getuid(); %w | %!whoami %h | %!hostname %v | printf "%o.%o-%o",a,b,c where a,b,c:=GetVersion(); For the following examples I first give the log line format, then an example of the output: "%d %h: %s (%ts, %mMB)" 2010-11-22 10:39:37 fano.local: This is an example log entry (12.430s, 15.02MB) "%w@%h [%p]: %s" alex@fano.local [2146]: This is an example log entry "Magma V%v <%l> %s" Magma V2.17-1 This is an example log entry The log destinations -------------------- SetLoggerToFile( path) Sets log messages to be saved to the indicated file, and enables logging. The default log line format is "%d %h[%p]: %s". "path" should be the path to the file to use (and will be created if it doesn't exist). Magma must have permission to write to this file. SetLoggerToGrowl() [ The optional parameters are address: The network address to send Growl notifications password: The network password ] Sets log messages to be sent to the Mac OS X notification system Growl (http://growl.info/), and enables logging. The default log line format is "%s". This requires the Magma Growl interface to be loaded, available from: http://magma.maths.usyd.edu.au/magma/extra/ SetLoggerToMagma() Sets log messages to be displayed on the Magma command line, and enables logging. The default log line format is "%d: %s". This is the default logging method. SetLoggerToMMS( recipient) Sets log messages to be sent to the Magma Messaging System server, and enables logging. Messages will be delivered to the named recipient. The default log line format is "%d: %s". This requires the MMS interface to be loaded, and for the current Magma session to be registered with the MMS server. SetLoggerToMySQL( database) [ The optional parameters are table_name: The name of the table to use (default: error_log) mysql: The path to the mysql command line tool user: The database username password: The database password socket: A socket to connect via host: A remote MySQL server to connect to port: The port number used by the remote MySQL server ] Sets log messages to be sent to a MySQL database, and enables logging. The default log line format is "%s". You MUST have the mysql command line tool installed on your computer. If the table does not already exist, it will be automatically created using the SQL command: CREATE TABLE error_log ( id INT NOT NULL AUTO_INCREMENT, stamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, level TINYINT NOT NULL, message TEXT, PRIMARY KEY(id), INDEX(stamp), INDEX(level) ); SetLoggerToSqlite( database) [ The optional parameters are table_name: The name of the table to use (default: error_log) sqlite: The path to the sqlite3 command line tool ] Sets log messages to be sent to an Sqlite database, and enables logging. The default log line format is "%s". You MUST have the sqlite3 command line tool installed on your computer (this is included by default on most UNIX-style systems, including Mac OS X). "database" should be the path to the database file to use (and will be created if it doesn't exist). Magma must have permission to write to this file. If the table does not already exist, it will be automatically created using the SQL commands: CREATE TABLE error_log ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, stamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, level INTEGER NOT NULL, message TEXT ); CREATE INDEX idx_stamp ON error_log(stamp); CREATE INDEX idx_level ON error_log(level); SetLoggerToSyslog() Sets log messages to be saved to the syslog, and enables logging. The default log line format is "%s". You MUST have the syslog command line tool installed on your computer (this is included by default on Mac OS X). SetLoggerToUserProgram( f) Sets log messages to be sent to the given user program, and enables logging. The default log line format is "%s". The user program "f" should be a procedure that accepts two arguments: Argument 1 is the message to log (as a string); Argument 2 is the log level (as an integer). Example: MMS ------------ First we register with the Magma Messaging System server. Here we assume that an MMS server is running at fano.maths.usyd.edu.au. > MMSRegister("alex","fano.maths.usyd.edu.au"); We will enable logging and request that all messages are sent to "alex", then send a test log message: > SetLoggerToMMS("alex"); > Logger("Hello world"); In a different Magma instance we register with the MMS server and recover the logged message: > MMSRegister("alex","fano.maths.usyd.edu.au"); > MMSHasMessage(); true > MMSRead(); 2012-01-07 11:57:20: Hello world Example: MySQL -------------- Connecting to a MySQL server running on your own machine is trivial. For this example we assume that the database "test" already exists, and that a username and password are required. > SetLoggerToMySQL("test" : user:="alex", password:="secret"); > Logger("Hello world"); Open a new terminal window and connect to MySQL. You can recover the logged message by the SQL command "SELECT * FROM error_log;". For example: % mysql -u alex -p -D test Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 624 Server version: 5.1.41 MySQL Community Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> SELECT * FROM error_log; +----+---------------------+-------+-------------+ | id | stamp | level | message | +----+---------------------+-------+-------------+ | 1 | 2010-11-22 10:39:37 | 2 | Hello world | +----+---------------------+-------+-------------+ 1 row in set (0.00 sec) If the MySQL database is hosted on a remote machine, you can use the parameters "host" (and, if necessary "port") to specify the connection details. > SetLoggerToMySQL("test" : user:="alex", password:="secret", host:="gino.maths.usyd.edu.au"); If you've entered your details incorrectly, you'll receive an error message such as this: >> SetLoggerToMySQL("test" : user:="alex", password:="secret", host:="gino.m ^ Runtime error in 'SetLoggerToMySQL': Unable to access MySQL database: mysql://alex@gino.maths.usyd.edu.au/test Remember that you can verify your connection details via the mysql command line tool. Example: Sqlite --------------- First start logging to an Sqlite database: > SetLoggerToSqlite("~/test.db"); > Logger("Hello world"); In a new terminal, connect to the database via the sqlite3 command: % sqlite3 -column -header ~/test.db Note: -column and -header are optional arguments which provide nicer formatted output. For example, to list all log entries you could type "SELECT * FROM error_log": % sqlite3 -column -header ~/test.db SQLite version 3.6.12 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> SELECT * FROM error_log; id stamp level message ---------- ------------------- ---------- ----------- 1 2010-11-22 10:39:37 2 Hello world Example: UserProgram -------------------- Log messages can be sent to a user-defined procedure. This procedure should accept two arguments: The first argument will be the message (as a string); The second argument will be the log level (as an integer). First, a frivolous example: > procedure my_logger(message,level) > print "I recieved a message!"; > print message; > end procedure; > > SetLoggerToUserProgram(my_logger); > Logger("Hello world"); I recieved a message! Hello world Perhaps more usefully, you can take advantage of Magma's Pipe intrinsic to forward messages to some other UNIX tool. In the following example we use "mail" to send an e-mail containing the message (obviously you would need to substitute your own e-mail address for me@example.com). > procedure email_message(message,level) > subject:="Logger Priority " cat IntegerToString(level); > cmd:="echo \"" cat message cat "\" | " cat "mail -s \"" cat subject cat "\" me@example.com"; > _:=Pipe(cmd,""); > end procedure; > SetLoggerToUserProgram(email_message); > Logger("Hello world"); Controlling the logger ---------------------- By default the logger is disabled. You can enable it explicitly via the EnableLogger intrinsic. It is also enabled automatically when you call any of the SetLoggerTo... intrinsics described above. Messages are passed to the logger only if they have a high enough log level. The default level of a message is 2, however it can be specified explicitly via: Logger( message, level) Log the message with the logger at the specified level. Only messages with a level greater than or equal to the value of GetLoggerLevel will be passed to the logger. GetLoggerLevel() -> RngIntElt The minimum level for which logging will occur. You can adjust the logger level via: SetLoggerLevel( level) Specifies the minimum level for which logging will occur. The minimum level is 0 (corresponding to the lowest priority message), and the maximum level is 4. Logging can be disabled via the DisableLogger intrinsic. You can determine if logging is currently enable by calling IsLoggerEnabled.