use of org.apache.htrace.Span in project phoenix by apache.
the class PhoenixTracingEndToEndIT method testMultipleSpans.
/**
* Test multiple spans, within the same trace. Some spans are independent of the parent span,
* some are child spans
* @throws Exception on failure
*/
@Test
public void testMultipleSpans() throws Exception {
Connection conn = getConnectionWithoutTracing();
String tableName = generateUniqueName();
latch = new CountDownLatch(4);
testTraceWriter = new TestTraceWriter(tableName, defaultTracingThreadPoolForTest, defaultTracingBatchSizeForTest);
// create a simple metrics record
long traceid = 12345;
List<Span> spans = new ArrayList<Span>();
Span span = createNewSpan(traceid, Span.ROOT_SPAN_ID, 7777, "root", 10, 30, "root process", "root-span tag");
spans.add(span);
// then create a child record
span = createNewSpan(traceid, 7777, 6666, "c1", 11, 15, "c1 process", "first child");
spans.add(span);
// create a different child
span = createNewSpan(traceid, 7777, 5555, "c2", 11, 18, "c2 process", "second child");
spans.add(span);
// create a child of the second child
span = createNewSpan(traceid, 5555, 4444, "c3", 12, 16, "c3 process", "third child");
spans.add(span);
for (Span span1 : spans) Tracing.getTraceSpanReceiver().receiveSpan(span1);
assertTrue("Updates not written in table", latch.await(100, TimeUnit.SECONDS));
// start a reader
validateTraces(spans, conn, traceid, tableName);
}
use of org.apache.htrace.Span in project phoenix by apache.
the class PhoenixTracingEndToEndIT method testSingleSpan.
@Test
public void testSingleSpan() throws Exception {
Properties props = new Properties(TEST_PROPERTIES);
Connection conn = DriverManager.getConnection(getUrl(), props);
String tableName = generateUniqueName();
latch = new CountDownLatch(1);
testTraceWriter = new TestTraceWriter(tableName, defaultTracingThreadPoolForTest, defaultTracingBatchSizeForTest);
// create a simple metrics record
long traceid = 987654;
Span span = createNewSpan(traceid, Span.ROOT_SPAN_ID, 10, "root", 12, 13, "Some process", "test annotation for a span");
Tracing.getTraceSpanReceiver().receiveSpan(span);
assertTrue("Updates not written in table", latch.await(60, TimeUnit.SECONDS));
// start a reader
validateTraces(Collections.singletonList(span), conn, traceid, tableName);
}
use of org.apache.htrace.Span in project phoenix by apache.
the class PhoenixTracingEndToEndIT method validateTrace.
/**
* @param spans
* @param trace
*/
private void validateTrace(List<Span> spans, TraceHolder trace) {
// drop each span into a sorted list so we get the expected ordering
Iterator<SpanInfo> spanIter = trace.spans.iterator();
for (Span span : spans) {
SpanInfo spanInfo = spanIter.next();
LOG.info("Checking span:\n" + spanInfo);
long parentId = span.getParentId();
if (parentId == Span.ROOT_SPAN_ID) {
assertNull("Got a parent, but it was a root span!", spanInfo.parent);
} else {
assertEquals("Got an unexpected parent span id", parentId, spanInfo.parent.id);
}
assertEquals("Got an unexpected start time", span.getStartTimeMillis(), spanInfo.start);
assertEquals("Got an unexpected end time", span.getStopTimeMillis(), spanInfo.end);
int annotationCount = 0;
for (Map.Entry<byte[], byte[]> entry : span.getKVAnnotations().entrySet()) {
int count = annotationCount++;
assertEquals("Didn't get expected annotation", count + " - " + Bytes.toString(entry.getValue()), spanInfo.annotations.get(count));
}
assertEquals("Didn't get expected number of annotations", annotationCount, spanInfo.annotationCount);
}
}
use of org.apache.htrace.Span in project phoenix by apache.
the class PhoenixTracingEndToEndIT method testWriteSpans.
/**
* Simple test that we can correctly write spans to the phoenix table
* @throws Exception on failure
*/
@Test
public void testWriteSpans() throws Exception {
// watch our sink so we know when commits happen
latch = new CountDownLatch(1);
testTraceWriter = new TestTraceWriter(tracingTableName, defaultTracingThreadPoolForTest, defaultTracingBatchSizeForTest);
// write some spans
TraceScope trace = Trace.startSpan("Start write test", Sampler.ALWAYS);
Span span = trace.getSpan();
// add a child with some annotations
Span child = span.child("child 1");
child.addTimelineAnnotation("timeline annotation");
TracingUtils.addAnnotation(child, "test annotation", 10);
child.stop();
// sleep a little bit to get some time difference
Thread.sleep(100);
trace.close();
// pass the trace on
Tracing.getTraceSpanReceiver().receiveSpan(span);
// wait for the tracer to actually do the write
assertTrue("Sink not flushed. commit() not called on the connection", latch.await(60, TimeUnit.SECONDS));
// look for the writes to make sure they were made
Connection conn = getConnectionWithoutTracing();
checkStoredTraces(conn, new TraceChecker() {
@Override
public boolean foundTrace(TraceHolder trace, SpanInfo info) {
if (info.description.equals("child 1")) {
assertEquals("Not all annotations present", 1, info.annotationCount);
assertEquals("Not all tags present", 1, info.tagCount);
boolean found = false;
for (String annotation : info.annotations) {
if (annotation.startsWith("test annotation")) {
found = true;
}
}
assertTrue("Missing the annotations in span: " + info, found);
found = false;
for (String tag : info.tags) {
if (tag.endsWith("timeline annotation")) {
found = true;
}
}
assertTrue("Missing the tags in span: " + info, found);
return true;
}
return false;
}
});
}
use of org.apache.htrace.Span in project phoenix by apache.
the class Indexer method doPostWithExceptions.
private void doPostWithExceptions(WALEdit edit, Mutation m, final Durability durability) throws Exception {
//short circuit, if we don't need to do any work
if (durability == Durability.SKIP_WAL || !this.builder.isEnabled(m) || edit == null) {
// already did the index update in prePut, so we are done
return;
}
// get the current span, or just use a null-span to avoid a bunch of if statements
try (TraceScope scope = Trace.startSpan("Completing index writes")) {
Span current = scope.getSpan();
if (current == null) {
current = NullSpan.INSTANCE;
}
// there is a little bit of excess here- we iterate all the non-indexed kvs for this check first
// and then do it again later when getting out the index updates. This should be pretty minor
// though, compared to the rest of the runtime
IndexedKeyValue ikv = getFirstIndexedKeyValue(edit);
/*
* early exit - we have nothing to write, so we don't need to do anything else. NOTE: we don't
* release the WAL Rolling lock (INDEX_UPDATE_LOCK) since we never take it in doPre if there are
* no index updates.
*/
if (ikv == null) {
return;
}
/*
* only write the update if we haven't already seen this batch. We only want to write the batch
* once (this hook gets called with the same WALEdit for each Put/Delete in a batch, which can
* lead to writing all the index updates for each Put/Delete).
*/
if (!ikv.getBatchFinished()) {
Collection<Pair<Mutation, byte[]>> indexUpdates = extractIndexUpdate(edit);
// already specified on each reference
try {
current.addTimelineAnnotation("Actually doing index update for first time");
writer.writeAndKillYourselfOnFailure(indexUpdates, false);
} finally {
// With a custom kill policy, we may throw instead of kill the server.
// Without doing this in a finally block (at least with the mini cluster),
// the region server never goes down.
// mark the batch as having been written. In the single-update case, this never gets check
// again, but in the batch case, we will check it again (see above).
ikv.markBatchFinished();
}
}
}
}
Aggregations