log4sh

Kate Ward


            
          

2006-03-25

Revision History
Revision 1.3.42006-03-25kwd
Revision 1.3.32006-02-11kwd
Revision 1.3.22006-01-18kwd
Revision 1.3.02005-08-15kwd
Revision 1.2.62005-02-01kwd
Revision 1.2.42004-12-28kwd

Abstract

log4sh is a logging framework for shell scripts that works similar to the other wonderful logging products available from the Apache Software Foundataion (eg. log4j, log4perl). Although not as powerful as the others, it can make the task of adding advanced logging to shell scripts easier. It has much more power than just using simple "echo" commands throughout. In addition, it can be configured from a properties file so that scripts in a production environment do not need to be altered to change the amount of logging they produce.


Table of Contents

1. Introduction
1. Credits / Contributors
2. Feedback
2. Quickstart
3. Usage Guide
1. Preconfigure log4sh (optional)
2. Source log4sh
3. Configure log4sh in code
4. Logging with log4sh
4. Configuration
1. Properties File
1.1. Root Logger
1.2. Levels
1.3. Appenders
2. Environment Variables
5. Function Reference
1. Appenders
2. FileAppender
3. Levels
4. Logger
5. PatternLayout
6. SMTPAppender
7. SyslogAppender
8. Threads
9. arrays
10. miscellaneous
11. properties
6. Conclusion

List of Tables

4.1. Logging Levels (from most output to least)
4.2. Appender Types
4.3. Appender Options
4.4. Layouts
4.5. Pattern Options
4.6. log4sh environment variables
5.1. Appenders
5.2. FileAppender
5.3. Levels
5.4. Logger
5.5. PatternLayout
5.6. SMTPAppender
5.7. SyslogAppender
5.8. Threads
5.9. arrays
5.10. miscellaneous
5.11. properties

List of Examples

2.1. Hello, World!
2.2. Properties Configuration Test
2.3. Runtime Configuration Test
3.1. Sourcing external shell code into current program
3.2. Hello, world (using properties file)
3.3. Hello, world; properties file
3.4. Hello, world (configured in code)
4.1. Recommended minimum log4sh.properties file
4.2. Sample appender names
4.3. Setting an appender type
4.4. Setting an appender option
4.5. Setting an appender's layout
4.6. Setting an appender's layout pattern
4.7. LOG4SH_CONFIGURATION variable
4.8. LOG4SH_CONFIG_PREFIX variable

Chapter 1. Introduction

Log4sh has been developed under the Bourne Again Shell (bash) on Linux, but great care has been taken to make sure it works under the default Bourne Shell of Solaris (sh) as this happens to be the primary platform used by myself.

Tested Operating Systems

  • Cygwin

  • FreeBSD

  • Linux

  • Solaris 8, 9, 10

Tested Shells

  • Bourne Shell (sh)

  • Bourne Again Shell (bash)

  • Korn Shell (ksh, pdksh)

1. Credits / Contributors

A list of contributors to log4sh can be found in the source archive as doc/contributors.txt. I want to personally thank all those who have contributed to make this a better tool.

2. Feedback

Feedback is most certainly welcome for this document. Send your additions, comments and criticisms to the following email address: .

Chapter 2. Quickstart

First things first. Go to the directory from which you extracted the log4sh software. In there, you should find a Makefile file. If you find one, you are in the right place. We need to setup the environment for running tests, so from this directory, execute the make command as shown below. Once this is done, the test directory will be prepared with everything needed to run the log4sh tests.

Prepare your environment.

$ make test-prep
$ cd test

Example 2.1. Hello, World!

Ok. What kind of a quickstart would this be if the first example wasn't a "Hello, World!" example? Who knows, but this isn't one of those kind of quickstarts.

Run the Hello World test.

$ ./test-hello_world
0 [main] INFO shell  - Hello, world

You should have seen output similar to that above. If not, make sure you are in the right location and such. If you really had problems, please send a letter to the log4sh maintainers. Who knows, maybe you already found a bug. Hopefully not!

The Hello World test is about as simple as it gets. If you take a look at the test, all it does is load log4sh, reset the default logging level from ERROR to INFO, and the logs a message. As you can see, it didn't take much to setup and use log4sh.

Example 2.2. Properties Configuration Test

In this example, a log4sh.properties configuraiton file will be used to pre-configure log4sh before any logging messages are output. It demonstrates that a configuration file can be used to alter the behavior of log4sh without having to change any shell code.

Run the properties configuration test.

$ ./test-prop-config
INFO - We are the Simpsons!
INFO - Mmmmmm .... Chocolate.
INFO - Homer likes chocolate
...

You should see much more output on your terminal that what was listed above. What is actually happening is log4sh is outputting information to STDERR using logging statements that were stored in the test-common script. In addition, there were multiple logfiles generated (take a look in the directory), and output was written to syslog. Take a look at both the property configuration script and the common script if you like to see what is happening. What you will notice is that nowhere was it configured to write to the any of those different locations. The log4sh.properties configuration file did all of that work. Take a look at it too. You might be amazed with how easy it was to write to so many locations with such a small amount of code.

Example 2.3. Runtime Configuration Test

This example is exactly like the last example as far as output is concerned (they both execute the same logging messages), but this one is configured instead at runtime with function calls. It demonstrates that log4sh is fully configurable at runtime.

Run the runtime configuration test.

$ ./test-runtime-config
INFO - We are the Simpsons!
INFO - Mmmmmm .... Chocolate.
INFO - Homer likes chocolate
...

You should again see much more output on your terminal that what was listed above. The output should also have been exactly the same (except that the times were different) as the above example. This is because the same logging commands were used. If you take a look a look in the test-runtime-config script though, you will see that log4sh was configured completly at runtime. The log4sh.properties was not used. It shows that log4sh can be fully configured without a pre-existing configuration file. This isn't nearly as friendly as using the configuration file, but there are times when it is needed.

Chapter 3. Usage Guide

The usage of log4sh is simple. There are only a few simple steps required to setup and use log4sh in your application.

  1. preconfigure log4sh (properties file)

  2. source the log4sh script code into the shell script

  3. configure log4sh in code (optional)

  4. call logging statements

1. Preconfigure log4sh (optional)

To preconfigure log4sh, create a properties file (see the Properties File later in this document). If the properties file is not located in the same directory as log4sh, set the LOG4SH_CONFIGURATION environment variable to the full path to the properties file. If you do not wish to preconfigure log4sh, please read the Configure log4sh in code section later in this chapter.

2. Source log4sh

To source the code into your script (also known as including), one uses the sourcing ability of shell to source one script into another. See the following quick example for how easy this is done.

Example 3.1. Sourcing external shell code into current program

#! /bin/sh

# source log4sh from current directory
. ./log4sh

Here is some sample code that looks for log4sh in the same directory as the script is located, as well as the current directory. If log4sh could not be found, it exits with an error. If log4sh is found, it is loaded, along with the log4sh.properties file in the current directory (see the following example). It then logs a message at the INFO level to STDOUT.

Example 3.2. Hello, world (using properties file)

#! /bin/sh
#
# log4sh example: Hello, world
#
myDir=`dirname $0`

# find and source log4sh
if [ -r "$myDir/log4sh" ]; then
  log4shDir=$myDir
elif [ -r "./log4sh" ]; then
  log4shDir=.
else
  echo "fatal: could not find log4sh" >&2
  exit 1
fi
. $log4shDir/log4sh

# say Hello to the world
logger_info "Hello, world"

Here is the log4sh.properties file for the previous example. Save it in the same directory you are running the above script from.

Example 3.3. Hello, world; properties file

#
# log4sh example: Hello, world properties file
#

# Set root logger level to DEBUG and its only appender to A1
log4sh.rootLogger=INFO, A1

# A1 is set to be a ConsoleAppender.
log4sh.appender.A1=ConsoleAppender

# A1 uses a PatternLayout.
log4sh.appender.A1.layout=PatternLayout
log4sh.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

3. Configure log4sh in code

If log4sh was not preconfigured, the default configuration will be equivalent the config shown below. Please note: log4sh will complain if no configuration file was found. If you meant for the default configuration to be used, or you want to configure log4sh via code, make sure to define the LOG4SH_CONFIGURATION with the value of "none".

log4sh.rootLogger=ERROR, stdout
log4sh.appender.stdout=ConsoleAppender
log4sh.appender.stdout.layout=PatternLayout
log4sh.appender.stdout.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

To configure log4sh in code, simply call the appropriate functions in your code. The following code sample loads log4sh from the current directory, configures it for STDERR output, and the logs a message at the INFO level.

Example 3.4. Hello, world (configured in code)

#! /bin/sh
#
# log4sh example: Hello, world
#

# source log4sh (disabling properties file warning)
LOG4SH_CONFIGURATION='none' . ./log4sh

# set the global logging level
logger_setLevel INFO

# close the default STDOUT appender, and add a new STDERR appender
appender_close stdout
logger_addAppender stderr
appender_setType stderr FileAppender
appender_file_setFile stderr STDERR

# say Hello to the world
logger_info 'Hello, world'

4. Logging with log4sh

Once log4sh is loaded, logging is as simple as calling the appropriate logging function with a message to be logged. Take a look at the above examples to see just how easy it was to log the statement "Hello, world" at an INFO level.

Chapter 4. Configuration

1. Properties File

Log4sh can be configured with a properties file that is separate from the actual script where the logging takes place. By default, log4sh looks for its properties file called log4sh.properties in the current directory. If the file is located elsewhere or with a different name, log4sh can be configured by setting the LOG4SH_CONFIGURATION environment variable (eg. LOG4SH_CONFIGURATION="/etc/log4sh.conf").

A log4sh.properties file that is completly empty is sufficient to configure log4sh. There will be absolutely no output however (which might just be what is desired). Usually though, some output is desired, so there is at least a recommended minimum configuration file. An explaination of the file follows the example.

Example 4.1. Recommended minimum log4sh.properties file

  log4sh.rootLogger=INFO, stdout
  log4sh.appender.stdout=ConsoleAppender
  

In the first line, the root logger is configured by setting the default logging level, and defining the name of an appender. In the second line, the stdout appender is defined as a ConsoleAppender.

1.1. Root Logger

(future)

1.2. Levels

Table 4.1. Logging Levels (from most output to least)

LevelDefinition
TRACEThe TRACE level has the lowest possible rank and is intended to turn on all logging.
DEBUGThe DEBUG level designates fine-grained informational events that are most useful to debug an application.
INFOThe INFO level designates informational messages that highlight the progress of the application at coarse-grained level.
WARNThe WARN level designates potentially harmful situations.
ERRORThe ERROR level designates error events that might still allow the application to continue running.
FATALThe FATAL level designates very severe error events that will presumably lead the application to abort.
OFFThe OFF level has the highest possible rank and is intended to turn off logging.

1.3. Appenders

An appender name can be any alpha-numeric string containing no spaces.

Example 4.2. Sample appender names

myAppender - good

1.3.1. Types

An appender can be set to one of several different types.

Example 4.3. Setting an appender type

    log4sh.appender.A1=FileAppender
    

Table 4.2. Appender Types

TypeDefinitionSupported?
ConsoleAppenderoutput sent to console (STDOUT)yes
FileAppenderoutput sent to a fileyes
DailyRollingFileAppenderoutput sent to a file that rolls over dailypartial; logs written, but not rotated
RollingFileAppenderoutput sent to a file that rolls over by sizepartial; works, but nees improvement
SMTPAppenderoutput sent via emailparital; works, but needs improvement
SyslogAppenderoutput sent to a remote syslog daemonpartial; only localhost supported

1.3.2. Options

An appender can take several different options.

Example 4.4. Setting an appender option

    log4sh.appender.A1.File=output.log
    

Table 4.3. Appender Options

OptionDefinitionSupported?
DatePatternconfigure a pattern for the output filenameno (ignored)
Fileoutput filename (special filename of STDERR used for logging to STDERR)yes
MaxBackupIndexnumber of old logfiles to keepno (ignored)
MaxFileSizemaximum size of old logfilesno (ignored)
Thresholdlogging level of the appenderyes

1.3.3. Layouts

An appender can be configured with various Layouts to customize how the output looks.

Example 4.5. Setting an appender's layout

    log4sh.appender.A1.layout=PatternLayout
    

Table 4.4. Layouts

LayoutDefinitionSupported?
HTMLLayoutlayout using HTMLno (same as SimpleLayout)
SimpleLayouta simple default layout ('%p - %m')yes
PatternLayouta patterned layout (default: '%d %p - %m%n')yes

An layout has many different options to configure how it appears. These are known as patterns.

Example 4.6. Setting an appender's layout pattern

    log4sh.appender.A1.layout.ConversionPattern=%d [%p] %c - %m%n
    

Table 4.5. Pattern Options

OptionDefinitionSupported?
cUsed to output the category of logging request. As this is not applicable in shell, the conversion character will always returns 'shell'.partial (fixed)
d

Used to output the date of the logging event. The date conversion specifier may be followed by a date format specifier enclosed between braces, but this specifier will be ignored. For example, %d{HH:mm:ss,SSS}, or %d{ISODATE}. The specifier is allowed only for compatibility with log4j properties files.

The default format of the date returned is equavilant to the output of the Unix date command with a format of +%Y-%m-%d %H:%M:%S.

yes
F

Used to output the file name where the logging request was issued.

The default value is equavilent basename $0.

yes
LThis option is for compatibility with log4j properties files.no (ignored)
mUsed to output the script supplied message associated with the logging event.yes
nThis option is for compatibility with log4j properties files.no (ignored)
pUsed to output the priority of the logging event.yes
rUsed to output the number of seconds elapsed since the start of the script until the creation of the logging event.partial (bash, ksh)
t

Used to output the current executing thread. As shell doesn't actually support threads, this is simply a value that can be set that can be put into the messages.i

The default value is 'main'.

yes
xThis option is for compatibility with log4j properties files.no (ignored)
XUsed to output the MDC (mapped diagnostic context) associated with the thread that generated the logging event. The X conversion character must be followed by an environment variable name placed between braces, as in %X{clientNumber} where clientNumber is the name of the environment variable. The value in the MDC corresponding to the environment variable will be output.no (ignored)
%The sequence %% outputs a single percent sign.yes

2. Environment Variables

There are some environment variables that can be used to pre-configure log4sh, or to change some of its default behavior. These variables should be set before log4sh is sourced so that they are immediately available to log4sh.

Here is the full list of supported variables.

Table 4.6. log4sh environment variables

VariableUsage
LOG4SH_CONFIGURATION

This variable is used to tell log4sh what the name of (and possibly the full path to) the configuration (a.k.a properties) file that should be used to configure log4sh at the time log4sh is sourced. If the value 'none' is passed, than log4sh will expect to be configured at a later time via run-time configuration.

Example 4.7. LOG4SH_CONFIGURATION variable

LOG4SH_CONFIGURATION='/path/to/log4j.properties'
LOG4SH_CONFIG_PREFIX

This variable is used to tell log4sh what prefix it should use when parsing the configuration file. Normally, the default value is 'log4sh' (e.g. 'log4sh.rootLogger'), but the value can be redefined so that a configuration file from another logging frame work such as log4j can be read.

Example 4.8. LOG4SH_CONFIG_PREFIX variable

LOG4SH_CONFIG_PREFIX='log4j'

Chapter 5. Function Reference

1. Appenders

Table 5.1. Appenders

string
_appender_getLayoutByIndex (index); 
integer  index;

Gets the Layout of an Appender at the given array index

type=`_appender_getLayoutByIndex 3`
string
_appender_getLevelByIndex (index); 
integer  index;

Gets the current logging Level of an Appender at the given array index

type=`_appender_getLevelByIndex 3`
string
_appender_getNameByIndex (index); 
integer  index;

Gets the name of the appender at the given position in the appender array.

appenderName=`_appender_getNameByIndex 3`
string
_appender_getPatternByIndex (index); 
integer  index;

Gets the Pattern of an Appender at the specified array index

pattern=`_appender_getPatternByIndex 3`
string
_appender_getTypeByIndex (index); 
integer  index;

Gets the Type of an Appender at the given array index

type=`_appender_getTypeByIndex 3`
string
_appender_parsePattern (pattern,  
 priority,  
 message); 
string  pattern;
string  priority;
string  message;

Generate a logging message given a Pattern, priority, and message. All dates will be represented as ISO 8601 dates (YYYY-MM-DD HH:MM:SS).

Note: the '%r' character modifier does not work in the Solaris /bin/sh shell

Example:

_appender_parsePattern '%d %p - %m%n' INFO "message to log"
void
_appender_setNameByIndex (index,  
 appenderName); 
integer  index;
string  appenderName;

(future) Sets the name of the appender at the given position in the appender array.

_appender_setNameByIndex 3 "myAppender"`
void
appender_close (appender); 
string  appender;

Disable any further logging via an appender. Once closed, the appender can be reopened by setting it to any logging Level (e.g. INFO).

appender_close myAppender
boolean
appender_exists (appender); 
string  appender;

Checks for the existance of a named appender

exists=`appender_exists myAppender`
string
appender_getAppenderType (index); 
integer  index;

(deprecated) Gets the Type of an Appender at the given array index

type=`appender_getAppenderType 3`
string
appender_getLayout (appender); 
string  appender;

Gets the Layout of an Appender

type=`appender_getLayout myAppender`
string
appender_getLevel (appender); 
string  appender;

Gets the current logging Level of an Appender

type=`appender_getLevel myAppender`
string
appender_getPattern (appender); 
string  appender;

Gets the Pattern of an Appender

pattern=`appender_getPattern myAppender`
string
appender_getType (appender); 
string  appender;

Gets the Type of an Appender

type=`appender_getType myAppender`
void
appender_setAppenderType (appender,  
 type); 
string  appender;
string  type;

(deprecated) Sets the Type of an Appender (e.g. FileAppender)

appender_setAppenderType myAppender FileAppender
void
appender_setLayout (appender,  
 layout); 
string  appender;
string  layout;

Sets the Layout of an Appender (e.g. PatternLayout)

appender_setLayout myAppender PatternLayout
void
appender_setLevel (appender,  
 level); 
string  appender;
string  level;

Sets the Level of an Appender (e.g. INFO)

appender_setLevel myAppender INFO
void
appender_setPattern (appender,  
 pattern); 
string  appender;
string  pattern;

Sets the Pattern of an Appender

appender_setPattern myAppender '%d %p - %m%n'
void
appender_setType (appender,  
 type); 
string  appender;
string  type;

Sets the Type of an Appender (e.g. FileAppender)

appender_setType myAppender FileAppender
void
logger_addAppender (appender); 
string  appender;

Add and initialize a new appender

logger_addAppender $appender
void
logger_addAppenderWithPattern (appender,  
 pattern); 
string  appender;
string  pattern;

Add and initialize a new appender with a specific PatternLayout

logger_addAppenderWithPattern $appender '%d %p - %m%n'

2. FileAppender

Table 5.2. FileAppender

string
_appender_file_getFileByIndex (index); 
integer  index;

Get the filename of a FileAppender at the given array index

_appender_file_getFileByIndex 3
string
appender_file_getFile (appender); 
string  appender;

Get the filename of a FileAppender

appender_file_getFile myAppender
void
appender_file_setFile (appender,  
 filename); 
string  appender;
string  filename;

Set the filename for a FileAppender (e.g. "STDERR" or "/var/log/log4sh.log")

appender_file_setFile myAppender STDERR
void
appender_setAppenderFile (appender,  
 filename); 
string  appender;
string  filename;

(deprecated) Set the filename for a FileAppender (e.g. "STDERR" or "/var/log/log4sh.log")

appender_setAppenderFile myAppender STDERR
void/boolean
appender_setAppenderSubject (appender,  
 subject); 
string  appender;
string  subject;

(deprecated) Sets the email subject for an SMTP appender

appender_setAppenderSubject myAppender "This is a test"
void/boolean
appender_smtp_setSubject(appender,  
 subject); 
string  appender;
string  subject;

Sets the email subject for an SMTP appender

appender_smtp_setSubject myAppender "This is a test"

3. Levels

Table 5.3. Levels

string
logger_getLevel (); 

Gets the global default logging level (e.g. DEBUG).

level=`logger_getLevel`
void
logger_setLevel (level); 
string  level;

Sets the global default logging level (e.g. DEBUG).

logger_setLevel INFO

4. Logger

Table 5.4. Logger

void
log (level,  
 message(s)); 
string  level;
string[]  message(s);

The base logging command that logs a message to all defined appenders

log DEBUG "This is a test message"`
void
logger_debug (message); 
string[]  message;

This is a helper function for logging a message at the DEBUG priority

logger_debug "This is a debug message"`
void
logger_error (message); 
string[]  message;

This is a helper function for logging a message at the ERROR priority

logger_error "This is a error message"`
void
logger_fatal (message); 
string[]  message;

This is a helper function for logging a message at the FATAL priority

logger_fatal This is a fatal message`
void
logger_info (message); 
string[]  message;

This is a helper function for logging a message at the INFO priority

logger_info "This is a info message"`
void
logger_trace (message); 
string[]  message;

This is a helper function for logging a message at the TRACE priority

logger_trace "This is a trace message"`
void
logger_warn (message); 
string[]  message;

This is a helper function for logging a message at the WARN priority

logger_warn "This is a warn message"`

5. PatternLayout

Table 5.5. PatternLayout

void
logger_setFilename (filename); 
string  filename;

Set the filename to be shown when the '%F' conversion character is used in a PatternLayout.

logger_setFilename "myScript.sh"

6. SMTPAppender

Table 5.6. SMTPAppender

string
_appender_smtp_getSubjectByIndex (index); 
integer  index;

Get the email subject for the given appender

subject=`_appender_smtp_getSubjectByIndex 3`
string
_appender_smtp_getToByIndex (index); 
integer  index;

Get the email to address for the given appender

email=`_appender_smtp_getToByIndex 3`
void
appender_setAppenderRecipient (appender,  
 email); 
string  appender;
string  email;

(deprecated)Set the to address for the given appender

appender_smtp_setTo myAppender user@example.com
string
appender_smtp_getSubject (appender); 
string  appender;

Get the email subject for the given appender

subject=`appender_smtp_getSubject myAppender`
string
appender_smtp_getTo (appender); 
string  appender;

Get the to address for the given appender

email=`appender_smtp_getTo myAppender`
void
appender_smtp_setTo (appender,  
 email); 
string  appender;
string  email;

Set the to address for the given appender

appender_smtp_setTo myAppender user@example.com

7. SyslogAppender

Table 5.7. SyslogAppender

string
_appender_syslog_getFacilityByIndex (index); 
integer  index;

Get the syslog facility of the specified appender by index

facility=`_appender_syslog_getFacilityByIndex 3`
string
appender_getSyslogFacility (index); 
integer  index;

(deprecated) Get the syslog facility of the specified appender by index

facility=`appender_getSyslogFacility 3`
void
appender_setSyslogFacility (appender,  
 facility); 
string  appender;
string  facility;

(deprecated) Set the syslog facility for the given appender

appender_setSyslogFacility myAppender local4`
void
appender_syslog_getFacility (appender); 
string  appender;

Get the syslog facility for the given appender

facility=`appender_syslog_getFacility myAppender`
string
appender_syslog_getFacility (appender); 
string  appender;

(deprecated) Get the syslog facility for the given appender

facility=`appender_syslog_getFacilityByName myAppender`
string
appender_syslog_getFacilityByIndex (index); 
integer  index;

(deprecated) Get the syslog facility of the specified appender by index

facility=`appender_syslog_getFacilityByIndex 3`
string
appender_syslog_getHost (index); 
integer  index;

TODO: Get the syslog host of the specified appender

host=`appender_syslog_getHost myAppender`
void
appender_syslog_setFacility (appender,  
 facility); 
string  appender;
string  facility;

Set the syslog facility for the given appender

appender_syslog_setFacility myAppender local4`
void
appender_syslog_setHost (appender,  
 host); 
string  appender;
string  host;

TODO: Set the syslog host for the given appender

appender_syslog_setHost myAppender localhost`

8. Threads

Table 5.8. Threads

string
logger_getThreadName (); 

Gets the current thread name.

threadName=`logger_getThreadName`
void
logger_popThreadName (); 

Removes the topmost thread name from the stack. The next thread name on the stack is then placed in the __log4shThreadName variable. If the stack is empty, or has only one element left, then a warning is given that no more thread names can be popped from the stack.

logger_popThreadName
void
logger_pushThreadName (threadName); 
string  threadName;

Sets the thread name (eg. the name of the script) and pushes the old on to a stack for later use. This thread name can be used with the '%t' conversion character within a PatternLayout.

logger_pushThreadName "myThread"
void
logger_setThreadName (threadName); 
string  threadName;

Sets the thread name (e.g. the name of the script). This thread name can be used with the '%t' conversion character within a PatternLayout.

logger_setThreadName "myThread"

9. arrays

Table 5.9. arrays

integer
_log4sh_findArrayElement (array,  
 element); 
string[]  array;
string  element;

Find the position of element in an array

pos=`_log4sh_findArrayElement "$array" $element`
string
_log4sh_getArrayElement (array,  
 position); 
string[]  array;
integer  position;

Retrieve the element at the given position from an array

element=`_log4sh_getArrayElement "$array" $position`
integer
_log4sh_getArrayLength (array); 
string[]  array;

Get the length of an array

length=`_log4sh_getArrayLength "$array"`
string
_log4sh_peekStack (array); 
string[]  array;

Return the topmost element on a stack without removing the element.

element=`_log4sh_peekStack "$array"`
string[]
_log4sh_popStack (array); 
string[]  array;

Remove the top-most element from a stack. This command takes a normal log4sh string array as input, but treats it as though it were a stack.

newArray=`_log4sh_popStack "$array"`
string
_log4sh_pushStack (array,  
 element); 
string[]  array;
string  element;

Add a new element to the top of a stack. This command takes a normal log4sh string array as input, but treats it as though it were a stack.

newArray=`_log4sh_pushStack "$array" $element`
string[]
_log4sh_setArrayElement (array,  
 position,  
 element); 
string[]  array;
integer  position;
string  element;

Place an element at a given location in an array

newArray=`_log4sh_setArrayElement "$array" $position $element`

10. miscellaneous

Table 5.10. miscellaneous

void
_log4sh_cleanup (signal); 
string  signal;

This is a cleanup function to remove the temporary directory used by log4sh. It should only be called by log4sh itself when it is taking control of traps.

If there was a previously defined trap for the given signal, log4sh will attempt to call the original trap handler as well so as not to break the parent script.

_log4sh_cleanup EXIT
string
_log4sh_level2tag (level); 
integer  level;

Converts an internally used level constant into its external tag equivalent

tag=`_log4sh_level2tag 3`
string
_log4sh_mktempDir (); 

Creates a secure temporary directory within which temporary files can be created. Honors the TMPDIR environment variable if it is set.

tmpDir=`_log4sh_mktempDir`
integer
_log4sh_tag2level (tag); 
string  tag;

Converts an externally used level tag into its internal constant equivalent

level=`_log4sh_tag2level WARN`
void
log4sh_cleanup (

This is a cleanup function to remove the temporary directory used by log4sh. It is provided for scripts who want to do log4sh cleanup work themselves rather than using the automated cleanup of log4sh that is invoked upon a normal exit of the script.

log4sh_cleanup

11. properties

Table 5.11. properties

string
_log4sh_getPropPrefix (property); 
string  property;

Takes a string (eg. "log4sh.appender.stderr.File") and returns the prefix of it (everything before the first '.' char). Normally used in parsing the log4sh configuration file.

prefix=`_log4sh_getPropPrefix $property"`
void
_log4sh_propAppender (property,  
 value); 
string  property;
string  value;

Configures log4sh using an appender property configuration statement

_log4sh_propAppender $property $value
string
_log4sh_propLogger (property,  
 value); 
string  property;
string  value;

(future) Configures log4sh with a logger configuration statement. Sample output: "logger: property value".

result=`_log4sh_propLogger $property $value`
void
_log4sh_propRootLogger (rootLogger); 
string  rootLogger;

Configures log4sh with a rootLogger configuration statement. It expects a comma separated string similar to the following:

log4sh.rootLogger=ERROR, stderr, R

The first option is the default logging level to set for all of the following appenders that will be created, and all following options are the names of appenders to create. The appender names must be unique.

_log4sh_propRootLogger $value
string
_log4sh_stripPropPrefix (property); 
string  property;

Strips the prefix off a property configuration command and returns the string. E.g. "log4sh.appender.stderr.File" becomes "appender.stderr.File".

newProperty=`_log4sh_stripPropPrefix $property`
void
log4sh_readProperties (filename); 
string  filename;

Reads a properties file and calls appropriate configuration functions.

pos=`_log4sh_findArrayElement "$array" $element`

Chapter 6. Conclusion

The idea of log4sh is obviously not novel, but the availibility of such a powerful logging framework that is available in (nearly) pure shell is. Hopefully you will find it useful in one of your projects as well.

If you like what you see, or have any suggestions on improvements, please feel free to drop me an email at .

Log4sh is licensed under the GNU Lesser Public License. The contents and copyright of this document and all provided source code are owned by Kate Ward.