001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package org.apache.hadoop.metrics2.lib;
020
021 import java.util.concurrent.atomic.AtomicReference;
022 import javax.management.ObjectName;
023
024 import org.apache.hadoop.classification.InterfaceAudience;
025 import org.apache.hadoop.classification.InterfaceStability;
026 import org.apache.hadoop.metrics2.MetricsException;
027 import org.apache.hadoop.metrics2.MetricsSystem;
028 import org.apache.hadoop.metrics2.impl.MetricsSystemImpl;
029
030 /**
031 * The default metrics system singleton
032 */
033 @InterfaceAudience.Public
034 @InterfaceStability.Evolving
035 public enum DefaultMetricsSystem {
036 INSTANCE; // the singleton
037
038 private AtomicReference<MetricsSystem> impl =
039 new AtomicReference<MetricsSystem>(new MetricsSystemImpl());
040 volatile boolean miniClusterMode = false;
041 transient final UniqueNames mBeanNames = new UniqueNames();
042 transient final UniqueNames sourceNames = new UniqueNames();
043
044 /**
045 * Convenience method to initialize the metrics system
046 * @param prefix for the metrics system configuration
047 * @return the metrics system instance
048 */
049 public static MetricsSystem initialize(String prefix) {
050 return INSTANCE.init(prefix);
051 }
052
053 MetricsSystem init(String prefix) {
054 return impl.get().init(prefix);
055 }
056
057 /**
058 * @return the metrics system object
059 */
060 public static MetricsSystem instance() {
061 return INSTANCE.getImpl();
062 }
063
064 /**
065 * Shutdown the metrics system
066 */
067 public static void shutdown() {
068 INSTANCE.shutdownInstance();
069 }
070
071 void shutdownInstance() {
072 boolean last = impl.get().shutdown();
073 if (last) synchronized(this) {
074 mBeanNames.map.clear();
075 sourceNames.map.clear();
076 }
077 }
078
079 @InterfaceAudience.Private
080 public static MetricsSystem setInstance(MetricsSystem ms) {
081 return INSTANCE.setImpl(ms);
082 }
083
084 MetricsSystem setImpl(MetricsSystem ms) {
085 return impl.getAndSet(ms);
086 }
087
088 MetricsSystem getImpl() { return impl.get(); }
089
090 @InterfaceAudience.Private
091 public static void setMiniClusterMode(boolean choice) {
092 INSTANCE.miniClusterMode = choice;
093 }
094
095 @InterfaceAudience.Private
096 public static boolean inMiniClusterMode() {
097 return INSTANCE.miniClusterMode;
098 }
099
100 @InterfaceAudience.Private
101 public static ObjectName newMBeanName(String name) {
102 return INSTANCE.newObjectName(name);
103 }
104
105 @InterfaceAudience.Private
106 public static void removeMBeanName(ObjectName name) {
107 INSTANCE.removeObjectName(name.toString());
108 }
109
110 @InterfaceAudience.Private
111 public static String sourceName(String name, boolean dupOK) {
112 return INSTANCE.newSourceName(name, dupOK);
113 }
114
115 synchronized ObjectName newObjectName(String name) {
116 try {
117 if (mBeanNames.map.containsKey(name) && !miniClusterMode) {
118 throw new MetricsException(name +" already exists!");
119 }
120 return new ObjectName(mBeanNames.uniqueName(name));
121 } catch (Exception e) {
122 throw new MetricsException(e);
123 }
124 }
125
126 synchronized void removeObjectName(String name) {
127 mBeanNames.map.remove(name);
128 }
129
130 synchronized String newSourceName(String name, boolean dupOK) {
131 if (sourceNames.map.containsKey(name)) {
132 if (dupOK) {
133 return name;
134 } else if (!miniClusterMode) {
135 throw new MetricsException("Metrics source "+ name +" already exists!");
136 }
137 }
138 return sourceNames.uniqueName(name);
139 }
140 }