1 /* 2 * Copyright 2017, 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.trace.export; 18 19 import com.google.auto.value.AutoValue; 20 import io.opencensus.internal.Utils; 21 import java.util.Collection; 22 import java.util.Collections; 23 import java.util.HashMap; 24 import java.util.Map; 25 import javax.annotation.concurrent.Immutable; 26 import javax.annotation.concurrent.ThreadSafe; 27 28 /** 29 * This class allows users to access in-process information about all running spans. 30 * 31 * <p>The running spans tracking is available for all the spans with the option {@link 32 * io.opencensus.trace.Span.Options#RECORD_EVENTS}. This functionality allows users to debug stuck 33 * operations or long living operations. 34 * 35 * @since 0.5 36 */ 37 @ThreadSafe 38 public abstract class RunningSpanStore { 39 40 private static final RunningSpanStore NOOP_RUNNING_SPAN_STORE = new NoopRunningSpanStore(); 41 42 protected RunningSpanStore() {} 43 44 /** 45 * Returns the no-op implementation of the {@code RunningSpanStore}. 46 * 47 * @return the no-op implementation of the {@code RunningSpanStore}. 48 */ 49 static RunningSpanStore getNoopRunningSpanStore() { 50 return NOOP_RUNNING_SPAN_STORE; 51 } 52 53 /** 54 * Returns the summary of all available data such, as number of running spans. 55 * 56 * @return the summary of all available data. 57 * @since 0.5 58 */ 59 public abstract Summary getSummary(); 60 61 /** 62 * Returns a list of running spans that match the {@code Filter}. 63 * 64 * @param filter used to filter the returned spans. 65 * @return a list of running spans that match the {@code Filter}. 66 * @since 0.5 67 */ 68 public abstract Collection<SpanData> getRunningSpans(Filter filter); 69 70 /** 71 * The summary of all available data. 72 * 73 * @since 0.5 74 */ 75 @AutoValue 76 @Immutable 77 public abstract static class Summary { 78 79 Summary() {} 80 81 /** 82 * Returns a new instance of {@code Summary}. 83 * 84 * @param perSpanNameSummary a map with summary for each span name. 85 * @return a new instance of {@code Summary}. 86 * @throws NullPointerException if {@code perSpanNameSummary} is {@code null}. 87 * @since 0.5 88 */ 89 public static Summary create(Map<String, PerSpanNameSummary> perSpanNameSummary) { 90 return new AutoValue_RunningSpanStore_Summary( 91 Collections.unmodifiableMap( 92 new HashMap<String, PerSpanNameSummary>( 93 Utils.checkNotNull(perSpanNameSummary, "perSpanNameSummary")))); 94 } 95 96 /** 97 * Returns a map with summary of available data for each span name. 98 * 99 * @return a map with all the span names and the summary. 100 * @since 0.5 101 */ 102 public abstract Map<String, PerSpanNameSummary> getPerSpanNameSummary(); 103 } 104 105 /** 106 * Summary of all available data for a span name. 107 * 108 * @since 0.5 109 */ 110 @AutoValue 111 @Immutable 112 public abstract static class PerSpanNameSummary { 113 114 PerSpanNameSummary() {} 115 116 /** 117 * Returns a new instance of {@code PerSpanNameSummary}. 118 * 119 * @param numRunningSpans the number of running spans. 120 * @return a new instance of {@code PerSpanNameSummary}. 121 * @throws IllegalArgumentException if {@code numRunningSpans} is negative. 122 * @since 0.5 123 */ 124 public static PerSpanNameSummary create(int numRunningSpans) { 125 Utils.checkArgument(numRunningSpans >= 0, "Negative numRunningSpans."); 126 return new AutoValue_RunningSpanStore_PerSpanNameSummary(numRunningSpans); 127 } 128 129 /** 130 * Returns the number of running spans. 131 * 132 * @return the number of running spans. 133 * @since 0.5 134 */ 135 public abstract int getNumRunningSpans(); 136 } 137 138 /** 139 * Filter for running spans. Used to filter results returned by the {@link 140 * #getRunningSpans(Filter)} request. 141 * 142 * @since 0.5 143 */ 144 @AutoValue 145 @Immutable 146 public abstract static class Filter { 147 148 Filter() {} 149 150 /** 151 * Returns a new instance of {@code Filter}. 152 * 153 * <p>Filters all the spans based on {@code spanName} and returns a maximum of {@code 154 * maxSpansToReturn}. 155 * 156 * @param spanName the name of the span. 157 * @param maxSpansToReturn the maximum number of results to be returned. {@code 0} means all. 158 * @return a new instance of {@code Filter}. 159 * @throws NullPointerException if {@code spanName} is {@code null}. 160 * @throws IllegalArgumentException if {@code maxSpansToReturn} is negative. 161 * @since 0.5 162 */ 163 public static Filter create(String spanName, int maxSpansToReturn) { 164 Utils.checkArgument(maxSpansToReturn >= 0, "Negative maxSpansToReturn."); 165 return new AutoValue_RunningSpanStore_Filter(spanName, maxSpansToReturn); 166 } 167 168 /** 169 * Returns the span name. 170 * 171 * @return the span name. 172 * @since 0.5 173 */ 174 public abstract String getSpanName(); 175 176 /** 177 * Returns the maximum number of spans to be returned. {@code 0} means all. 178 * 179 * @return the maximum number of spans to be returned. 180 * @since 0.5 181 */ 182 public abstract int getMaxSpansToReturn(); 183 } 184 185 private static final class NoopRunningSpanStore extends RunningSpanStore { 186 187 private static final Summary EMPTY_SUMMARY = 188 Summary.create(Collections.<String, PerSpanNameSummary>emptyMap()); 189 190 @Override 191 public Summary getSummary() { 192 return EMPTY_SUMMARY; 193 } 194 195 @Override 196 public Collection<SpanData> getRunningSpans(Filter filter) { 197 Utils.checkNotNull(filter, "filter"); 198 return Collections.<SpanData>emptyList(); 199 } 200 } 201 } 202