001/**
002 * Copyright 2015 DuraSpace, Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.fcrepo.metrics;
017
018import static java.lang.Integer.parseInt;
019import static java.lang.System.getProperty;
020
021import java.net.InetSocketAddress;
022
023import org.springframework.context.annotation.Bean;
024import org.springframework.context.annotation.Configuration;
025import org.springframework.context.annotation.Profile;
026
027import com.codahale.metrics.JmxReporter;
028import com.codahale.metrics.graphite.Graphite;
029import com.codahale.metrics.graphite.GraphiteReporter;
030
031/**
032 * Configuration class for Metrics reporting to Graphite and JMX.
033 * <p>
034 * To enable Metrics reporting to Graphite, activate the Spring profile
035 * "metrics.graphite". The system properties fcrepo.metrics.host and
036 * fcrepo.metrics.port can also be set (defaults to "localhost" and 2003,
037 * respectively.
038 * </p>
039 * <p>
040 * To enable Metrics reporting to JMX, activate the Spring profile
041 * "metrics.jmx".
042 * </p>
043 * <p>
044 * To enable both Graphite and JMX reporting, the Spring profile "metrics", can
045 * be used instead of specifying both metrics.graphite and metrics.jmx, e.g.:
046 * </p>
047 * <blockquote><code>-Dspring.profiles.active="metrics"</code></blockquote>
048 * 
049 * @author Edwin Shin
050 */
051@Configuration
052public class MetricsConfig {
053
054    public static final String METRIC_PREFIX = getProperty("fcrepo.metrics.prefix", "org.fcrepo");
055
056    /**
057     * Provide the reporter factory to Spring
058     * 
059     * @return the reporter factory
060     */
061    @Bean
062    public ReporterFactory reporterFactory() {
063        return new ReporterFactory();
064    }
065
066    /**
067     * <p>
068     * Metrics configuration for Graphite reporting.
069     * </p>
070     * <p>
071     * Graphite reporting can be enabled by activating the "metrics.graphite"
072     * Spring profile.
073     * </p>
074     */
075    @Configuration
076    @Profile({"metrics", "metrics.graphite"})
077    public static class GraphiteConfig {
078
079        /**
080         * <p>
081         * Host and port may be configured with system properties
082         * "fcrepo.metrics.host" and "fcrepo.metrics.port", respectively.
083         * </p>
084         * <p>
085         * Host and port default to "localhost" and "2003", respectively.
086         * </p>
087         * 
088         * @return a Graphite client to a Carbon server
089         */
090        @Bean
091        public Graphite graphiteClient() {
092            final String hostname =
093                    getProperty("fcrepo.metrics.host", "localhost");
094            final int port =
095                    parseInt(getProperty("fcrepo.metrics.port", "2003"));
096
097            return new Graphite(new InetSocketAddress(hostname, port));
098        }
099
100        /**
101         * @return a Reporter which publishes metrics to a Graphite server
102         */
103        @Bean
104        public GraphiteReporter graphiteReporter() {
105            final MetricsConfig cfg = new MetricsConfig();
106            final String prefix = METRIC_PREFIX;
107            return cfg.reporterFactory().getGraphiteReporter(prefix,
108                    graphiteClient());
109        }
110    }
111
112    /**
113     * <p>
114     * JMX configuration for metrics reporting.
115     * </p>
116     * <p>
117     * JMX reporting can be enabled by activating the "metrics.jmx" Spring
118     * profile.
119     * </p>
120     */
121    @Configuration
122    @Profile({"metrics", "metrics.jmx"})
123    public static class JmxConfig {
124
125        /**
126         * @return a Reporter that exposes metrics under the "org.fcrepo" prefix
127         */
128        @Bean
129        public JmxReporter jmxReporter() {
130            final MetricsConfig cfg = new MetricsConfig();
131            final String prefix = METRIC_PREFIX;
132            return cfg.reporterFactory().getJmxReporter(prefix);
133        }
134    }
135}