{"id":18854768,"url":"https://github.com/astefanutti/metrics-cdi","last_synced_at":"2025-04-14T10:42:16.256Z","repository":{"id":11303247,"uuid":"13719326","full_name":"astefanutti/metrics-cdi","owner":"astefanutti","description":"CDI extension for Dropwizard Metrics","archived":false,"fork":false,"pushed_at":"2022-01-04T16:31:59.000Z","size":783,"stargazers_count":77,"open_issues_count":4,"forks_count":19,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-27T23:51:10.349Z","etag":null,"topics":["cdi","dropwizard","java","javaee","metrics"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"allegro/bigcache","license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/astefanutti.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-10-20T13:15:52.000Z","updated_at":"2024-03-31T14:14:10.000Z","dependencies_parsed_at":"2022-09-07T19:40:20.411Z","dependency_job_id":null,"html_url":"https://github.com/astefanutti/metrics-cdi","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astefanutti%2Fmetrics-cdi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astefanutti%2Fmetrics-cdi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astefanutti%2Fmetrics-cdi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astefanutti%2Fmetrics-cdi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/astefanutti","download_url":"https://codeload.github.com/astefanutti/metrics-cdi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248867351,"owners_count":21174717,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cdi","dropwizard","java","javaee","metrics"],"created_at":"2024-11-08T03:51:14.986Z","updated_at":"2025-04-14T10:42:16.236Z","avatar_url":"https://github.com/astefanutti.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CDI Extension for Metrics\n\n[![Build Status][Travis badge]][Travis build] [![Coverage Status][Coveralls badge]][Coveralls build] [![Maven Central][Maven Central badge]][Maven Central build]\n\n[Travis badge]: https://travis-ci.org/astefanutti/metrics-cdi.svg\n[Travis build]: https://travis-ci.org/astefanutti/metrics-cdi\n[Coveralls badge]: https://coveralls.io/repos/astefanutti/metrics-cdi/badge.svg\n[Coveralls build]: https://coveralls.io/github/astefanutti/metrics-cdi\n[Maven Central badge]: https://img.shields.io/maven-central/v/io.astefanutti.metrics.cdi/metrics-cdi.svg\n[Maven Central build]: https://repo1.maven.org/maven2/io/astefanutti/metrics/cdi/metrics-cdi/1.6.0/\n\n[CDI][] portable extension for Dropwizard [Metrics][] compliant with [JSR 346: Contexts and Dependency Injection for Java\u003csup\u003eTM\u003c/sup\u003e EE 1.2][JSR 346 1.2].\n\n[CDI]: http://www.cdi-spec.org/\n[Metrics]: https://metrics.dropwizard.io/\n[JSR 346]: https://jcp.org/en/jsr/detail?id=346\n[JSR 346 1.1]: https://jcp.org/aboutJava/communityprocess/final/jsr346/index.html\n[JSR 346 1.2]: https://jcp.org/aboutJava/communityprocess/mrel/jsr346/index.html\n[JSR 365]: https://jcp.org/en/jsr/detail?id=365\n[CDI 1.2]: https://docs.jboss.org/cdi/spec/1.2/cdi-spec.html\n\n## About\n\n_Metrics CDI_ provides support for the [_Metrics_ annotations][Metrics annotations] in CDI enabled environments. It implements the contract specified by these annotations with the following level of functionality:\n+ Intercepts invocations of bean constructors, methods and public methods of bean classes annotated with [`@Counted`][], [`@ExceptionMetered`][], [`@Metered`][] and [`@Timed`][],\n+ Creates [`Gauge`][] and [`CachedGauge`][] instances for bean methods annotated with [`@Gauge`][] and [`@CachedGauge`][] respectively,\n+ Injects [`Counter`][], [`Gauge`][], [`Histogram`][], [`Meter`][] and [`Timer`][] instances,\n+ Registers or retrieves the produced [`Metric`][] instances in the resolved [`MetricRegistry`][] bean,\n+ Declares automatically a default [`MetricRegistry`][] bean if no one exists in the CDI container,\n+ Registers [`HealthCheck`][] beans with a provided or automatically configured [`HealthCheckRegistry`][] bean instance.\n\n_Metrics CDI_ is compatible with _Metrics_ version `3.1.0`+.\n\n[Metrics annotations]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/annotation/package-summary.html\n[`@CachedGauge`]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/annotation/CachedGauge.html\n[`@Counted`]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/annotation/Counted.html\n[`@ExceptionMetered`]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/annotation/ExceptionMetered.html\n[`@Gauge`]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/annotation/Gauge.html\n[`@Metered`]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/annotation/Gauge.html\n[`@Timed`]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/annotation/Timed.html\n[`CachedGauge`]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/CachedGauge.html\n[`Counter`]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/Counter.html\n[`Gauge`]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/Gauge.html\n[`Histogram`]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/Histogram.html\n[`Meter`]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/Meter.html\n[`Metric`]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/Metric.html\n[`Timer`]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/Timer.html\n[`MetricRegistry`]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/MetricRegistry.html\n[`HealthCheck`]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/health/HealthCheck.html\n[`HealthCheckRegistry`]: https://metrics.dropwizard.io/4.0.0/apidocs/com/codahale/metrics/health/HealthCheckRegistry.html\n\n## Getting Started\n\n#### Using Maven\n\nAdd the `metrics-cdi` library as a dependency:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.astefanutti.metrics.cdi\u003c/groupId\u003e\n    \u003cartifactId\u003emetrics-cdi\u003c/artifactId\u003e\n    \u003cversion\u003e1.6.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n#### Required Dependencies\n\nBesides depending on _Metrics_ (`metrics-core` and `metrics-annotation` modules), _Metrics CDI_ requires a CDI enabled environment running in Java 8 or greater.\n\n#### Supported Containers\n\n_Metrics CDI_ is currently successfully tested with the following containers:\n\n| Container             | Version        | Environment                        |\n| --------------------- | -------------- | ---------------------------------- |\n| [Weld][]              | `2.4.3.Final`  | Java SE 8 / [CDI 1.2][JSR 346 1.2] |\n| [Weld][]              | `3.0.3.Final`  | Java SE 8 / [CDI 2.0][JSR 365]     |\n| [OpenWebBeans][]      | `1.7.3`        | Java SE 8 / [CDI 1.2][JSR 346 1.2] |\n| [Jetty][]             | `9.4.5`        | [Servlet 3.1][]                    |\n| [WildFly 10][WildFly] | `10.1.0.Final` | [Java EE 7][]                      |\n\n[Weld]: https://weld.cdi-spec.org/\n[OpenWebBeans]: https://openwebbeans.apache.org/\n[Jetty]: https://www.eclipse.org/jetty/\n[WildFly]: http://www.wildfly.org/\n[Servlet 3.1]: https://jcp.org/en/jsr/detail?id=340\n[Java EE 7]: https://jcp.org/en/jsr/detail?id=342\n\n## Usage\n\n_Metrics CDI_ activates the [_Metrics_ AOP Instrumentation](#metrics-aop-instrumentation) for beans annotated with [_Metrics_ annotations][Metrics annotations] and automatically registers the corresponding `Metric` instances in the [_Metrics_ registry][] resolved for the CDI application. The registration of these `Metric` instances happens each time such a bean gets instantiated. Besides, `Metric` instances can be retrieved from the _Metrics_ registry by declaring [metrics injection points](#metrics-injection).\n\nThe [metrics registration](#metrics-registration) mechanism can be used to customize the `Metric` instances that get registered. Besides, the [_Metrics_ registry resolution](#metrics-registry-resolution) mechanism can be used for the application to provide a custom [`MetricRegistry`] instance.\n\n[Health checks](#health-checks) support is automatically activated when the `metrics-healthchecks` optional dependency is present in the classpath.\n\n[_Metrics_ registry]: https://metrics.dropwizard.io/4.0.0/getting-started.html#the-registry\n\n#### Metrics AOP Instrumentation\n\n_Metrics_ comes with the [`metrics-annotation`][] module that contains a set of annotations and provides a standard way to integrate _Metrics_ with frameworks supporting Aspect Oriented Programming (AOP). These annotations are supported by _Metrics CDI_ that implements their contract as documented in their Javadoc.\n\n[`metrics-annotation`]: https://github.com/dropwizard/metrics/tree/4.0.0-docs/metrics-annotation\n\nFor example, a method of a bean can be annotated so that its execution can be monitored using _Metrics_:\n\n```java\nimport com.codahale.metrics.annotation.Timed;\n\nclass TimedMethodBean {\n\n    @Timed\n    void timedMethod() {\n        // Timer name =\u003e TimedMethodBean.timedMethod\n    }\n}\n```\n\nor the [bean class][] can be annotated directly so that all its public methods get monitored:\n\n```java\nimport com.codahale.metrics.annotation.Metered;\n\n@Metered\npublic class MeteredClassBean {\n\n    public void meteredMethod() {\n        // Meter name =\u003e MeteredClassBean.meteredMethod\n    }\n}\n```\n\nor the [bean constructor][] can be annotated so that its instantiations get monitored:\n\n```java\nimport com.codahale.metrics.annotation.Counted;\n\nclass CountedConstructorBean {\n\n    @Counted\n    CountedConstructorBean() {\n        // Counter name =\u003e CountedConstructorBean.CountedConstructorBean\n    }\n}\n```\n\nThe `name` and `absolute` attributes available on every _Metrics_ annotation can be used to customize the name of the `Metric` instance that gets registered in the _Metrics_ registry. The default naming convention being the annotated member simple name relative to the declaring class fully qualified name as illustrated in the above examples.\n\n[bean class]: https://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#what_classes_are_beans\n[bean constructor]: https://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#bean_constructors\n\n#### Metrics Injection\n\n`Metric` instances can be retrieved from the _Metrics_ registry by declaring an [injected field][], e.g.:\n\n```java\nimport com.codahale.metrics.Timer;\n\nimport javax.inject.Inject;\n\nclass TimerBean {\n\n    @Inject\n    private Timer timer; // Timer name =\u003e TimerBean.Timer\n}\n```\n\n`Metric` instances can be injected similarly as parameters of any [initializer method][] or [bean constructor][], e.g.:\n\n```java\nimport com.codahale.metrics.Timer;\n\nimport javax.inject.Inject;\n\nclass TimerBean {\n\n    private final Timer timer;\n\n    @Inject\n    private TimerBean(Timer timer) { // Timer name =\u003e TimerBean.Timer\n       this.timer = timer;\n    }\n}\n```\n\nIn the above example, the `-parameters` compiler option is required to get access to injected parameter name. Indeed, access to parameter names at runtime has been introduced with [JEP-118][]. More information can be found in [Obtaining Names of Method Parameters][] from the Java tutorials. To work around that limitation, or to declare a specific name, the `@Metric` annotation can be used as documented hereafter.\n\n[JEP-118]: http://openjdk.java.net/jeps/118\n[Obtaining Names of Method Parameters]: https://docs.oracle.com/javase/tutorial/reflect/member/methodparameterreflection.html\n\nIn order to provide metadata for the `Metric` instantiation and resolution, the injection point can be annotated with the `@Metric` annotation, e.g., with an [injected field][]:\n\n```java\nimport com.codahale.metrics.Timer;\nimport com.codahale.metrics.annotation.Metric;\n\nimport javax.inject.Inject;\n\n@Inject\n@Metric(name = \"timerName\", absolute = true)\nprivate Timer timer; // Timer name =\u003e timerName\n```\n\nor when using a [bean constructor][]:\n\n```java\nimport com.codahale.metrics.Timer;\nimport com.codahale.metrics.annotation.Metric;\n\nimport javax.inject.Inject;\n\nclass TimerBean {\n\n    private final Timer timer;\n\n    @Inject\n    private TimerBean(@Metric(name = \"timerName\", absolute = true) Timer timer) {\n        // Timer name =\u003e timerName\n        this.timer = timer;\n    }\n}\n```\n\n[injected field]: https://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#injected_fields\n[initializer method]: https://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#initializer_methods\n\n#### Metrics Registration\n\nWhile _Metrics CDI_ automatically registers `Metric` instances during the [_Metrics_ AOP instrumentation](#metrics-aop-instrumentation), it may be necessary for an application to explicitly provide the `Metric` instances to register. For example, to provide particular `Reservoir` implementations to [histograms][] or [timers][], e.g. with a [producer field][]:\n\n```java\nimport com.codahale.metrics.SlidingTimeWindowReservoir;\nimport com.codahale.metrics.Timer;\nimport com.codahale.metrics.annotation.Metric;\nimport com.codahale.metrics.annotation.Timed;\n\nimport javax.enterprise.inject.Produces;\n\nclass TimedMethodBean {\n\n    @Produces\n    @Metric(name = \"customTimer\") // Timer name =\u003e TimedMethodBean.customTimer\n    Timer Timer = new Timer(new SlidingTimeWindowReservoir(1L, TimeUnit.MINUTES));\n\n    @Timed(name = \"customTimer\")\n    void timedMethod() {\n        // Timer name =\u003e TimedMethodBean.customTimer\n    }\n}\n```\n\nAnother use case is to register custom [gauges], e.g. with a [producer method][]:\n\n```java\nclass CacheHitRatioBean {\n\n    @Inject\n    private Meter hits;\n\n    @Timed(name = \"calls\")\n    public void cachedMethod() {\n        if (hit) hits.mark();\n    }\n\n    @Produces\n    @Metric(name = \"cache-hits\")\n    private Gauge\u003cDouble\u003e cacheHitRatioGauge(Meter hits, Timer calls) {\n        return () -\u003e Ratio.of(hits.getCount(), calls.getCount()).getValue();\n    }\n}\n```\n\n[gauges]: https://metrics.dropwizard.io/4.0.0/manual/core.html#gauges\n[histograms]: https://metrics.dropwizard.io/4.0.0/manual/core.html#histograms\n[timers]: https://metrics.dropwizard.io/4.0.0/manual/core.html#timers\n[producer field]: https://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#producer_field\n[producer method]: https://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#producer_method\n\n#### Metrics Registry Resolution\n\n_Metrics CDI_ automatically registers a `MetricRegistry` bean into the CDI container to register any `Metric` instances produced. That _default_ `MetricRegistry` bean can be injected using standard CDI [typesafe resolution][], for example, by declaring an [injected field][]:\n\n```java\nimport com.codahale.metrics.MetricRegistry;\n\nimport javax.inject.Inject;\n\n@Inject\nprivate MetricRegistry registry;\n```\n\nor by declaring a [bean constructor][]:\n\n```java\nimport com.codahale.metrics.MetricRegistry;\n\nimport javax.inject.Inject;\n\nclass MetricRegistryBean {\n\n    private final MetricRegistry registry;\n\n    @Inject\n    private MetricRegistryBean(MetricRegistry registry) {\n        this.registry = registry;\n    }\n}\n```\n\nOtherwise, _Metrics CDI_ uses any `MetricRegistry` bean declared in the CDI container with the [built-in _default_ qualifier][] `@Default` so that a _custom_ `MetricRegistry` can be provided. For example, that _custom_ `MetricRegistry` can be declared with a [producer field][]:\n\n```java\nimport com.codahale.metrics.MetricRegistry;\n\nimport javax.enterprise.context.ApplicationScoped;\nimport javax.enterprise.inject.Produces;\n\n@Produces\n@ApplicationScoped\nprivate final MetricRegistry registry = new MetricRegistry();\n```\n\nor with a [producer method][]:\n\n```java\nimport com.codahale.metrics.MetricRegistry;\n\nimport javax.enterprise.context.ApplicationScoped;\nimport javax.enterprise.inject.Produces;\n\nclass MetricRegistryFactoryBean {\n\n    @Produces\n    @ApplicationScoped\n    private MetricRegistry metricRegistry() {\n        return new MetricRegistry();\n    }\n}\n```\n\n[typesafe resolution]: https://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#typesafe_resolution\n[built-in _default_ qualifier]: https://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#builtin_qualifiers\n\n#### Health Checks\n\n_Metrics CDI_ automatically registers a `HealthCheckRegistry` bean into the CDI container. This follows the same resolution mechanism as that of the [_Metrics_ registry](#metrics-registry-resolution), so that the application may provide a custom `HealthCheckRegistry` instance.\n\n_Metrics CDI_ then automatically registers any `HealthCheck` instance with the configured `HealthCheckRegistry` instance.\nA `HealthCheck` bean can be declared as any CDI bean, e.g. with a [bean class][]:\n\n```java\nimport com.codahale.metrics.health.HealthCheck;\n\nimport javax.inject.Inject;\nimport javax.inject.Named;\n\n@Named(\"databaseHealthCheck\")\nclass DatabaseHealthCheck extends HealthCheck {\n\n    @Inject\n    private Database database;\n\n    @Override\n    protected Result check() {\n        return database.ping()\n            ? Result.healthy()\n            : Result.unhealthy(\"Can't ping database!\");\n    }\n}\n```\n\n#### Metrics CDI Configuration\n\n_Metrics CDI_ fires a `MetricsConfiguration` event at deployment time that can be used by the application to configure it, e.g.:\n\n```java\nimport io.astefanutti.metrics.cdi.MetricsConfiguration;\n\nimport javax.enterprise.event.Observes;\n\nclass MetricsCdiConfiguration {\n\n    static void configure(@Observes MetricsConfiguration metrics) {\n        // Use absolute name globally\n        metrics.useAbsoluteName(true);\n        // Use a uniform reservoir globally\n        metrics.reservoirFunction((name, type) -\u003e Optional.of(new UniformReservoir());\n    }\n}\n```\n\nNote that this event can only be used within the context of the observer method invocation. Any attempt to call one of its methods outside of that context will result in an `IllegalStateException` to be thrown.\n\n## Limitations\n\n[CDI 1.2][] leverages on [Java Interceptors Specification 1.2][] to provide the ability to [associate interceptors to beans][Binding an interceptor to a bean] via _typesafe_ interceptor bindings. Interceptors are a mean to separate cross-cutting concerns from the business logic and _Metrics CDI_ is relying on interceptors to implement the support of _Metrics_ annotations in a CDI enabled environment.\n\n[CDI 1.2][] sets additional restrictions about the type of bean to which an interceptor can be bound. From a _Metrics CDI_ end-user perspective, that implies that the managed beans to be monitored with _Metrics_ (i.e. having at least one member method annotated with one of the _Metrics_ annotations) must be _proxyable_ bean types, as defined in [Unproxyable bean types][], that are:\n\u003e + Classes which don’t have a non-private constructor with no parameters,\n\u003e + Classes which are declared `final`,\n\u003e + Classes which have non-static, final methods with public, protected or default visibility,\n\u003e + Primitive types,\n\u003e + And array types.\n\n[Java Interceptors Specification 1.2]: https://download.oracle.com/otndocs/jcp/interceptors-1_2-mrel2-eval-spec/\n[Binding an interceptor to a bean]: https://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#binding_interceptor_to_bean\n[Unproxyable bean types]: https://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#unproxyable\n\n## License\n\nCopyright © 2013, Antonin Stefanutti\n\nPublished under Apache Software License 2.0, see LICENSE\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fastefanutti%2Fmetrics-cdi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fastefanutti%2Fmetrics-cdi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fastefanutti%2Fmetrics-cdi/lists"}