From 8a38002dd92d0c6e5f7c04a6cfb6d7f578bbc61d Mon Sep 17 00:00:00 2001 From: Sergii Kabashniuk Date: Fri, 9 Nov 2018 14:42:52 +0200 Subject: [PATCH] Basic tracing support for OpenShift (#11844) Basic tracing support for OpenShift (#11844) --- assembly/assembly-wsmaster-war/pom.xml | 20 ++ .../che/api/deploy/WsMasterModule.java | 5 +- .../che/api/deploy/WsMasterServletModule.java | 5 + core/che-core-tracing-core/pom.xml | 50 +++++ .../che/core/tracing/TracerProvider.java | 40 ++++ .../che/core/tracing/TracingModule.java | 24 +++ core/che-core-tracing-web/pom.xml | 55 +++++ .../tracing/web/TracingFilterProvider.java | 40 ++++ .../core/tracing/web/TracingWebModule.java | 27 +++ core/pom.xml | 2 + deploy/openshift/deploy_che.sh | 40 +++- deploy/openshift/ocp.sh | 5 + .../templates/che-server-template.yaml | 6 + .../templates/jaeger-all-in-one-template.yml | 190 ++++++++++++++++++ pom.xml | 10 + 15 files changed, 517 insertions(+), 2 deletions(-) create mode 100644 core/che-core-tracing-core/pom.xml create mode 100644 core/che-core-tracing-core/src/main/java/org/eclipse/che/core/tracing/TracerProvider.java create mode 100644 core/che-core-tracing-core/src/main/java/org/eclipse/che/core/tracing/TracingModule.java create mode 100644 core/che-core-tracing-web/pom.xml create mode 100644 core/che-core-tracing-web/src/main/java/org/eclipse/che/core/tracing/web/TracingFilterProvider.java create mode 100644 core/che-core-tracing-web/src/main/java/org/eclipse/che/core/tracing/web/TracingWebModule.java create mode 100644 deploy/openshift/templates/jaeger-all-in-one-template.yml diff --git a/assembly/assembly-wsmaster-war/pom.xml b/assembly/assembly-wsmaster-war/pom.xml index d25957bff1..f72e0b9325 100644 --- a/assembly/assembly-wsmaster-war/pom.xml +++ b/assembly/assembly-wsmaster-war/pom.xml @@ -59,6 +59,18 @@ com.h2database h2 + + io.jaegertracing + jaeger-client + + + io.jaegertracing + jaeger-core + + + io.jaegertracing + jaeger-tracerresolver + javax.inject javax.inject @@ -221,6 +233,14 @@ org.eclipse.che.core che-core-sql-schema + + org.eclipse.che.core + che-core-tracing-core + + + org.eclipse.che.core + che-core-tracing-web + org.eclipse.che.core wsagent diff --git a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java index 76ea8b1c4b..97a43311a3 100644 --- a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java +++ b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java @@ -271,8 +271,11 @@ public class WsMasterModule extends AbstractModule { } bind(org.eclipse.che.api.user.server.AppStatesPreferenceCleaner.class); - MapBinder.newMapBinder(binder(), String.class, ChePluginsApplier.class); + + if (Boolean.valueOf(System.getenv("CHE_TRACING_ENABLED"))) { + install(new org.eclipse.che.core.tracing.TracingModule()); + } } private void configureSingleUserMode(Map persistenceProperties) { diff --git a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterServletModule.java b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterServletModule.java index cd537a9381..bbf270e224 100644 --- a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterServletModule.java +++ b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterServletModule.java @@ -27,6 +27,11 @@ import org.everrest.guice.servlet.GuiceEverrestServlet; public class WsMasterServletModule extends ServletModule { @Override protected void configureServlets() { + + if (Boolean.valueOf(System.getenv("CHE_TRACING_ENABLED"))) { + install(new org.eclipse.che.core.tracing.web.TracingWebModule()); + } + final Map corsFilterParams = new HashMap<>(); corsFilterParams.put("cors.allowed.origins", "*"); corsFilterParams.put( diff --git a/core/che-core-tracing-core/pom.xml b/core/che-core-tracing-core/pom.xml new file mode 100644 index 0000000000..21a036a779 --- /dev/null +++ b/core/che-core-tracing-core/pom.xml @@ -0,0 +1,50 @@ + + + + 4.0.0 + + che-core-parent + org.eclipse.che.core + 6.14.0-SNAPSHOT + + che-core-tracing-core + Che Core :: Tracing :: Core + + + com.google.guava + guava + + + com.google.inject + guice + + + io.opentracing + opentracing-api + + + io.opentracing + opentracing-util + + + io.opentracing.contrib + opentracing-tracerresolver + + + javax.inject + javax.inject + + + diff --git a/core/che-core-tracing-core/src/main/java/org/eclipse/che/core/tracing/TracerProvider.java b/core/che-core-tracing-core/src/main/java/org/eclipse/che/core/tracing/TracerProvider.java new file mode 100644 index 0000000000..e997823c40 --- /dev/null +++ b/core/che-core-tracing-core/src/main/java/org/eclipse/che/core/tracing/TracerProvider.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.core.tracing; + +import com.google.common.annotations.Beta; +import io.opentracing.Tracer; +import io.opentracing.contrib.tracerresolver.TracerResolver; +import io.opentracing.util.GlobalTracer; +import javax.inject.Provider; +import javax.inject.Singleton; + +/** + * Guice @{@link javax.inject.Provider} of @{@link io.opentracing.Tracer} objects. Register Tracer + * in @{@link io.opentracing.util.GlobalTracer} for future use by classes that has no access to + * container like datasources, etc. + */ +@Beta +@Singleton +public class TracerProvider implements Provider { + private final Tracer tracer; + + public TracerProvider() { + this.tracer = TracerResolver.resolveTracer(); + GlobalTracer.register(tracer); + } + + @Override + public Tracer get() { + return tracer; + } +} diff --git a/core/che-core-tracing-core/src/main/java/org/eclipse/che/core/tracing/TracingModule.java b/core/che-core-tracing-core/src/main/java/org/eclipse/che/core/tracing/TracingModule.java new file mode 100644 index 0000000000..2072437616 --- /dev/null +++ b/core/che-core-tracing-core/src/main/java/org/eclipse/che/core/tracing/TracingModule.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.core.tracing; + +import com.google.common.annotations.Beta; +import com.google.inject.AbstractModule; +import io.opentracing.Tracer; + +@Beta +public class TracingModule extends AbstractModule { + @Override + protected void configure() { + bind(Tracer.class).toProvider(TracerProvider.class); + } +} diff --git a/core/che-core-tracing-web/pom.xml b/core/che-core-tracing-web/pom.xml new file mode 100644 index 0000000000..f9e0024d90 --- /dev/null +++ b/core/che-core-tracing-web/pom.xml @@ -0,0 +1,55 @@ + + + + 4.0.0 + + che-core-parent + org.eclipse.che.core + 6.14.0-SNAPSHOT + + che-core-tracing-web + Che Core :: Tracing :: Web + + + com.google.guava + guava + + + com.google.inject + guice + + + com.google.inject.extensions + guice-servlet + + + io.opentracing + opentracing-api + + + io.opentracing.contrib + opentracing-web-servlet-filter + + + javax.inject + javax.inject + + + javax.servlet + javax.servlet-api + provided + + + diff --git a/core/che-core-tracing-web/src/main/java/org/eclipse/che/core/tracing/web/TracingFilterProvider.java b/core/che-core-tracing-web/src/main/java/org/eclipse/che/core/tracing/web/TracingFilterProvider.java new file mode 100644 index 0000000000..f12fa93ebe --- /dev/null +++ b/core/che-core-tracing-web/src/main/java/org/eclipse/che/core/tracing/web/TracingFilterProvider.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.core.tracing.web; + +import com.google.common.annotations.Beta; +import io.opentracing.Tracer; +import io.opentracing.contrib.web.servlet.filter.TracingFilter; +import javax.inject.Inject; +import javax.inject.Provider; +import javax.inject.Singleton; + +/** + * Guice @{@link javax.inject.Provider} of @{@link + * io.opentracing.contrib.web.servlet.filter.TracingFilter} objects + */ +@Beta +@Singleton +public class TracingFilterProvider implements Provider { + + private final TracingFilter filter; + + @Inject + public TracingFilterProvider(Tracer tracer) { + filter = new TracingFilter(tracer); + } + + @Override + public TracingFilter get() { + return filter; + } +} diff --git a/core/che-core-tracing-web/src/main/java/org/eclipse/che/core/tracing/web/TracingWebModule.java b/core/che-core-tracing-web/src/main/java/org/eclipse/che/core/tracing/web/TracingWebModule.java new file mode 100644 index 0000000000..416994f23d --- /dev/null +++ b/core/che-core-tracing-web/src/main/java/org/eclipse/che/core/tracing/web/TracingWebModule.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.che.core.tracing.web; + +import com.google.common.annotations.Beta; +import com.google.inject.servlet.ServletModule; +import io.opentracing.contrib.web.servlet.filter.TracingFilter; +import javax.inject.Singleton; + +@Beta +public class TracingWebModule extends ServletModule { + @Override + protected void configureServlets() { + // tracing + bind(TracingFilter.class).toProvider(TracingFilterProvider.class).in(Singleton.class); + filter("/*").through(TracingFilter.class); + } +} diff --git a/core/pom.xml b/core/pom.xml index bb82221c72..d8f3e4b693 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -38,5 +38,7 @@ che-core-db-vendor-h2 che-core-db-vendor-mysql che-core-db-vendor-postgresql + che-core-tracing-core + che-core-tracing-web diff --git a/deploy/openshift/deploy_che.sh b/deploy/openshift/deploy_che.sh index 1dc44ca6d2..159706e2bb 100755 --- a/deploy/openshift/deploy_che.sh +++ b/deploy/openshift/deploy_che.sh @@ -161,6 +161,28 @@ export PLUGIN_REGISTRY_IMAGE_PULL_POLICY=${PLUGIN_REGISTRY_IMAGE_PULL_POLICY:-${ DEFAULT_PLUGIN__REGISTRY__URL="https://che-plugin-registry.openshift.io" export PLUGIN__REGISTRY__URL=${PLUGIN__REGISTRY__URL:-${DEFAULT_PLUGIN__REGISTRY__URL}} +DEFAULT_CHE_TRACING_ENABLED="false" +export CHE_TRACING_ENABLED=${CHE_TRACING_ENABLED:-${DEFAULT_CHE_TRACING_ENABLED}} + +DEFAULT_JAEGER_ENDPOINT="http://jaeger-collector:14268/api/traces" +export JAEGER_ENDPOINT=${JAEGER_ENDPOINT:-${DEFAULT_JAEGER_ENDPOINT}} + +DEFAULT_JAEGER_SERVICE_NAME="che-server" +export JAEGER_SERVICE_NAME=${JAEGER_SERVICE_NAME:-${DEFAULT_JAEGER_SERVICE_NAME}} + +DEFAULT_JAEGER_SAMPLER_MANAGER_HOST_PORT="jaeger:5778" +export JAEGER_SAMPLER_MANAGER_HOST_PORT=${JAEGER_SAMPLER_MANAGER_HOST_PORT:-${DEFAULT_JAEGER_SAMPLER_MANAGER_HOST_PORT}} + +DEFAULT_JAEGER_SAMPLER_TYPE="const" +export JAEGER_SAMPLER_TYPE=${JAEGER_SAMPLER_TYPE:-${DEFAULT_JAEGER_SAMPLER_TYPE}} + +DEFAULT_JAEGER_SAMPLER_PARAM="1" +export JAEGER_SAMPLER_PARAM=${JAEGER_SAMPLER_PARAM:-${DEFAULT_JAEGER_SAMPLER_PARAM}} + +DEFAULT_JAEGER_REPORTER_MAX_QUEUE_SIZE="10000" +export JAEGER_REPORTER_MAX_QUEUE_SIZE=${JAEGER_REPORTER_MAX_QUEUE_SIZE:-${DEFAULT_JAEGER_REPORTER_MAX_QUEUE_SIZE}} + + if [ "${ENABLE_SSL}" == "true" ]; then HTTP_PROTOCOL="https" WS_PROTOCOL="wss" @@ -375,9 +397,22 @@ if [ "${DEPLOY_CHE_PLUGIN_REGISTRY}" == "true" ]; then fi } +deployJaeger(){ + if [ "${CHE_TRACING_ENABLED}" == "true" ]; then + echo "Deploying Jaeger..." + ${OC_BINARY} new-app -f ${BASE_DIR}/templates/jaeger-all-in-one-template.yml + JAEGER_ROUTE=$($OC_BINARY get route/jaeger-query --namespace=${CHE_OPENSHIFT_PROJECT} -o=jsonpath={'.spec.host'}) + echo "Jaeger deployment complete. $JAEGER_ROUTE" + fi +} + deployChe() { - CHE_VAR_ARRAY=$(env | grep "^CHE_.") + if [ "${CHE_TRACING_ENABLED}" == "true" ]; then + CHE_VAR_ARRAY=$(env | grep -e "^CHE_." -e "^JAEGER_.") + else + CHE_VAR_ARRAY=$(env | grep "^CHE_.") + fi if [ ${#CHE_VAR_ARRAY[@]} -gt 0 ]; then ENV="-e ${CHE_VAR_ARRAY}" fi @@ -390,6 +425,7 @@ Image: ${CHE_IMAGE_REPO} Pull policy: ${IMAGE_PULL_POLICY} Update strategy: ${UPDATE_STRATEGY} Setup OpenShift oAuth: ${SETUP_OCP_OAUTH} +Enable Jaeger based tracing: ${CHE_TRACING_ENABLED} Environment variables: ${CHE_VAR_ARRAY}" CHE_INFRA_OPENSHIFT_PROJECT=${CHE_OPENSHIFT_PROJECT} @@ -477,6 +513,7 @@ ${CHE_VAR_ARRAY}" -p TLS=${TLS} \ -p CHE_WORKSPACE_PLUGIN__REGISTRY__URL=${PLUGIN__REGISTRY__URL} \ -p CHE_INFRA_KUBERNETES_SERVICE__ACCOUNT__NAME=${WORKSPACE_SERVICE_ACCOUNT_NAME} \ + -p CHE_TRACING_ENABLED=${CHE_TRACING_ENABLED} \ ${ENV} if [ ${UPDATE_STRATEGY} == "Recreate" ]; then @@ -503,4 +540,5 @@ isLoggedIn createNewProject getRoutingSuffix deployChePluginRegistry +deployJaeger deployChe diff --git a/deploy/openshift/ocp.sh b/deploy/openshift/ocp.sh index f6a05a513e..60e7b4a0b7 100755 --- a/deploy/openshift/ocp.sh +++ b/deploy/openshift/ocp.sh @@ -261,6 +261,7 @@ parse_args() { --remove-che - remove existing che project --setup-ocp-oauth - register OCP oauth client and setup Keycloak and Che to use OpenShift Identity Provider --deploy-che-plugin-registry - deploy Che plugin registry + --enable-tracing - Enable tracing and deploy Jaeger =================================== ENV vars CHE_IMAGE_TAG - set che-server image tag, default: nightly @@ -354,6 +355,10 @@ parse_args() { export DEPLOY_CHE_PLUGIN_REGISTRY=true shift ;; + --enable-tracing) + export CHE_TRACING_ENABLED=true + shift + ;; *) echo "You've passed wrong arg '$i'." echo -e "$HELP" diff --git a/deploy/openshift/templates/che-server-template.yaml b/deploy/openshift/templates/che-server-template.yaml index 4d63b94622..649257cd08 100644 --- a/deploy/openshift/templates/che-server-template.yaml +++ b/deploy/openshift/templates/che-server-template.yaml @@ -151,6 +151,8 @@ objects: optional: true - name: CHE_WORKSPACE_PLUGIN__REGISTRY__URL value: "${CHE_WORKSPACE_PLUGIN__REGISTRY__URL}" + - name: CHE_TRACING_ENABLED + value: "${CHE_TRACING_ENABLED}" image: ${IMAGE_CHE}:${CHE_VERSION} imagePullPolicy: "${PULL_POLICY}" livenessProbe: @@ -292,6 +294,10 @@ parameters: displayName: Plugin sidecar default memory limit description: Plugin sidecar default memory limit in megabytes value: '128' +- name: CHE_TRACING_ENABLED + displayName: Eclipse Che tracing + description: Enable or disable tracing in Eclipse Che + value: 'false' labels: app: che template: che diff --git a/deploy/openshift/templates/jaeger-all-in-one-template.yml b/deploy/openshift/templates/jaeger-all-in-one-template.yml new file mode 100644 index 0000000000..ad85fad2ea --- /dev/null +++ b/deploy/openshift/templates/jaeger-all-in-one-template.yml @@ -0,0 +1,190 @@ +# +# Copyright 2017-2018 The Jaeger Authors +# +# Licensed 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. +# + +parameters: +- description: The name of the Jaeger Service. + displayName: Jaeger Service Name + name: JAEGER_SERVICE_NAME + required: true + value: jaeger +- description: The Jaeger image version to use + displayName: Image version + name: IMAGE_VERSION + required: false + value: "latest" +- description: The name of the Jaeger Zipkin Service. + displayName: Jaeger Zipkin Service Name + name: JAEGER_ZIPKIN_SERVICE_NAME + required: true + value: zipkin + +apiVersion: v1 +kind: Template +labels: + template: jaeger-template-all-in-one + jaeger-infra: template-all-in-one +metadata: + name: jaeger-template-all-in-one + annotations: + description: Jaeger Distributed Tracing Server (all-in-one) + iconClass: icon-go-gopher + openshift.io/display-name: Jaeger (all-in-one) + tags: instant-app,tracing,opentracing,jaeger + labels: + name: jaeger-infra + jaeger-infra: jaeger-template-all-in-one +objects: +- apiVersion: extensions/v1beta1 + kind: Deployment + metadata: + name: ${JAEGER_SERVICE_NAME} + labels: + app: jaeger + jaeger-infra: jaeger-deployment + spec: + replicas: 1 + strategy: + type: Recreate + template: + metadata: + labels: + app: jaeger + jaeger-infra: jaeger-pod + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "16686" + spec: + containers: + - env: + - name: COLLECTOR_ZIPKIN_HTTP_PORT + value: "9411" + image: jaegertracing/all-in-one:${IMAGE_VERSION} + name: ${JAEGER_SERVICE_NAME} + ports: + - containerPort: 5775 + protocol: UDP + - containerPort: 6831 + protocol: UDP + - containerPort: 6832 + protocol: UDP + - containerPort: 16686 + protocol: TCP + - containerPort: 9411 + protocol: TCP + - containerPort: 5778 + protocol: TCP + readinessProbe: + httpGet: + path: "/" + port: 14269 + initialDelaySeconds: 5 +- apiVersion: v1 + kind: Service + metadata: + name: ${JAEGER_SERVICE_NAME}-query + labels: + app: jaeger + jaeger-infra: jaeger-service + spec: + ports: + - name: query-http + port: 80 + protocol: TCP + targetPort: 16686 + selector: + jaeger-infra: jaeger-pod + type: LoadBalancer +- apiVersion: v1 + kind: Service + metadata: + name: ${JAEGER_SERVICE_NAME}-collector + labels: + app: jaeger + jaeger-infra: collector-service + spec: + ports: + - name: jaeger-collector-tchannel + port: 14267 + protocol: TCP + targetPort: 14267 + - name: jaeger-collector-http + port: 14268 + protocol: TCP + targetPort: 14268 + - name: jaeger-collector-zipkin + port: 9411 + protocol: TCP + targetPort: 9411 + selector: + jaeger-infra: jaeger-pod + type: ClusterIP +- apiVersion: v1 + kind: Service + metadata: + name: ${JAEGER_SERVICE_NAME}-agent + labels: + app: jaeger + jaeger-infra: agent-service + spec: + ports: + - name: agent-zipkin-thrift + port: 5775 + protocol: UDP + targetPort: 5775 + - name: agent-compact + port: 6831 + protocol: UDP + targetPort: 6831 + - name: agent-binary + port: 6832 + protocol: UDP + targetPort: 6832 + - name: agent-sampler-manager + port: 5778 + protocol: TCP + targetPort: 5778 + clusterIP: None + selector: + jaeger-infra: jaeger-pod +- apiVersion: v1 + kind: Service + metadata: + name: ${JAEGER_ZIPKIN_SERVICE_NAME} + labels: + app: jaeger + jaeger-infra: zipkin-service + spec: + ports: + - name: jaeger-zipkin-http + port: 9411 + protocol: TCP + targetPort: 9411 + selector: + jaeger-infra: jaeger-pod + type: ClusterIP +- apiVersion: v1 + kind: Route + metadata: + name: ${JAEGER_SERVICE_NAME}-query + labels: + jaeger-infra: query-route + spec: + to: + kind: Service + name: ${JAEGER_SERVICE_NAME}-query + port: + targetPort: query-http + tls: + termination: edge + insecureEdgeTerminationPolicy: Allow diff --git a/pom.xml b/pom.xml index 20e74e9d29..5f2b30fbcd 100644 --- a/pom.xml +++ b/pom.xml @@ -754,6 +754,16 @@ che-core-sql-schema ${che.version} + + org.eclipse.che.core + che-core-tracing-core + ${che.version} + + + org.eclipse.che.core + che-core-tracing-web + ${che.version} + org.eclipse.che.core che-core-workspace-activity-server