From d71f317397b8f96591e411b2585444e864f692b0 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Sat, 7 Jan 2017 12:27:56 +0800 Subject: [PATCH] Flags yellow for annotations that match case insensitive error Particularly, this flags existing finagle formatted errors, like so: "Server Send Error: TimeoutException: socket timed out" Fixes #1472 See https://github.com/openzipkin/openzipkin.github.io/issues/52 --- zipkin-ui/js/component_ui/spanPanel.js | 12 ++++-- zipkin-ui/test/component_ui/spanPanel.test.js | 38 +++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/zipkin-ui/js/component_ui/spanPanel.js b/zipkin-ui/js/component_ui/spanPanel.js index bc6e7e95e54..764b5c73d72 100644 --- a/zipkin-ui/js/component_ui/spanPanel.js +++ b/zipkin-ui/js/component_ui/spanPanel.js @@ -2,6 +2,14 @@ import {component} from 'flightjs'; import $ from 'jquery'; import {Constants} from './traceConstants'; +// Annotation values that contain the word "error" hint of a transient error. +// This adds a class when that's the case. +export function maybeMarkTransientError(row, anno) { + if (/error/i.test(anno.value)) { + row.addClass('anno-error-transient'); + } +} + // annotations are named events which shouldn't hold json. If someone passed // json, format as a single line. That way the rows corresponding to timestamps // aren't disrupted. @@ -42,9 +50,7 @@ export default component(function spanPanel() { const $annoBody = this.$node.find('#annotations tbody').text(''); $.each((span.annotations || []), (i, anno) => { const $row = self.$annotationTemplate.clone(); - if (anno.value === Constants.ERROR) { - $row.addClass('anno-error-transient'); - } + maybeMarkTransientError($row, anno); $row.find('td').each(function() { const $this = $(this); const unformattedValue = anno[$this.data('key')]; diff --git a/zipkin-ui/test/component_ui/spanPanel.test.js b/zipkin-ui/test/component_ui/spanPanel.test.js index 289846dae7c..0cdc4881ddd 100644 --- a/zipkin-ui/test/component_ui/spanPanel.test.js +++ b/zipkin-ui/test/component_ui/spanPanel.test.js @@ -1,10 +1,48 @@ +import {Constants} from '../../js/component_ui/traceConstants'; import { + maybeMarkTransientError, formatAnnotationValue, formatBinaryAnnotationValue } from '../../js/component_ui/spanPanel'; +import {endpoint, annotation} from './traceTestHelpers'; + +const ep = endpoint(123, 123, 'service1'); chai.config.truncateThreshold = 0; +describe('maybeMarkTransientError', () => { + const row = { + className: '', + addClass(className) {this.className = className;} + }; + + it('should not add class when annotation is not error', () => { + const anno = annotation(100, Constants.CLIENT_SEND, ep); + + maybeMarkTransientError(row, anno); + row.className.should.equal(''); + }); + + it('should add class when annotation is error', () => { + const anno = annotation(100, Constants.ERROR, ep); + + maybeMarkTransientError(row, anno); + row.className.should.equal('anno-error-transient'); + }); + + // uses an actual value from Finagle + it('should add class when annotation matches error', () => { + const anno = annotation( + 100, + 'Server Send Error: TimeoutException: socket timed out', + ep + ); + + maybeMarkTransientError(row, anno); + row.className.should.equal('anno-error-transient'); + }); +}); + describe('formatAnnotationValue', () => { it('should return same value when string', () => { formatAnnotationValue('foo').should.equal('foo');