All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.solr.metrics.reporters.SolrSlf4jReporter Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.solr.metrics.reporters;

import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.Map;
import java.util.SortedMap;
import java.util.concurrent.TimeUnit;

import com.codahale.metrics.Counter;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricFilter;
import com.codahale.metrics.ScheduledReporter;
import com.codahale.metrics.Slf4jReporter;
import com.codahale.metrics.Timer;
import org.apache.solr.metrics.FilteringSolrMetricReporter;
import org.apache.solr.metrics.SolrMetricManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

/**
 * Metrics reporter that wraps {@link com.codahale.metrics.Slf4jReporter}.
 * The following init arguments are supported:
 * 
    *
  • period: (optional, int) number of seconds between reports, default is 60,
  • *
  • prefix: (optional, str) prefix for metric names, in addition to * registry name. Default is none, ie. just registry name.
  • *
  • filter: (optional, str) if not empty only metric names that start * with this value will be reported, default is all metrics from a registry,
  • *
  • logger: (optional, str) logger name to use. Default is the * metrics group, eg. solr.jvm, solr.core, etc
  • *
*/ public class SolrSlf4jReporter extends FilteringSolrMetricReporter { @SuppressWarnings("unused") // we need this to pass validate-source-patterns private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private String instancePrefix = null; private String logger = null; private Map mdcContext; private Slf4jReporterWrapper reporter; private boolean active; // this wrapper allows us to set MDC context - unfortunately it's not possible to // simply override {@link Slf4jReporter#report()} because its constructor is private private class Slf4jReporterWrapper extends ScheduledReporter { final Slf4jReporter delegate; final Map mdcContext; Slf4jReporterWrapper(String logger, Map mdcContext, Slf4jReporter delegate, TimeUnit rateUnit, TimeUnit durationUnit) { super(null, logger, null, rateUnit, durationUnit); this.delegate = delegate; this.mdcContext = mdcContext; } @Override public void report() { // set up MDC MDC.setContextMap(mdcContext); try { delegate.report(); } finally { // clear MDC MDC.clear(); } } @Override public void report(SortedMap gauges, SortedMap counters, SortedMap histograms, SortedMap meters, SortedMap timers) { throw new UnsupportedOperationException("this method should never be called here!"); } @Override public void close() { super.close(); delegate.close(); } } /** * Create a SLF4J reporter for metrics managed in a named registry. * * @param metricManager metric manager instance that manages the selected registry * @param registryName registry to use, one of registries managed by * {@link SolrMetricManager} */ public SolrSlf4jReporter(SolrMetricManager metricManager, String registryName) { super(metricManager, registryName); } public void setPrefix(String prefix) { this.instancePrefix = prefix; } public void setLogger(String logger) { this.logger = logger; } @Override protected void doInit() { mdcContext = MDC.getCopyOfContextMap(); mdcContext.put("registry", "m:" + registryName); Slf4jReporter.Builder builder = Slf4jReporter .forRegistry(metricManager.registry(registryName)) .convertRatesTo(TimeUnit.SECONDS) .convertDurationsTo(TimeUnit.MILLISECONDS); final MetricFilter filter = newMetricFilter(); builder = builder.filter(filter); if (instancePrefix != null) { builder = builder.prefixedWith(instancePrefix); } if (logger == null || logger.isEmpty()) { // construct logger name from Group if (pluginInfo.attributes.containsKey("group")) { logger = SolrMetricManager.enforcePrefix(pluginInfo.attributes.get("group")); } else if (pluginInfo.attributes.containsKey("registry")) { String reg = SolrMetricManager.enforcePrefix(pluginInfo.attributes.get("registry")); String[] names = reg.split("\\."); if (names.length < 2) { logger = reg; } else { logger = names[0] + "." + names[1]; } } } builder = builder.outputTo(LoggerFactory.getLogger(logger)); // build BUT don't start - scheduled execution is handled by the wrapper Slf4jReporter delegate = builder.build(); reporter = new Slf4jReporterWrapper(logger, mdcContext, delegate, TimeUnit.SECONDS, TimeUnit.MILLISECONDS); reporter.start(period, TimeUnit.SECONDS); active = true; } @Override protected void validate() throws IllegalStateException { if (period < 1) { throw new IllegalStateException("Init argument 'period' is in time unit 'seconds' and must be at least 1."); } } @Override public void close() throws IOException { if (reporter != null) { reporter.close(); } active = false; } // for unit tests boolean isActive() { return active; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy