# Structured Log
Class StructuredLog
offers structured (as opposed to flat) logging. Nested sections (blocks) in Ruby code become nested XML elements in the log.
This sectioning allows you to group actions in your program, and that grouping carries over into the log.
Optionally, each section may include:
section
element by passing a string argument.
@[ruby](scripts/text.rb)
@[xml](logs/text.xml)
### Attributes
Add attributes to a section
element by passing a hash argument.
@[ruby](scripts/attributes.rb)
@[xml](logs/attributes.xml)
### Timestamps and Durations
Add a timestamp or duration to a section
element by passing a special symbol argument.
@[ruby](scripts/time.rb)
@[xml](logs/time.xml)
### Rescued Section
Add rescuing to a section
element by passing a special symbol argument.
For the rescued exception, the class, message, and backtrace are logged.
@[ruby](scripts/rescue.rb)
@[xml](logs/rescue.xml)
### Potpourri
Pass any mixture of arguments to method section
.
The section name must be first; after that, anything goes.
@[ruby](scripts/potpourri.rb)
@[xml](logs/potpourri.xml)
## Data
### Hash-LIke Objects
Use method put_each_pair
, or its alias put_hash
, to log an object that respond_to?(:each_pair)
.
@[ruby](scripts/hash.rb)
@[xml](logs/hash.xml)
### Array-Like Objects
Use method put_each_with_index
, or its aliases put_array
and put_set
, to log an object that respond_to?(:each_with_index)
.
@[ruby](scripts/array.rb)
@[xml](logs/array.xml)
### Other Objects
Use method put_data
to log any object.
@[ruby](scripts/data.rb)
@[xml](logs/data.xml)
### Formatted Text
Use method put_cdata
to log a string (possibly multi-line) as CDATA.
@[ruby](scripts/cdata.rb)
@[xml](logs/cdata.xml)
### Comment
Use method comment
to log a comment.
@[ruby](scripts/comment.rb)
@[xml](logs/comment.xml)
## Custom Logging
At the heart of class StructuredLog
is method put_element
. It logs an element, possibly with children, attributes, and text. Several methods call it, and you can too.
Basically, it's just like method section
, except that you choose the element name (instead of the fixed name section
).
Otherwise, it handles a block and all the same arguments as section
.
### Section
Create a custom section by calling method put_element
with a block. The custom section will have children if you call logging methods within the block.
@[ruby](scripts/custom_section.rb)
@[xml](logs/custom_section.xml)
### Entry
Create a custom entry by calling method put_element
without a block. The custom entry will not have children.
@[ruby](scripts/custom_entry.rb)
@[xml](logs/custom_entry.xml)
## Uncaught Exception
Finally, what about an uncaught exception, one not rescued by :rescue
?
When an exception is raised in a section that does not have :rescue
, the logger rescues and logs it anyway, just as if there were an invisible "outermost section" with :rescue
(which, in fact, there is).
Just as for a rescued exception, the log includes the exception's class, message, and backtrace.
@[ruby](scripts/exception.rb)
@[xml](logs/exception.xml)