Kirk Rader  1.0-SNAPSHOT
Status Codes

Status codes for monitoring and reporting.

Overview

The us.rader.logging.statuscodes package provides utilities for declaring and using information to drive monitoring and reporting for Java based applications.

Custom Annotations

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

Note
Monitored components correspond to the conceptual level at which applications should be monitored and reported for use by operations and support staff. The log messages for such components as described below will also include class and method names, stack traces and the like sufficient to aid developers when escalating issues detected by monitoring and searching log entries.

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.

Note
This is different from Java's built-in support for inheritance using the @Inherited annotation. Annotations marked with @Inherited are inherited according to similar rules by which types inherit functionality. I.e. according to Java's built-in @Inherited mechanism, 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 enum that 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 @Inherited annotation but is implemented by the utility functions defined by us.rader.logging.statuscodes.MonitoredStatusCodeInfoList.

Extraction

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.

Logging and Monitoring

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.