Skip to content

Commit

Permalink
Merge pull request #667 from Channyboy/mpm5prop-customScopes
Browse files Browse the repository at this point in the history
 Provide support for user defined Custom Scopes for Metric Registries
  • Loading branch information
Channyboy committed Aug 6, 2022
2 parents a80ebd6 + 486eec5 commit 2a882f5
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 119 deletions.
Expand Up @@ -43,42 +43,19 @@
public interface MetricRegistry {

/**
* An enumeration representing the scopes of the MetricRegistry
*/
enum Type {
/**
* The Application (default) scoped MetricRegistry. Any metric registered/accessed via CDI will use this
* MetricRegistry.
*/
APPLICATION("application"),

/**
* The Base scoped MetricRegistry. This MetricRegistry will contain required metrics specified in the
* MicroProfile Metrics specification.
*/
BASE("base"),

/**
* The Vendor scoped MetricRegistry. This MetricRegistry will contain vendor provided metrics which may vary
* between different vendors.
*/
VENDOR("vendor");

private final String name;

Type(String name) {
this.name = name;
}

/**
* Returns the name of the MetricRegistry scope.
*
* @return the scope
*/
public String getName() {
return name;
}
}
* String constant to represent the scope value used for the application scope
*/
public static final String APPLICATION_SCOPE = "application";

/**
* String constant to represent the scope value used for the vendor scope
*/
public static final String VENDOR_SCOPE = "vendor";

/**
* String constant to represent the scope value used for the base scope
*/
public static final String BASE_SCOPE = "base";

/**
* Concatenates elements to form a dotted name, eliding any null values or empty strings.
Expand Down Expand Up @@ -751,10 +728,10 @@ static String name(Class<?> klass, String... names) {
Map<String, Metadata> getMetadata();

/**
* Returns the type of this metric registry.
* Returns the scope of this metric registry.
*
* @return Type of this registry (VENDOR, BASE, APPLICATION)
* @return Scope of this registry (VENDOR, BASE, APPLICATION)
*/
Type getType();
String getScope();

}
Expand Up @@ -29,6 +29,7 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.eclipse.microprofile.metrics.MetricRegistry;
import org.eclipse.microprofile.metrics.MetricUnits;

import jakarta.enterprise.util.Nonbinding;
Expand Down Expand Up @@ -144,4 +145,13 @@
@Nonbinding
String unit() default MetricUnits.NONE;

/**
* The scope that this counter belongs to.
*
* @return The scope this counter belongs to. By default, the value is {@link MetricRegistry.APPLICATION_SCOPE}.
*
*/
@Nonbinding
String scope() default MetricRegistry.APPLICATION_SCOPE;

}
@@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (c) 2017 Contributors to the Eclipse Foundation
* Copyright (c) 2017, 2022 Contributors to the Eclipse Foundation
* 2010-2013 Coda Hale, Yammer.com
*
* See the NOTICES file(s) distributed with this work for additional
Expand All @@ -27,6 +27,8 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.eclipse.microprofile.metrics.MetricRegistry;

import jakarta.enterprise.util.Nonbinding;
import jakarta.interceptor.InterceptorBinding;

Expand Down Expand Up @@ -115,4 +117,13 @@
@Nonbinding
String unit();

/**
* The scope that this gauge belongs to.
*
* @return The scope this gauge belongs to. By default, the value is {@link MetricRegistry.APPLICATION_SCOPE}.
*
*/
@Nonbinding
String scope() default MetricRegistry.APPLICATION_SCOPE;

}
@@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (c) 2017, 2019 Contributors to the Eclipse Foundation
* Copyright (c) 2017, 2022 Contributors to the Eclipse Foundation
* 2012 Ryan W Tenney (ryan@10e.us)
*
* See the NOTICES file(s) distributed with this work for additional
Expand All @@ -27,6 +27,7 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.eclipse.microprofile.metrics.MetricRegistry;
import org.eclipse.microprofile.metrics.MetricUnits;

import jakarta.enterprise.util.Nonbinding;
Expand Down Expand Up @@ -114,4 +115,12 @@
@Nonbinding
String unit() default MetricUnits.NONE;

/**
* The scope that this metric belongs to.
*
* @return The scope this metric belongs to. By default, the value is {@link MetricRegistry.APPLICATION_SCOPE}.
*
*/
@Nonbinding
String scope() default MetricRegistry.APPLICATION_SCOPE;
}
@@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (c) 2017 Contributors to the Eclipse Foundation
* Copyright (c) 2017, 2022 Contributors to the Eclipse Foundation
*
* See the NOTICES file(s) distributed with this work for additional
* information regarding copyright ownership.
Expand Down Expand Up @@ -29,38 +29,44 @@

import org.eclipse.microprofile.metrics.MetricRegistry;

import jakarta.inject.Qualifier;

/**
* Qualifies the type of Metric Registry to inject.
* Specifies the scope of Metric Registry to inject.
* <p>
* This can be used to obtain the respective scoped {@link MetricRegistry}:
* </p>
*
* <pre>
* <code>
* {@literal @}Inject
* {@literal @}RegistryType(type=MetricRegistry.Type.BASE)
* MetricRegistry baseRegistry;
* {@literal @}RegistryScope(scope=MetricRegistry.APPLICATION_SCOPE)
* MetricRegistry appRegistry;
*
* {@literal @}Inject
* {@literal @}RegistryScope(scope="customScope")
* MetricRegistry customRegistry;
*
* </code>
* </pre>
*
* @see org.eclipse.microprofile.metrics.MetricRegistry.Type
* see {@link MetricRegistry.APPLICATION_SCOPE}, {@link MetricRegistry.BASE_SCOPE} and
* {@link MetricRegistry.VENDOR_SCOPE}
*
* @author Raymond Lam
*
*/
@Qualifier
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
public @interface RegistryType {
public @interface RegistryScope {
/**
* The scope of the MetricRegistry.
*
* @return Returns the scope of the MetricRegistry. The {@link MetricRegistry.Type} can be {@code APPLICATION},
* {@code BASE}, or {@code VENDOR}.
* @see org.eclipse.microprofile.metrics.MetricRegistry.Type
* @return Indicates the scope of the MetricRegistry to be injected. The MicroProfile runtimes provides
* {@code application}, {@code base} and {@code vendor} scopes automatically and creates user-defined scopes
* as needed.
*
* see {@link MetricRegistry.APPLICATION_SCOPE}, {@link MetricRegistry.BASE_SCOPE} and
* {@link MetricRegistry.VENDOR_SCOPE}
*/
MetricRegistry.Type type() default MetricRegistry.Type.APPLICATION;
String scope() default MetricRegistry.APPLICATION_SCOPE;
}
Expand Up @@ -29,6 +29,7 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.eclipse.microprofile.metrics.MetricRegistry;
import org.eclipse.microprofile.metrics.MetricUnits;

import jakarta.enterprise.util.Nonbinding;
Expand Down Expand Up @@ -138,4 +139,13 @@
@Nonbinding
String unit() default MetricUnits.NANOSECONDS;

/**
* The scope that this Timer belongs to.
*
* @return The scope this Timer belongs to. By default, the value is {@link MetricRegistry.APPLICATION_SCOPE}.
*
*/
@Nonbinding
String scope() default MetricRegistry.APPLICATION_SCOPE;

}
Expand Up @@ -70,17 +70,18 @@
* </pre>
*
*
* <h2>CDI Qualifier</h2>
* <h2>RegistryScope annotation</h2>
* <p>
* The {@link org.eclipse.microprofile.metrics.annotation.RegistryType RegistryType} is used to identify which
* <code>MetricRegistry</code> (Application, Base, or Vendor) should be injected. By default, no
* <code>RegistryType</code> will inject the application <code>MetricRegistry</code>.
* The {@link org.eclipse.microprofile.metrics.annotation.RegistryScope RegistryScope} is used to identify which
* <code>MetricRegistry</code> (Application, Base, Vendor or a user-defined scope) should be injected. Injecting a
* <code>MetricRegistry</code> without a <code>RegistryScope</code> annotation gives the application-scoped
* <code>MetricRegistry</code>.
*
* <pre>
* <code>
* {@literal @}Inject
* {@literal @}RegistryType(type=MetricRegistry.Type.BASE)
* MetricRegistry baseRegistry;
* {@literal @}RegistryScope(scope=MetricRegistry.APPLICATION_SCOPE)
* MetricRegistry appRegistry;
* </code>
* </pre>
*
Expand Down
35 changes: 17 additions & 18 deletions spec/src/main/asciidoc/app-programming-model.adoc
Expand Up @@ -106,12 +106,12 @@ The following Annotations exist, see below for common fields:
|===
|Annotation | Description | Default

|@RegistryType| Qualifies the scope of Metric Registry to inject when injecting a MetricRegistry. | _application_ (scope)
|@RegistryScope| Indicates the scope of Metric Registry to inject when injecting a MetricRegistry. | _application_ (scope)
|===

==== Fields

All annotations (Except `RegistryType`) have the following fields that correspond to the metadata fields described
All annotations (Except `RegistryScope`) have the following fields that correspond to the metadata fields described
in <<architecture#meta-data-def>>.

`String name`:: Optional. Sets the name of the metric. If not explicitly given the name of the annotated object is used.
Expand All @@ -120,6 +120,7 @@ If `false`, prepends the package name and class name before the given name. Defa
`String displayName`:: Optional. A human readable display name for metadata.
`String description`:: Optional. A description of the metric.
`String unit`:: Unit of the metric. For `@Gauge` no default is provided. Check the `MetricUnits` class for a set of pre-defined units.
`String scope`:: Optional. The `MetricRegistry` scope that this metric belongs to. Default value is `application`.

NOTE: Implementors are encouraged to issue warnings in the server log if metadata is missing. Implementors
MAY stop the deployment of an application if Metadata is missing.
Expand Down Expand Up @@ -468,19 +469,19 @@ There is one shared singleton of the `MetricRegistry` per pre-defined scope (_ap
There is also one shared singleton of the `MetricRegistry` per custom scope.
When metrics are registered using annotations and no scope is provided, the metrics are registered in the _application_ `MetricRegistry` (and thus the _application_ scope).

When injected, the `@RegistryType` is used as a qualifier to selectively inject one of the `APPLICATION`, `BASE`, `VENDOR` or custom registries.
If no qualifier is used, the default `MetricRegistry` returned is the `APPLICATION` registry.
When injected, the `@RegistryScope` is used to selectively inject one of the `application`, `base`, `vendor` or custom registries.
If no _scope_ parameter is used, the default `MetricRegistry` returned is the `application` registry.

Implementations may choose to use a Factory class to produce the injectable `MetricRegistry` bean via CDI. See <<appendix#metric-registry-factory>>. Note: The factory would be an internal class and not exposed to the application.

==== @RegistryType
The `@RegistryType` can be used to retrieve the `MetricRegistry` for a specific scope.
The implementation must produce the corresponding `MetricRegistry` specified by the `RegistryType`.
==== @RegistryScope
The `@RegistryScope` can be used to retrieve the `MetricRegistry` for a specific scope.
The implementation must produce the corresponding `MetricRegistry` specified by the `RegistryScope`.

NOTE: The implementor can optionally provide a _read_only_ copy of the `MetricRegistry` for _base_ and _vendor_ scopes.

==== Application Metric Registry
The implementation must produce the _application_ `MetricRegistry` when no `RegistryType` is provided (`@Default`) or when the `RegistryType` is `APPLICATION`.
The implementation must produce the _application_ `MetricRegistry` when no `RegistryScope` is provided or when the `RegistryScope` is `application` (i.e. `MetricRegistry.APPLICATION_SCOPE`). Application-defined metrics can also be registered to <<pgm-custom-scope,user-defined scopes>>

.Example of the application injecting the application registry
[source, java]
Expand All @@ -493,45 +494,43 @@ MetricRegistry metricRegistry;
[source, java]
----
@Inject
@RegistryType(type=MetricRegistry.Type.APPLICATION)
@RegistryScope(scope=MetricRegistry.APPLICATION_SCOPE)
MetricRegistry metricRegistry;
----

==== Base Metric Registry
The implementation must produce the _base_ `MetricRegistry` when the `RegistryType` is `BASE`. The _base_ `MetricRegistry` must contain the required metrics specified in <<required-metrics#required-metrics>>.
The implementation must produce the _base_ `MetricRegistry` when the `RegistryScope` is `base` (i.e. `MetricRegistry.BASE_SCOPE`). The _base_ `MetricRegistry` must contain the required metrics specified in <<required-metrics#required-metrics>>.

.Example of the application injecting the base registry
[source, java]
----
@Inject
@RegistryType(type=MetricRegistry.Type.BASE)
@RegistryScope(scope=MetricRegistry.BASE_SCOPE)
MetricRegistry baseRegistry;
----

==== Vendor Metric Registry
The implementation must produce the _vendor_ `MetricRegistry` when the `RegistryType` is `VENDOR`. The _vendor_ `MetricRegistry` must contain any vendor specific metrics.
The implementation must produce the _vendor_ `MetricRegistry` when the `RegistryScope` is `vendor` (i.e. `MetricRegistry.VENDOR_SCOPE`). The _vendor_ `MetricRegistry` must contain any vendor specific metrics.

.Example of the application injecting the vendor registry
[source, java]
----
@Inject
@RegistryType(type=MetricRegistry.Type.VENDOR)
@RegistryScope(scope=MetricRegistry.VENDOR_SCOPE)
MetricRegistry vendorRegistry;
----

==== Custom Metric Registries
The implementation must produce the `MetricRegistry` corresponding to the custom-named registry when the `RegistryType` is a custom value. If the custom-named MetricRegistry does not yet exist the implementation must create a `MetricRegistry` with the specified name.
[[pgm-custom-scope]]
The implementation must produce the `MetricRegistry` corresponding to the custom-named registry when the `RegistryType` is a custom value. If the custom-named `MetricRegistry` does not yet exist the implementation must create a `MetricRegistry` with the specified name.

.Example of the application injecting a custom-named registry
[source, java]
----
@Inject
@RegistryType(type="motorguide")
@RegistryScope(scope="motorguide")
MetricRegistry motorGuideRegistry;
----



[[pgm-metadata]]
==== Metadata

Expand Down

0 comments on commit 2a882f5

Please sign in to comment.