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 */
018package org.apache.hadoop.hbase.trace;
019
020import org.apache.hadoop.conf.Configuration;
021import org.apache.htrace.core.HTraceConfiguration;
022import org.apache.htrace.core.Sampler;
023import org.apache.htrace.core.Span;
024import org.apache.htrace.core.SpanReceiver;
025import org.apache.htrace.core.TraceScope;
026import org.apache.htrace.core.Tracer;
027import org.apache.yetus.audience.InterfaceAudience;
028
029/**
030 * This wrapper class provides functions for accessing htrace 4+ functionality in a simplified way.
031 */
032@InterfaceAudience.Private
033public final class TraceUtil {
034  private static HTraceConfiguration conf;
035  private static Tracer tracer;
036
037  private TraceUtil() {
038  }
039
040  public static void initTracer(Configuration c) {
041    if (c != null) {
042      conf = new HBaseHTraceConfiguration(c);
043    }
044
045    if (tracer == null && conf != null) {
046      tracer = new Tracer.Builder("Tracer").conf(conf).build();
047    }
048  }
049
050  /**
051   * Wrapper method to create new TraceScope with the given description
052   * @return TraceScope or null when not tracing
053   */
054  public static TraceScope createTrace(String description) {
055    return (tracer == null) ? null : tracer.newScope(description);
056  }
057
058  /**
059   * Wrapper method to create new child TraceScope with the given description
060   * and parent scope's spanId
061   * @param span parent span
062   * @return TraceScope or null when not tracing
063   */
064  public static TraceScope createTrace(String description, Span span) {
065    if (span == null) {
066      return createTrace(description);
067    }
068
069    return (tracer == null) ? null : tracer.newScope(description, span.getSpanId());
070  }
071
072  /**
073   * Wrapper method to add new sampler to the default tracer
074   * @return true if added, false if it was already added
075   */
076  public static boolean addSampler(Sampler sampler) {
077    if (sampler == null) {
078      return false;
079    }
080
081    return (tracer == null) ? false : tracer.addSampler(sampler);
082  }
083
084  /**
085   * Wrapper method to add key-value pair to TraceInfo of actual span
086   */
087  public static void addKVAnnotation(String key, String value){
088    Span span = Tracer.getCurrentSpan();
089    if (span != null) {
090      span.addKVAnnotation(key, value);
091    }
092  }
093
094  /**
095   * Wrapper method to add receiver to actual tracerpool
096   * @return true if successfull, false if it was already added
097   */
098  public static boolean addReceiver(SpanReceiver rcvr) {
099    return (tracer == null) ? false : tracer.getTracerPool().addReceiver(rcvr);
100  }
101
102  /**
103   * Wrapper method to remove receiver from actual tracerpool
104   * @return true if removed, false if doesn't exist
105   */
106  public static boolean removeReceiver(SpanReceiver rcvr) {
107    return (tracer == null) ? false : tracer.getTracerPool().removeReceiver(rcvr);
108  }
109
110  /**
111   * Wrapper method to add timeline annotiation to current span with given message
112   */
113  public static void addTimelineAnnotation(String msg) {
114    Span span = Tracer.getCurrentSpan();
115    if (span != null) {
116      span.addTimelineAnnotation(msg);
117    }
118  }
119
120  /**
121   * Wrap runnable with current tracer and description
122   * @param runnable to wrap
123   * @return wrapped runnable or original runnable when not tracing
124   */
125  public static Runnable wrap(Runnable runnable, String description) {
126    return (tracer == null) ? runnable : tracer.wrap(runnable, description);
127  }
128}