Kirk Rader 1.0-SNAPSHOT
Status codes for monitoring and reporting.
The us.rader.logging.statuscodes package provides utilities for declaring and using information to drive monitoring and reporting for Java based applications.
The us.rader.logging.statuscodes package defines two custom annotations:
The first annotation is used to declare that particular Java classes contribute to the implementation of a specific monitored component. Such components are conceptual and correspond to features of the application's software architecture and design. More than one application class can and should have the same value for us.rader.logging.statuscodes.MonitoredComponent if they all work together to implement some specific operation or function of the overall application. Classes that contribute to the implementation of disjoint functional components or services should be annotated with different values for us.rader.logging.statuscodes.MonitoredComponent
The second annotation is used to declare that specific constants represent specific application states or error conditions. While Java will allow you to annotate any field of any type with us.rader.logging.statuscodes.MonitoredStatusCode, to be effective this annotation should only be applied to public, static, final fields with non-
null values of types which have us.rader.logging.statuscodes.MonitoredComponent annotations or which are, themselves, members of types for which us.rader.logging.statuscodes.MonitoredComponent annotations can be found by recursive application of the reflection API, as described subsequently.
@Inheritedannotation. Annotations marked with
@Inheritedare inherited according to similar rules by which types inherit functionality. I.e. according to Java's built-in
@Inheritedmechanism, type B will inherit an annotation from type A only if there exists an "is a" relationship from B to A. When "inheriting" component id's, as described below, the logic is not based on such "is a" relationships. It is, instead, based on membership where an
enumthat is a member of another type, for example, will "inherit" a component id for purposes of extracting status code information from the type of which it is a member. This is not supported directly by Java's reflection API and its use of the
@Inheritedannotation but is implemented by the utility functions defined by us.rader.logging.statuscodes.MonitoredStatusCodeInfoList.
In addition to allowing developers to declare the existence of status codes and associating them with functional components, the us.rader.logging.statuscodes package supports extracting such information from a collection of classes at run time. In particular, us.rader.logging.statuscodes.MonitoredStatusCodeInfoList is a JSON / JAXB friendly wrapper for a collection of status reporting meta-data.
See the us.rader.logging.statuscodes.MonitoredStatusCodeInfoList::MonitoredStatusCodeInfoList constructor for the entry point to extract a collection of monitoring and reporting data from a given set of Java classes.
See us.rader.logging.AnnotationsAgent for helper mechanisms to obtain such a set of classes dynamically while an application is running, as described by the information page for the us.rader.logging package.
See the us.rader.logging.statuscodes.maven package for a Maven plugin to extract such monitoring data at build time and embedding it as a resource file in the corresponding JAR file.
In addition to extracting status code meta-data from a collection of Java classes, the us.rader.logging.statuscodes package includes facilities to simplify logging and reporting.
See us.rader.logging.statuscodes.Log::loadLogMessages for a utility function to load status code meta-data from a Java properties file embedded as a resource.
See us.rader.logging.statuscodes.Log::log for a utility function to write a log message in a standardized format amenable for use with monitoring and reporting applications and frameworks such as ELK or Splunk.
See the us.rader.logging.demo package for an example of how all this can be plumbed together at build and run time.