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) return createTrace(description);
066
067    return (tracer == null) ? null : tracer.newScope(description, span.getSpanId());
068  }
069
070  /**
071   * Wrapper method to add new sampler to the default tracer
072   * @return true if added, false if it was already added
073   */
074  public static boolean addSampler(Sampler sampler) {
075    if (sampler == null) {
076      return false;
077    }
078
079    return (tracer == null) ? false : tracer.addSampler(sampler);
080  }
081
082  /**
083   * Wrapper method to add key-value pair to TraceInfo of actual span
084   */
085  public static void addKVAnnotation(String key, String value){
086    Span span = Tracer.getCurrentSpan();
087    if (span != null) {
088      span.addKVAnnotation(key, value);
089    }
090  }
091
092  /**
093   * Wrapper method to add receiver to actual tracerpool
094   * @return true if successfull, false if it was already added
095   */
096  public static boolean addReceiver(SpanReceiver rcvr) {
097    return (tracer == null) ? false : tracer.getTracerPool().addReceiver(rcvr);
098  }
099
100  /**
101   * Wrapper method to remove receiver from actual tracerpool
102   * @return true if removed, false if doesn't exist
103   */
104  public static boolean removeReceiver(SpanReceiver rcvr) {
105    return (tracer == null) ? false : tracer.getTracerPool().removeReceiver(rcvr);
106  }
107
108  /**
109   * Wrapper method to add timeline annotiation to current span with given message
110   */
111  public static void addTimelineAnnotation(String msg) {
112    Span span = Tracer.getCurrentSpan();
113    if (span != null) {
114      span.addTimelineAnnotation(msg);
115    }
116  }
117
118  /**
119   * Wrap runnable with current tracer and description
120   * @param runnable to wrap
121   * @return wrapped runnable or original runnable when not tracing
122   */
123  public static Runnable wrap(Runnable runnable, String description) {
124    return (tracer == null) ? runnable : tracer.wrap(runnable, description);
125  }
126}