1 /* 2 * Copyright 2016-17, OpenCensus Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.opencensus.stats; 18 19 import io.opencensus.internal.DefaultVisibilityForTesting; 20 import io.opencensus.internal.Provider; 21 import java.util.logging.Level; 22 import java.util.logging.Logger; 23 import javax.annotation.Nullable; 24 25 /** 26 * Class for accessing the default {@link StatsComponent}. 27 * 28 * @since 0.8 29 */ 30 public final class Stats { 31 private static final Logger logger = Logger.getLogger(Stats.class.getName()); 32 33 private static final StatsComponent statsComponent = 34 loadStatsComponent(StatsComponent.class.getClassLoader()); 35 36 /** 37 * Returns the default {@link StatsRecorder}. 38 * 39 * @since 0.8 40 */ 41 public static StatsRecorder getStatsRecorder() { 42 return statsComponent.getStatsRecorder(); 43 } 44 45 /** 46 * Returns the default {@link ViewManager}. 47 * 48 * @since 0.8 49 */ 50 public static ViewManager getViewManager() { 51 return statsComponent.getViewManager(); 52 } 53 54 /** 55 * Returns the current {@code StatsCollectionState}. 56 * 57 * <p>When no implementation is available, {@code getState} always returns {@link 58 * StatsCollectionState#DISABLED}. 59 * 60 * <p>Once {@link #getState()} is called, subsequent calls to {@link 61 * #setState(StatsCollectionState)} will throw an {@code IllegalStateException}. 62 * 63 * @return the current {@code StatsCollectionState}. 64 * @since 0.8 65 */ 66 public static StatsCollectionState getState() { 67 return statsComponent.getState(); 68 } 69 70 /** 71 * Sets the current {@code StatsCollectionState}. 72 * 73 * <p>When no implementation is available, {@code setState} does not change the state. 74 * 75 * <p>If state is set to {@link StatsCollectionState#DISABLED}, all stats that are previously 76 * recorded will be cleared. 77 * 78 * @param state the new {@code StatsCollectionState}. 79 * @throws IllegalStateException if {@link #getState()} was previously called. 80 * @deprecated This method is deprecated because other libraries could cache the result of {@link 81 * #getState()}, use a stale value, and behave incorrectly. It is only safe to call early in 82 * initialization. This method throws {@link IllegalStateException} after {@code getState()} 83 * has been called, in order to limit changes to the result of {@code getState()}. 84 * @since 0.8 85 */ 86 @Deprecated 87 public static void setState(StatsCollectionState state) { 88 statsComponent.setState(state); 89 } 90 91 // Any provider that may be used for StatsComponent can be added here. 92 @DefaultVisibilityForTesting 93 static StatsComponent loadStatsComponent(@Nullable ClassLoader classLoader) { 94 try { 95 // Call Class.forName with literal string name of the class to help shading tools. 96 return Provider.createInstance( 97 Class.forName( 98 "io.opencensus.impl.stats.StatsComponentImpl", /*initialize=*/ true, classLoader), 99 StatsComponent.class); 100 } catch (ClassNotFoundException e) { 101 logger.log( 102 Level.FINE, 103 "Couldn't load full implementation for StatsComponent, now trying to load lite " 104 + "implementation.", 105 e); 106 } 107 try { 108 // Call Class.forName with literal string name of the class to help shading tools. 109 return Provider.createInstance( 110 Class.forName( 111 "io.opencensus.impllite.stats.StatsComponentImplLite", 112 /*initialize=*/ true, 113 classLoader), 114 StatsComponent.class); 115 } catch (ClassNotFoundException e) { 116 logger.log( 117 Level.FINE, 118 "Couldn't load lite implementation for StatsComponent, now using " 119 + "default implementation for StatsComponent.", 120 e); 121 } 122 return NoopStats.newNoopStatsComponent(); 123 } 124 125 private Stats() {} 126 } 127