From 2be43a5f9d9d6325f1b887815683bb3d9c880e64 Mon Sep 17 00:00:00 2001 From: Tarun Pothulapati Date: Thu, 7 May 2020 21:35:56 +0000 Subject: [PATCH] Add Jaeger links to the Linkerd dashboard (#4177) * Add Jaeger reverse proxy * add jaegerLink to the metrics table * update MetricsTable tests * Add optional jaeger link * rename grafana_proxy to reverse_proxy Signed-off-by: Tarun Pothulapati --- charts/add-ons/tracing/templates/tracing.yaml | 4 +- charts/linkerd2/templates/web.yaml | 3 + .../install_addon_control-plane.golden | 5 +- .../install_helm_output_addons.golden | 5 +- cli/cmd/testdata/install_tracing.golden | 5 +- .../upgrade_add-on_controlplane.golden | 5 +- .../testdata/upgrade_add-on_overwrite.golden | 5 +- cli/cmd/testdata/upgrade_add_add-on.golden | 5 +- web/app/js/components/JaegerLink.jsx | 41 + web/app/js/components/MetricsTable.jsx | 38 +- web/app/js/components/MetricsTable.test.js | 14 + web/app/js/components/util/SvgWrappers.jsx | 2589 +++++++++++++++++ web/main.go | 3 +- web/srv/handlers.go | 9 +- .../{grafana_proxy.go => reverse_proxy.go} | 14 +- web/srv/server.go | 27 +- web/templates/app.tmpl.html | 3 +- 17 files changed, 2745 insertions(+), 30 deletions(-) create mode 100644 web/app/js/components/JaegerLink.jsx rename web/srv/{grafana_proxy.go => reverse_proxy.go} (56%) diff --git a/charts/add-ons/tracing/templates/tracing.yaml b/charts/add-ons/tracing/templates/tracing.yaml index 6c456905c..5f929a131 100644 --- a/charts/add-ons/tracing/templates/tracing.yaml +++ b/charts/add-ons/tracing/templates/tracing.yaml @@ -206,7 +206,9 @@ spec: {{- include "partials.proxy.labels" .Values.global.proxy | nindent 8}} spec: containers: - - image: {{.Values.jaeger.image}} + - args: + - --query.base-path=/jaeger + image: {{.Values.jaeger.image}} imagePullPolicy: {{.Values.global.imagePullPolicy}} name: jaeger ports: diff --git a/charts/linkerd2/templates/web.yaml b/charts/linkerd2/templates/web.yaml index e3eb720df..b5b77a681 100644 --- a/charts/linkerd2/templates/web.yaml +++ b/charts/linkerd2/templates/web.yaml @@ -64,6 +64,9 @@ spec: - args: - -api-addr=linkerd-controller-api.{{.Values.global.namespace}}.svc.{{.Values.global.clusterDomain}}:8085 - -grafana-addr=linkerd-grafana.{{.Values.global.namespace}}.svc.{{.Values.global.clusterDomain}}:3000 + {{- if .Values.tracing.enabled }} + - -jaeger-addr={{.Values.tracing.jaeger.name}}.{{.Values.global.namespace}}.svc.{{.Values.global.clusterDomain}}:16686 + {{- end}} - -controller-namespace={{.Values.global.namespace}} - -log-level={{.Values.controllerLogLevel}} {{- if .Values.enforcedHostRegexp }} diff --git a/cli/cmd/testdata/install_addon_control-plane.golden b/cli/cmd/testdata/install_addon_control-plane.golden index 1957e5901..09d799512 100644 --- a/cli/cmd/testdata/install_addon_control-plane.golden +++ b/cli/cmd/testdata/install_addon_control-plane.golden @@ -801,6 +801,7 @@ spec: - args: - -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085 - -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000 + - -jaeger-addr=linkerd-jaeger.linkerd.svc.cluster.local:16686 - -controller-namespace=linkerd - -log-level=info - -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$ @@ -2615,7 +2616,9 @@ spec: linkerd.io/proxy-deployment: linkerd-jaeger spec: containers: - - image: jaegertracing/all-in-one:1.17.1 + - args: + - --query.base-path=/jaeger + image: jaegertracing/all-in-one:1.17.1 imagePullPolicy: IfNotPresent name: jaeger ports: diff --git a/cli/cmd/testdata/install_helm_output_addons.golden b/cli/cmd/testdata/install_helm_output_addons.golden index c45ea4ae0..3f65db2cf 100644 --- a/cli/cmd/testdata/install_helm_output_addons.golden +++ b/cli/cmd/testdata/install_helm_output_addons.golden @@ -1714,6 +1714,7 @@ spec: - args: - -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085 - -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000 + - -jaeger-addr=linkerd-jaeger.linkerd.svc.cluster.local:16686 - -controller-namespace=linkerd - -log-level=info - -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$ @@ -3512,7 +3513,9 @@ spec: linkerd.io/proxy-deployment: linkerd-jaeger spec: containers: - - image: jaegertracing/all-in-one:1.17.1 + - args: + - --query.base-path=/jaeger + image: jaegertracing/all-in-one:1.17.1 imagePullPolicy: IfNotPresent name: jaeger ports: diff --git a/cli/cmd/testdata/install_tracing.golden b/cli/cmd/testdata/install_tracing.golden index 42b2c0076..89b6967f1 100644 --- a/cli/cmd/testdata/install_tracing.golden +++ b/cli/cmd/testdata/install_tracing.golden @@ -1641,6 +1641,7 @@ spec: - args: - -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085 - -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000 + - -jaeger-addr=linkerd-jaeger.linkerd.svc.cluster.local:16686 - -controller-namespace=linkerd - -log-level=info - -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$ @@ -3481,7 +3482,9 @@ spec: linkerd.io/proxy-deployment: linkerd-jaeger spec: containers: - - image: jaegertracing/all-in-one:1.17.1 + - args: + - --query.base-path=/jaeger + image: jaegertracing/all-in-one:1.17.1 imagePullPolicy: IfNotPresent name: jaeger ports: diff --git a/cli/cmd/testdata/upgrade_add-on_controlplane.golden b/cli/cmd/testdata/upgrade_add-on_controlplane.golden index 351e767ff..1c6a32bf9 100644 --- a/cli/cmd/testdata/upgrade_add-on_controlplane.golden +++ b/cli/cmd/testdata/upgrade_add-on_controlplane.golden @@ -807,6 +807,7 @@ spec: - args: - -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085 - -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000 + - -jaeger-addr=linkerd-jaeger.linkerd.svc.cluster.local:16686 - -controller-namespace=linkerd - -log-level=info - -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$ @@ -2635,7 +2636,9 @@ spec: linkerd.io/proxy-deployment: linkerd-jaeger spec: containers: - - image: jaegertracing/all-in-one:1.17.1 + - args: + - --query.base-path=/jaeger + image: jaegertracing/all-in-one:1.17.1 imagePullPolicy: IfNotPresent name: jaeger ports: diff --git a/cli/cmd/testdata/upgrade_add-on_overwrite.golden b/cli/cmd/testdata/upgrade_add-on_overwrite.golden index db5abaf51..0553ac75e 100644 --- a/cli/cmd/testdata/upgrade_add-on_overwrite.golden +++ b/cli/cmd/testdata/upgrade_add-on_overwrite.golden @@ -1647,6 +1647,7 @@ spec: - args: - -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085 - -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000 + - -jaeger-addr=linkerd-jaeger.linkerd.svc.cluster.local:16686 - -controller-namespace=linkerd - -log-level=info - -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$ @@ -3499,7 +3500,9 @@ spec: linkerd.io/proxy-deployment: linkerd-jaeger spec: containers: - - image: jaegertracing/all-in-one:1.17.1 + - args: + - --query.base-path=/jaeger + image: jaegertracing/all-in-one:1.17.1 imagePullPolicy: IfNotPresent name: jaeger ports: diff --git a/cli/cmd/testdata/upgrade_add_add-on.golden b/cli/cmd/testdata/upgrade_add_add-on.golden index fd1feac14..4bfb636d1 100644 --- a/cli/cmd/testdata/upgrade_add_add-on.golden +++ b/cli/cmd/testdata/upgrade_add_add-on.golden @@ -1647,6 +1647,7 @@ spec: - args: - -api-addr=linkerd-controller-api.linkerd.svc.cluster.local:8085 - -grafana-addr=linkerd-grafana.linkerd.svc.cluster.local:3000 + - -jaeger-addr=linkerd-jaeger.linkerd.svc.cluster.local:16686 - -controller-namespace=linkerd - -log-level=info - -enforced-host=^(localhost|127\.0\.0\.1|linkerd-web\.linkerd\.svc\.cluster\.local|linkerd-web\.linkerd\.svc|\[::1\])(:\d+)?$ @@ -3501,7 +3502,9 @@ spec: linkerd.io/proxy-deployment: linkerd-jaeger spec: containers: - - image: jaegertracing/all-in-one:1.17.1 + - args: + - --query.base-path=/jaeger + image: jaegertracing/all-in-one:1.17.1 imagePullPolicy: IfNotPresent name: jaeger ports: diff --git a/web/app/js/components/JaegerLink.jsx b/web/app/js/components/JaegerLink.jsx new file mode 100644 index 000000000..1009d7e43 --- /dev/null +++ b/web/app/js/components/JaegerLink.jsx @@ -0,0 +1,41 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import _isEmpty from 'lodash/isEmpty'; +import { jaegerIcon } from './util/SvgWrappers.jsx'; + +function jaegerQuery(name, namespace, resource) { + if (_isEmpty(namespace)) { + return `{"linkerd.io/workload-ns"%3A"${name}"}`; + } else if (resource === 'pod') { + return `{"hostname"%3A"${name}"%2C"linkerd.io/workload-ns"%3A"${namespace}"}`; + } else { + return `{"linkerd.io%2Fproxy-${resource}"%3A"${name}"%2C"linkerd.io/workload-ns"%3A"${namespace}"}`; + } +} + +const JaegerLink = ({ PrefixedLink, name, namespace, resource }) => { + const link = `/jaeger/search?service=linkerd-proxy&tags=${jaegerQuery(name, namespace, resource)}`; + + return ( + +    + {jaegerIcon} + + ); +}; + + +JaegerLink.propTypes = { + name: PropTypes.string.isRequired, + namespace: PropTypes.string, + PrefixedLink: PropTypes.func.isRequired, + resource: PropTypes.string.isRequired, +}; + +JaegerLink.defaultProps = { + namespace: '', +}; + +export default JaegerLink; diff --git a/web/app/js/components/MetricsTable.jsx b/web/app/js/components/MetricsTable.jsx index 59c54b558..9d981005c 100644 --- a/web/app/js/components/MetricsTable.jsx +++ b/web/app/js/components/MetricsTable.jsx @@ -3,6 +3,7 @@ import BaseTable from './BaseTable.jsx'; import ErrorModal from './ErrorModal.jsx'; import GrafanaLink from './GrafanaLink.jsx'; import Grid from '@material-ui/core/Grid'; +import JaegerLink from './JaegerLink.jsx'; import PropTypes from 'prop-types'; import React from 'react'; import SuccessRateMiniChart from './util/SuccessRateMiniChart.jsx'; @@ -110,7 +111,7 @@ const trafficSplitDetailColumns = [ }, ]; -const columnDefinitions = (resource, showNamespaceColumn, showNameColumn, PrefixedLink, isTcpTable, grafana) => { +const columnDefinitions = (resource, showNamespaceColumn, showNameColumn, PrefixedLink, isTcpTable, grafana, jaeger) => { const isAuthorityTable = resource === 'authority'; const isTrafficSplitTable = resource === 'trafficsplit'; const isMultiResourceTable = resource === 'multi_resource'; @@ -154,6 +155,26 @@ const columnDefinitions = (resource, showNamespaceColumn, showNameColumn, Prefix }, }; + + const jaegerColumn = { + title: 'Jaeger', + key: 'JaegerDashboard', + isNumeric: true, + render: row => { + if (!isAuthorityTable && (!row.added || _get(row, 'pods.totalPods') === '0')) { + return null; + } + + return ( + + ); + }, + }; + const nameColumn = { title: isMultiResourceTable ? 'Resource' : friendlyTitle(resource).singular, dataIndex: 'name', @@ -200,8 +221,13 @@ const columnDefinitions = (resource, showNamespaceColumn, showNameColumn, Prefix columns.splice(1, 0, meshedColumn); } - if (!isTrafficSplitTable && grafana !== '') { - columns = columns.concat(grafanaColumn); + if (!isTrafficSplitTable) { + if (grafana !== '') { + columns = columns.concat(grafanaColumn); + } + if (jaeger !== '') { + columns = columns.concat(jaegerColumn); + } } if (!showNamespaceColumn) { @@ -224,12 +250,12 @@ const preprocessMetrics = metrics => { return tableData; }; -const MetricsTable = ({ metrics, resource, showNamespaceColumn, showName, title, api, isTcpTable, selectedNamespace, grafana }) => { +const MetricsTable = ({ metrics, resource, showNamespaceColumn, showName, title, api, isTcpTable, selectedNamespace, grafana, jaeger }) => { const showNsColumn = resource === 'namespace' || selectedNamespace !== '_all' ? false : showNamespaceColumn; const showNameColumn = resource !== 'trafficsplit' ? true : showName; let orderBy = 'name'; if (resource === 'trafficsplit' && !showNameColumn) { orderBy = 'leaf'; } - const columns = columnDefinitions(resource, showNsColumn, showNameColumn, api.PrefixedLink, isTcpTable, grafana); + const columns = columnDefinitions(resource, showNsColumn, showNameColumn, api.PrefixedLink, isTcpTable, grafana, jaeger); const rows = preprocessMetrics(metrics); return ( ', () => { expect(table.props().tableColumns).toHaveLength(8); }); + it('render table with all columens including jaeger', () => { + let extraProps = _merge({}, defaultProps, { + metrics: [], + resource: "deployment", + showNamespaceColumn: false, + jaeger: 'jaeger.xyz' + }); + const component = mount(routerWrap(MetricsTable, extraProps)); + const table = component.find("BaseTable"); + + expect(table).toBeDefined(); + expect(table.props().tableColumns).toHaveLength(9); + }); + it('adds apex, leaf and weight columns, and omits meshed and grafana column, for a trafficsplit resource', () => { let extraProps = _merge({}, defaultProps, { metrics: [], resource: "trafficsplit"}); const component = mount(routerWrap(MetricsTable, extraProps)); diff --git a/web/app/js/components/util/SvgWrappers.jsx b/web/app/js/components/util/SvgWrappers.jsx index 36be7468f..6716bd2eb 100644 --- a/web/app/js/components/util/SvgWrappers.jsx +++ b/web/app/js/components/util/SvgWrappers.jsx @@ -36,6 +36,2595 @@ export const grafanaIcon = ( ); +export const jaegerIcon = ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + export const linkerdLogoOnly = (

Failed to call public API: {{ .ErrorMessage }}

{{ end }}