| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.accumulo.tracer; |
| |
| import java.text.SimpleDateFormat; |
| import java.util.Date; |
| import java.util.Iterator; |
| import java.util.Map.Entry; |
| |
| import org.apache.accumulo.core.data.Key; |
| import org.apache.accumulo.core.data.Value; |
| import org.apache.accumulo.core.util.format.DateFormatSupplier; |
| import org.apache.accumulo.core.util.format.DefaultFormatter; |
| import org.apache.accumulo.core.util.format.Formatter; |
| import org.apache.accumulo.core.util.format.FormatterConfig; |
| import org.apache.accumulo.tracer.thrift.Annotation; |
| import org.apache.accumulo.tracer.thrift.RemoteSpan; |
| import org.apache.commons.lang.NotImplementedException; |
| import org.apache.hadoop.io.Text; |
| import org.apache.thrift.TException; |
| import org.apache.thrift.protocol.TCompactProtocol; |
| import org.apache.thrift.transport.TMemoryInputTransport; |
| |
| /** |
| * A formatter than can be used in the shell to display trace information. |
| * |
| */ |
| public class TraceFormatter implements Formatter { |
| public static final String DATE_FORMAT = DateFormatSupplier.HUMAN_READABLE_FORMAT; |
| // ugh... SimpleDataFormat is not thread safe |
| private static final DateFormatSupplier formatter = DateFormatSupplier |
| .createSimpleFormatSupplier(DATE_FORMAT); |
| |
| public static String formatDate(final Date date) { |
| return formatter.get().format(date); |
| } |
| |
| private static final Text SPAN_CF = new Text("span"); |
| |
| private Iterator<Entry<Key,Value>> scanner; |
| private FormatterConfig config; |
| |
| public static RemoteSpan getRemoteSpan(Entry<Key,Value> entry) { |
| TMemoryInputTransport transport = new TMemoryInputTransport(entry.getValue().get()); |
| TCompactProtocol protocol = new TCompactProtocol(transport); |
| RemoteSpan span = new RemoteSpan(); |
| try { |
| span.read(protocol); |
| } catch (TException ex) { |
| throw new RuntimeException(ex); |
| } |
| return span; |
| } |
| |
| @Override |
| public boolean hasNext() { |
| return scanner.hasNext(); |
| } |
| |
| @Override |
| public String next() { |
| Entry<Key,Value> next = scanner.next(); |
| if (next.getKey().getColumnFamily().equals(SPAN_CF)) { |
| StringBuilder result = new StringBuilder(); |
| SimpleDateFormat dateFormatter = new SimpleDateFormat(DATE_FORMAT); |
| RemoteSpan span = getRemoteSpan(next); |
| result.append("----------------------\n"); |
| result.append(String.format(" %12s:%s%n", "name", span.description)); |
| result.append(String.format(" %12s:%s%n", "trace", Long.toHexString(span.traceId))); |
| result.append(String.format(" %12s:%s%n", "loc", span.svc + "@" + span.sender)); |
| result.append(String.format(" %12s:%s%n", "span", Long.toHexString(span.spanId))); |
| result.append(String.format(" %12s:%s%n", "parent", Long.toHexString(span.parentId))); |
| result.append(String.format(" %12s:%s%n", "start", dateFormatter.format(span.start))); |
| result.append(String.format(" %12s:%s%n", "ms", span.stop - span.start)); |
| if (span.data != null) { |
| for (Entry<String,String> entry : span.data.entrySet()) { |
| result.append(String.format(" %12s:%s%n", entry.getKey(), entry.getValue())); |
| } |
| } |
| if (span.annotations != null) { |
| for (Annotation annotation : span.annotations) { |
| result.append(String.format(" %12s:%s:%s%n", "annotation", annotation.getMsg(), |
| dateFormatter.format(annotation.getTime()))); |
| } |
| } |
| |
| if (config.willPrintTimestamps()) { |
| result.append(String.format(" %-12s:%d%n", "timestamp", next.getKey().getTimestamp())); |
| } |
| return result.toString(); |
| } |
| return DefaultFormatter.formatEntry(next, config.willPrintTimestamps()); |
| } |
| |
| @Override |
| public void remove() { |
| throw new NotImplementedException(); |
| } |
| |
| @Override |
| public void initialize(Iterable<Entry<Key,Value>> scanner, FormatterConfig config) { |
| this.scanner = scanner.iterator(); |
| this.config = new FormatterConfig(config); |
| } |
| } |