Monitors are POJOs
Monitor implementations are plain old Java objects that implement the Monitor interface. Client code obtains an instance of a monitor by instantiating one directly. Since ERMA deals with Monitors using an interface, the developer is free to implement their own Monitor. They might use this functionality to ensure required data is captured when instrumenting code, or to calculate new data from two or more pieces of data stored on the Monitor. Take advantage of this feature. Create custom Monitors to reduce the amount of monitoring code in your application logic.
Monitors contain attributes
Monitors store all their gathered data as attributes. Attributes are key/value pairs. The keys are Strings. The values can be any Object or Java primitive. Attributes can be decomposed to a representation that can be serialized to another VM.
Using a key/value system allows developers to add new data to a Monitor without needing to add an additional data field to the monitor implementation.
Attributes can be inheritable
When a monitor is instantiated, it inherits any attributes from its parent monitor that were set as inheritable. This feature can be used to have attributes about a user's request propagate down to the lowest levels of the system, without the developer needing to tunnel this data to the bottom layer. For example, it might be useful to know for every request going out of a VM, what the client IP address was of the request coming in. Rather than explicitly passing this data to the bottom of the stack (where it isn't needed for processing), the developer can simply add this as an inheritable attribute to a Monitor that wraps the entire transaction. When the Monitor at the bottom of the stack is processed, it will implicitly have this attribute set.
Processing of Monitors is highly configurable
When instrumenting the application code, developers need not worry about where the data will be sent to. Developers can feel free to include all relevant data in their monitoring code. The processor implementations can pick off the most relevant pieces.
MonitorProcessorFactory implementations are responsible for linking Monitors to MonitorProcessors. Depending on the implementation you use, configuration may be slighly different.
Errors during processing of Monitors cannot affect your application
ERMA goes to great pains to ensure that errors during processing of a Monitor do not propagate to the application code, potentially causing a user's request to fail due to an error in monitoring. For this reason, ERMA catches all Throwables when passing your Monitor to a MonitorProcessor. ERMA even catches Throwables for each MonitorProcessor individually, ensuring that one misbehaving processor doesn't affect other processors.
Instrumentation is testable
Though developers shouldn't need to worry about how the data they collect is used, they should ensure that their application continues to collect the data it's supposed to. ERMA can help in this case. Since processing is configurable, it's trivial to configure all Monitors to route to a mock monitor processor implementation. ERMA even has a mock implementation ready to use. In this way, you can ensure that your monitoring collects all the data you expect even during heavy refactoring.
Small API, Big library
ERMA's codebase is structured to present a small API for use by client code to instrument their application. ERMA also ships with a large library of processing code. This code is typically combined with the instrumentation application code at runtime to produce the desired monitoring environment.
orbitz-api-monitoring contains all the interfaces that describe the relationships between the various components of ERMA. These interfaces are tied together by the MonitoringEngine, a singleton class that controls the communication between Monitors and MonitorProcessors. This class is also responsible for some of the advanced features of ERMA such as attribute inheritance and monitor correlation. Also included in this artifact are two general purpose Monitor implementations: EventMonitor and TransactionMonitor. These implementations will not change often and are usable for most monitoring needs.
orbitz-lib-monitoring contains library code that will change often. Currently, this includes implementations of MonitorProcessorFactory and MonitorProcessor. Typically only your deployable applications will depend on this artifact.