blob: d5c2d83e598123e5e91c25900f172a1015777c47 [file] [log] [blame]
/*
* 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;
import java.io.IOException;
/**
* Used by objects that expose metrics through {@link SolrMetricManager}.
*/
public interface SolrMetricProducer extends AutoCloseable {
/**
* Unique metric tag identifies components with the same life-cycle, which should
* be registered / unregistered together. It is in the format of A:B:C, where
* A is the parent of B is the parent of C and so on.
* If object "B" is unregistered C also must get unregistered.
* If object "A" is unregistered B and C also must get unregistered.
* @param o object to create a tag for
* @param parentName parent object name, or null if no parent exists
*/
static String getUniqueMetricTag(Object o, String parentName) {
String name = o.getClass().getSimpleName() + "@" + Integer.toHexString(o.hashCode());
if (parentName != null && parentName.contains(name)) {
throw new RuntimeException("Parent already includes this component! parent=" + parentName + ", this=" + name);
}
return parentName == null ?
name :
parentName + ":" + name;
}
/**
* Initializes metrics specific to this producer
*
* @param manager an instance of {@link SolrMetricManager}
* @param registry registry name where metrics are registered
* @param tag a symbolic tag that represents this instance of the producer,
* or a group of related instances that have the same life-cycle. This tag is
* used when managing life-cycle of some metrics.
* @param scope scope of the metrics (eg. handler name) to separate metrics of components with
* the same implementation but different scope.
* @deprecated use {@link #initializeMetrics(SolrMetricsContext, String)} instead
*/
@Deprecated
default void initializeMetrics(SolrMetricManager manager, String registry, String tag, String scope) {
initializeMetrics(new SolrMetricsContext(manager, registry, tag), scope);
}
/**
* Initialize metrics specific to this producer.
* @param parentContext parent metrics context. If this component has the same life-cycle as the parent
* it can simply use the parent context, otherwise it should obtain a child context
* using {@link SolrMetricsContext#getChildContext(Object)} passing <code>this</code>
* as the child.
* @param scope component scope
*/
default void initializeMetrics(SolrMetricsContext parentContext, String scope) {
throw new RuntimeException("In class " + getClass().getName() +
" you must implement either initializeMetrics(SolrMetricsContext, String) or " +
"initializeMetrics(SolrMetricManager, String, String, String)");
}
/**
* Implementing classes should override this method to provide the context obtained in
* {@link #initializeMetrics(SolrMetricsContext, String)} to ensure proper cleanup of metrics
* at the end of the life-cycle of this component.
*/
default SolrMetricsContext getSolrMetricsContext() {
return null;
}
/**
* Implementations should always call <code>SolrMetricProducer.super.close()</code> to ensure that
* metrics with the same life-cycle as this component are properly unregistered. This prevents
* obscure memory leaks.
*
* from: https://docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html
* While this interface method is declared to throw Exception, implementers are strongly encouraged
* to declare concrete implementations of the close method to throw more specific exceptions, or to
* throw no exception at all if the close operation cannot fail.
*/
@Override
default void close() throws IOException {
SolrMetricsContext context = getSolrMetricsContext();
if (context == null) {
return;
} else {
context.unregister();
}
// ??? (ab) no idea what this was supposed to avoid
//if (info == null || info.tag.indexOf(':') == -1) return;//this will end up unregistering the root itself
}
}