VXML Server Logging Design
Before discussing the design of an individual logger, it is warranted to introduce the design of the logging mechanism within VXML Server. Knowledge of this design will help the logger developer create loggers that work harmoniously with the system.
The mechanism by which information is passed to a logger is through an event object. This object will encapsulate information about what just occurred, including a timestamp. Event objects are created by VXML Server in many different situations that belong to three levels: related to global activities, related to an application and related to a call session. The event object will contain all the information accessible to the logger for the particular event as well as information about the environment. For global level events, the environment varies. For some events the environment consists of HTTP information about the request such as parameters and headers. Other events were activated internally and so do not define any environment information. For application-level events such as an administration event, the environment consists of application data and global data (not call data since this event is not affiliated with a call). For call-level events such as a call start event, the environment consists of information about the call such as the ANI, element and session data, default audio path, etc. Since the purpose of a logger is to report information, loggers are limited to obtaining environment information and cannot change any value. Loggers may still need to store session-related information for its purposes so to accommodate this VXML Server provides loggers scratch data that is stored in the session and will be available to the logger only for those events associated with the session.
The following figure shows the class hierarchy for all events both global and application.
Notes on events:
ApplicationEventboth extend the generic event class
LoggerEvent. In this structure, new event types in the future can be added without affecting the existing class hierarchy.
All events have an ID, obtained by calling the
An 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 of them.
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
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 simultaneous callers.
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.
To 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 are summarized below:
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.