application designer can define any number of loggers to use in an application
and an administrator can define any number of global loggers to deploy to
Unified CVP VXML Server. Logger instances are defined with unique names and
loggers can be built to support configurations. Multiple instances of the same
logger class can also be defined, with a different configuration for each.
Unified CVP VXML Server will then create a separate instance of the logger
class for each instance referenced in the application’s settings and in the
server configuration. Application logger instances are created when the
individual applications are initialized and are maintained for the lifetime of
the application. All events for the application, both application-level events
as well as call-level events, are handled by this single instance.
An instance variable in the logger class will allow it to maintain
information that spans calls. Global logger instances are created when VXML
Server initializes and are maintained for the lifetime of the system and hence
the logger class can maintain information that lasts the lifetime of the
system. It will handle any global events that occur.
A logger is
expected to register the events it wishes to act on. This
is done on logger initialization. When VXML Server loads, it initializes all
the global loggers and the loggers referenced for an application and records
which events each will act on. When a situation occurs that would constitute an
event, VXML Server checks to see if any loggers will act on the event and if
so, will create the event object and pass it to the logger instances. This
registration mechanism allows VXML Server to save the overhead in creating an
event if no loggers will act on it. Additionally, should there be multiple
loggers acting on an event, only one event object is created and passed to all
In order to ensure that no call be held up due to logging
activities, the entire VXML Server logging mechanism is fully multi-threaded.
The only logging-related activity that an HTTP request thread (provided by the
application server) performs is creating an event object and adding it to a
queue. It does not actually handle the logging of that event and once it has
added the event to the queue, it continues with the call. A separate,
constantly running asynchronous process, called the Logger Manager, will
process the events in the queue. This allows the logging process to act
independently from the process of handling a call and so will not directly
affect the performance of the system.
In order to ensure that no
logger be held up due to the activities of another logger (or the same logger)
while handling an event, a second layer of threads are used. While the Logger
Manager handles the queue, when it is time for a logger to be given the event
to handle, this is itself done in a separate thread. The Logger Manager
therefore is responsible only for managing the queue of events and spawning
threads for loggers to handle them. This ensures that a logger that takes a
long time to handle an event does not hold up the logging for the same or other
applications, it only holds up the thread in which it is running. A thread
pooling mechanism exists to efficiently manage thread use. To avoid creating
too many threads when under load, the maximum number of allowable threads in
the pool can be configured in the global configuration file named
global_config.xml found in the conf directory of
VXML Server by editing the contents of the
<maximum_thread_pool_size> tag. For a thread
to be reused after it is done with the current task, the
<keep_alive_time> tag from the same
configuration file can be set. When all the allowable threads in the pool are
taken, VXML Server will not process the queue until a thread becomes available
from the pool.
One of the consequences here is that the longer the
events remain in the queue, the less real-time the logging
will occur. Additionally, if the maximum thread pool size is made too low to
handle a given call volume, the queue can become very large and could
eventually cause issues with memory and spiking CPU. Typically, though, a
logger handles an event in a very short period of time, allowing a small number
of threads to handle the events created by many times that number of
There are times when the true asynchronous
nature of the logging design works against the developer. The tasks done by a
logger can take a variable amount of time to complete so there is no guarantee
when a call event will be handled. This is by design, and for a logger that
simply records events that are then sorted by timestamp later, this is not a
problem. A logger that requires more context, though, could encounter issues.
For example, if a logger needed to note when a call was received so that an
event that occurred later on in the call could be handled correctly, problems
could be encountered because there would be no guarantee that the events would
be handled in the same order they occurred within the call.
remedy this situation while keeping the design unfettered, it is possible to
specify that VXML Server pass a logger instance events in the same order they
occurred in a call. With this option on, the logger developer can be assured
that the events for a call would not be handled out of order. In fact, the
Activity Logger included with VXML Server has this requirement. The penalty for
this requirement, however, is a loss of some of the true asynchronous nature of
the system as there will now be situations where events that are ready to be
handled must wait for a previous event to be handled by the logger. If a logger
hung while handling one event, the queue would forever contain the events that
occurred after it in the call, and that call session would not be fully logged.
This feature, however, is available to application loggers only, global loggers
handle their events as soon as a thread is allocated from the pool to handle
it. This is understandable because global log events are more holistic in
nature and do not track detailed behavior as application loggers do.
Some of the conclusions that can be deduced from the VXML Server
logging design can be summarized in some best practices:
- A logger developer need not worry about the time taken by the logger to
handle an event as it will have no bearing on the performance of the call. With
that said, the developer must also be aware of the expected call volume and
ensure that the logger not take so long as to use up the event threads faster
than they can be handled.
- Loggers work under a
multi-threaded environment and the logger developer must understand how to code
with this in mind. A single logger class can be handling events for many calls
and so it must manage internal and external resources in a synchronized manner
to prevent non-deterministic behavior.
- When possible,
design an application logger so that it does not rely on events within a call
being passed to it in the order in which they occurred in the call. Doing so
will maximize performance due to being able to handle events whenever they
occur. Should the logger be unable to do so, require that the enforce call
event order option be turned on for the logger.