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.client.trace;
019
020import static org.apache.hadoop.hbase.trace.HBaseSemanticAttributes.DB_NAME;
021import static org.apache.hadoop.hbase.trace.HBaseSemanticAttributes.TABLE_KEY;
022
023import io.opentelemetry.api.common.AttributeKey;
024import io.opentelemetry.api.trace.Span;
025import io.opentelemetry.api.trace.SpanBuilder;
026import io.opentelemetry.api.trace.SpanKind;
027import java.util.HashMap;
028import java.util.Map;
029import java.util.function.Supplier;
030import org.apache.hadoop.hbase.TableName;
031import org.apache.hadoop.hbase.client.AsyncConnectionImpl;
032import org.apache.hadoop.hbase.client.ClusterConnection;
033import org.apache.hadoop.hbase.trace.TraceUtil;
034import org.apache.yetus.audience.InterfaceAudience;
035
036/**
037 * Construct {@link Span} instances involving data tables.
038 */
039@InterfaceAudience.Private
040public class TableSpanBuilder implements Supplier<Span> {
041
042  private String name;
043  private final Map<AttributeKey<?>, Object> attributes = new HashMap<>();
044
045  public TableSpanBuilder(ClusterConnection conn) {
046    ConnectionSpanBuilder.populateConnectionAttributes(attributes, conn);
047  }
048
049  public TableSpanBuilder(AsyncConnectionImpl conn) {
050    ConnectionSpanBuilder.populateConnectionAttributes(attributes, conn);
051  }
052
053  @Override
054  public Span get() {
055    return build();
056  }
057
058  public TableSpanBuilder setName(final String name) {
059    this.name = name;
060    return this;
061  }
062
063  public TableSpanBuilder setTableName(final TableName tableName) {
064    populateTableNameAttributes(attributes, tableName);
065    return this;
066  }
067
068  @SuppressWarnings("unchecked")
069  public Span build() {
070    final SpanBuilder builder =
071      TraceUtil.getGlobalTracer().spanBuilder(name).setSpanKind(SpanKind.INTERNAL);
072    attributes.forEach((k, v) -> builder.setAttribute((AttributeKey<? super Object>) k, v));
073    return builder.startSpan();
074  }
075
076  /**
077   * Static utility method that performs the primary logic of this builder. It is visible to other
078   * classes in this package so that other builders can use this functionality as a mix-in.
079   * @param attributes the attributes map to be populated.
080   * @param tableName  the source of attribute values.
081   */
082  static void populateTableNameAttributes(final Map<AttributeKey<?>, Object> attributes,
083    final TableName tableName) {
084    attributes.put(DB_NAME, tableName.getNamespaceAsString());
085    attributes.put(TABLE_KEY, tableName.getNameAsString());
086  }
087}