### Metrics Library

The Metrics library is available to application code to get production metrics from their applications. It allows applications to easily mark critical section for metrics gathering, without handling the details with the Metrics Extension.

Table 38. Artifact

Group ID | Artifact ID | Version
--- | --- | ---
org.qi4j.library | org.qi4j.library.metrics | 2.1

#### Usage

There are currently the following possibilities available;

- @TimingCapture - capture timing on a single method
- TimingCaptureAll - capture timing on all methods of a composite

Before looking at the details of these, we need to point out that there are some pre-conditions for Metrics to be working. First of all, you need to install a Metrics Extensions, most likely the Yammer Metrics Extension. See your chosen extension for details on how to do that.

Once the Metrics extension is installed, you will also need a suitable backend to gather all the data out of a production plant and likewise a good front-end to view this. See your chosen Metrics Extension for this as well.

#### TimingCaptureAll

There is a TimingCaptureAllConcern, which when added to a composite will install a Timer for every method call in the composite.

#### @TimingCapture

The `@TimingCapture` annotation can be placed on any method of the composite, to indicate that a Timer is wanted on that method.

Example;

    public interface Router
    {
        @TimingCapture
        List<Coordinate> route( String source, String destination );
    }

    public class RouterAlgorithm1
        implements Router
    {
        @Override
        public List<Coordinate> route( String source, String destination )
        {
        [...snip...]

        }
    }

    public class RouterAlgorithm2
        implements Router
    {
        @Override
        public List<Coordinate> route( String source, String destination )
        {
        [...snip...]

        }

        [...snip...]

            @Override
            public void assemble( ModuleAssembly module )
                throws AssemblyException
            {
                module.addServices( Router.class ).identifiedBy( "router1" ).withMixins( RouterAlgorithm1.class );
                module.addServices( Router.class ).identifiedBy( "router2" ).withMixins( RouterAlgorithm2.class );
                [...snip...]

            }
        }
    }

#### Which method?

It is valid to annotate either the composite interface methods or the mixin implementation methods. Any of the method declarations should work. From the testcases we have the following example;

    public interface Country extends TransientComposite
    {
        @Optional
        Property<String> name();

        void updateName( String newName );
    }

    @Mixins( Country1Mixin.class )
    public interface Country1 extends Country
    {

    }

    public static abstract class Country1Mixin
        implements Country1
    {

        @Override
        public void updateName( String newName )
        {
            name().set( newName );
        }
    }

    @Mixins( Country2Mixin.class )
    public interface Country2 extends Country
    {
    }

    public static abstract class Country2Mixin
        implements Country2
    {

        @Override
        public void updateName( String newName )
        {
            name().set( newName );
        }
    }

    @Mixins( Country3Mixin.class )
    @Concerns( TimingCaptureConcern.class )
    public interface Country3 extends Country
    {
    }

    public static abstract class Country3Mixin
        implements Country3
    {
        @Override
        @TimingCapture
        public void updateName( String newName )
        {
            name().set( newName );
        }
    }