Dumps input data to a file on disk.
The file location is logically related to the class or class group (from here onward named calling context) that invokes the module's logging functionality.
Note: the module is built on top of the ParamsProxy module, and therefore inherits its security model, base functionality and limitations.
built-in serialization of complex input data (objects, arrays);
built-in split functionality: there can be several volumes of a given log file, based on a file size constraint;
built-in trim functionality: or, there can be a single log file that automatically trims itself from top to bottom – as new content is logged to the file – based on a file size constraint;
built-in optional wrapping of logged content;
built-in optional stamping of entries with current date and time;*
configurable output using templates – for log file header and entries.
* via including the appropriate placeholders in the entries template.
The module is a singleton – therefor any configuration is shared system wide.
The module's API provides a single public method,
/** * Writes given data on disk. * If data is anything but a string, it is first serialized. */ log ($data);
one would invoke like this:
Logger::getInstance()->log ("FAIL: could not send email '$emailSubject' to $recipient; server responded: $error.");
Upon making this call, the module will use PHP's trace debug feature to figure out the name of the calling class and will try to match it against a context definition, as stated by the module's configuration file.
Note: more on configuration file, their use, structure and location in the ParamsProxy.html document.
If the calling class isn't part of any defined context, the default Main context will be assumed. The string passed as argument to log will then be written into the
<logs directory>/<context name>/log.txt
file (the file will be created if it doesn't yet exist). See also the insides about the split operation mode of the module.
The location of the <logs directory>
is the parent directory of the <configuration directory>
and cannot be changed. Therefore, the above could have been written as such:
<configuration directory>/../<context name>/log.txt
Note: for more on the configuration folder, please consult the ParamsProxy.html document.
The module is configured via its dedicated XML configuration file. The module introduces no syntax extensions to the standard defined by the ParamsProxy module.
Note: for more on the configuration files syntax, please consult the ParamsProxy.html document..
However, some values – shown in bold in the example below – are to be parsed by the module, and therefor must be entered literally.
<config for="Logger"> <param> <type>number</type> <name>maxFileSize</name> <value>125</value> </param> <param> <type>string</type> <name>operatingMode</name> <value>split</value> </param> <param> <type>number</type> <name>wrapLimit</name> <value>80</value> </param> <param> <type>string</type> <name>bannerTemplate</name> <value> <![CDATA[ FILE: %FILE NAME% <%FILE SIZE%> PATH: %FILE PATH% DESCRIPTION: Log file for the %RELATED CONTEXT NAME% STATUS: %FILE STATUS% as of %LAST MODIFIED DATE% ---------------------------------------------------------------------- ]]> </value> </param> <param> <type>string</type> <name>entryTemplate</name> <value> <![CDATA[[ %CALLING CLASS NAME% @ %Y%/%M%/%D%-%H%:%S% %CONTENT% ]]> </value> </param> <param> <type>array</type> <!-- This is a context name! There may be countless of them, as long as each name appears only once (or else will cause a fatal error). --> <name>LoginOperations</name> <value> <!-- This is a class name! A class that appeared in one context cannot appear in another (or else will cause a fatal error). --> <item>Authenticator</item> <item>CookieManager</item> <item>MailHandler</item> </value> </param> </config>
This example uses all parameters but not all possible values. Parameters, their usage and possible values are described in the next section.
PARAMETER NAME |
POSSIBLE VALUES |
COMMENTS |
---|---|---|
maxFileSize |
125 to 1250 |
Ranges from a hundred to a thousand bytes – with plenty of room for additional noise introduced by templates – for the log file upper size limit. If the log file is about to exceed its upper size limit, trimming or splitting occurs, based on the operatingMode parameter setting. If omitted, defaults to 125. |
operatingMode |
one of the "trim" or "split" words, literally |
Sets up the action to trigger when the log file is about to grow oversize due to incoming data. Trim will keep the file size the same but will alter content, by progressively deleting oldest entries until there is room for new ones. Split will keep both the file size and content the same, but will archive the file and will start writing to a new file instead. In this documentation, archived files are currently referred to as volumes. Making a log file into a volume is handled behind the scene, and simply means renaming it, i.e., from "log.txt" to "log.txt.2". The "log.txt.2" above means there are at least three volumes, – count starts from 1. The last (improperly named) volume is the log file currently being written, therefore its name is not altered: "log.txt". If omitted, this parameter defaults to trim. |
wrapLimit |
80 to 240 or -1 |
The number of chars to allow per each written line of the log file. "-1" will disable the feature. Wrapping line is aggressive, i.e., "middle word" splits can occur if there's no other available split point on a line (this is especially prone to happen with url-encoded links). By exception, the banner will never be split, rather trim horizontally to the wrapLimit number of chars (see next). Wrapping is off by default. |
bannerTemplate |
any string, optionally including one or more of the following placeholders, literally, in the form of %PLACEHOLDER%: "FILE PATH" "FILE SIZE" "FILE STATUS" "LAST MODIFIED DATE" "RELATED CONTEXT NAME" |
The banner of a log file represents a reserved, rectangular area found at the top of the file. This banner will always be wrapLimit columns by 5 rows (hardcoded) wide, regardless of the actual size needed by the banner template or the data that will populate the template. If a template taller than 5 rows has been defined, it will be populated, then trimmed to 5 lines starting at the top, then applied. An ellipsis (…) char will be added at the end of the last line to indicate trimming. If a template shorter than 5 rows has been defined, empty lines will be added to the bottom – which implies that, if no template is defined, 5 blank lines will be at the top of every log file. Template content does not wrap horizontally. If the applied, i.e., populated, template is greater than wrapLimit chars, each line will be trimmed at wrapLimit chars and ellipsis chars will be added to indicate trimming. If wrapping is disabled, the banner will be horizontally trimmed at 240 chars (the maximum wrapping value). Shorter lines in the banner will be right padded with spaces to the wrapping width (or the maximum wrapping value if disabled). Placeholder names are quite self-explanatory, except:
|
entryTemplate |
any string, optionally including one or more of the following placeholders, literally, in the form of %PLACEHOLDER%: "M" (for month) "D" (for day) "H" (for hour) "MIN" (for minute) "S" (for seconds) "CALLING CLASS NAME" "CONTENT" |
Each log file is comprised by a header and several entries. An entry represents the result of one call to the log() method (see the API section). Although entries will frequently only span one line, entries and lines mustn't be mistaken. The module internally adds a non printing start-of-heading char right before any entry; the module uses this delimiter for operations that involve entry manipulation, such as the trim functionality. Entries are stripped from null chars before printing, should they have any. A bell char is inserted after the first start-of-heading char in file, if the file has been trimmed. The entryTemplate parameter controls the printed look of an entry. Unlike the banner, entries do wrap, and have no limitations in lines number. New lines within entries content are preserved. The placeholders names are quite self-explanatory, except:
|
<context> nodes |
an array holding class names, in the form of "ClassName" |
Any param node with a name different from all of the above is considered to be a context definition. A context definition must be comprised of one or several unique class names and have an unique name. In other words, there cannot be several contexts named the same, nor can a class name appear in more than exactly one context definition. Failing to comply with any of the above will produce a fatal error. The rationale is to group calling classes into contexts, since it is likely to be impractical to have each calling class logging into its own log file – this can be achieved, though, by specifying a context with a single class. If none given, a context named "Main" is assumed, which will include all calling classes that will ever log (…). By exception, the "Main" context can be overridden by explicitly defining a context with this name. |
The module can only be called from within a class execution context.
The line ending in log files will be UNIX style, irrespective to the host operating system or the line ending used by the entries template or the original line ending of the content to be logged.