chore: Removed manipulation for custom traceparent header (#37121)
This commit is contained in:
parent
d6305bad82
commit
e7e3d5e002
|
|
@ -16,7 +16,7 @@ const provider = new NodeTracerProvider({
|
|||
resource: new Resource({
|
||||
[ATTR_DEPLOYMENT_NAME]: `${process.env.APPSMITH_DEPLOYMENT_NAME || "self-hosted"}`,
|
||||
[ATTR_SERVICE_INSTANCE_ID]: `${process.env.HOSTNAME || "appsmith-0"}`,
|
||||
[ATTR_SERVICE_NAME]: "rts",
|
||||
[ATTR_SERVICE_NAME]: "appsmith-rts",
|
||||
}),
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ export const getAppsmithConfigs = (): AppsmithUIConfigs => {
|
|||
observability: {
|
||||
deploymentName: observabilityDeploymentName.value,
|
||||
serviceInstanceId: observabilityServiceInstanceId.value,
|
||||
serviceName: "frontend",
|
||||
serviceName: "appsmith-client",
|
||||
},
|
||||
fusioncharts: {
|
||||
enabled: fusioncharts.enabled,
|
||||
|
|
|
|||
|
|
@ -7,5 +7,6 @@ public class MDCConstants {
|
|||
public static final String THREAD = "thread";
|
||||
public static final String OBSERVATION = "micrometer.observation";
|
||||
public static final String TRACE_ID = "traceId";
|
||||
public static final String TRACE_PARENT = "traceparent";
|
||||
public static final String SPAN_ID = "spanId";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,5 +15,5 @@ import java.lang.annotation.Target;
|
|||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@ConditionalOnExpression("${appsmith.micrometer.metrics.enabled}")
|
||||
@ConditionalOnExpression("${appsmith.observability.metrics.enabled}")
|
||||
public @interface ConditionalOnMicrometerMetricsEnabled {}
|
||||
|
|
|
|||
|
|
@ -64,13 +64,13 @@ public class CommonConfig {
|
|||
@Value("${disable.telemetry:true}")
|
||||
private boolean isTelemetryDisabled;
|
||||
|
||||
@Value("${appsmith.micrometer.tracing.detail.enabled:false}")
|
||||
@Value("${appsmith.observability.tracing.detail.enabled:false}")
|
||||
private boolean tracingDetail;
|
||||
|
||||
@Value("${appsmith.micrometer.metrics.detail.enabled:false}")
|
||||
@Value("${appsmith.observability.metrics.detail.enabled:false}")
|
||||
private boolean metricsDetail;
|
||||
|
||||
@Value("${appsmith.micrometer.metrics.interval.millis:60000}")
|
||||
@Value("${appsmith.observability.metrics.interval.millis:60000}")
|
||||
private int metricsIntervalMillis;
|
||||
|
||||
private List<String> allowedDomains;
|
||||
|
|
|
|||
|
|
@ -33,20 +33,21 @@ public class MetricsConfig {
|
|||
|
||||
public static final String NEW_RELIC_MICROMETER_METRICS_ENDPOINT = "https://otlp.nr-data.net:4317";
|
||||
public static final String API_KEY = "api-key";
|
||||
public static final String CONTAINER_NAME_KEY = "container.name";
|
||||
|
||||
public static final String DEPLOYMENT_NAME_KEY = "deployment.name";
|
||||
public static final String SERVICE_INSTANCE_ID_KEY = "service.instance.id";
|
||||
public static final String SERVICE_NAME_KEY = "service.name";
|
||||
public static final String SERVICE_NAME = "appsmith-server";
|
||||
public static final String INSTRUMENTATION_PROVIDER_KEY = "instrumentation.provider";
|
||||
public static final String MICROMETER = "micrometer";
|
||||
|
||||
@Value("${appsmith.newrelic.micrometer.metrics.application.name}")
|
||||
private String newRelicApplicationName;
|
||||
|
||||
@Value("${appsmith.newrelic.licensekey}")
|
||||
private String newRelicKey;
|
||||
|
||||
@Value("${appsmith.newrelic.micrometer.metrics.container.name}")
|
||||
private String newRelicContainerName;
|
||||
@Value("${appsmith.observability.deployment.name}")
|
||||
private String deploymentName;
|
||||
|
||||
@Value("${appsmith.observability.service.instance.id}")
|
||||
private String serviceInstanceId;
|
||||
|
||||
private final CommonConfig commonConfig;
|
||||
|
||||
|
|
@ -68,11 +69,12 @@ public class MetricsConfig {
|
|||
return OpenTelemetrySdk.builder()
|
||||
.setMeterProvider(SdkMeterProvider.builder()
|
||||
.setResource(Resource.getDefault().toBuilder()
|
||||
.put(SERVICE_NAME_KEY, newRelicApplicationName)
|
||||
.put(DEPLOYMENT_NAME_KEY, deploymentName)
|
||||
.put(SERVICE_NAME_KEY, SERVICE_NAME)
|
||||
// Include instrumentation.provider=micrometer to enable micrometer metrics
|
||||
// experience in New Relic
|
||||
.put(INSTRUMENTATION_PROVIDER_KEY, MICROMETER)
|
||||
.put(CONTAINER_NAME_KEY, newRelicContainerName)
|
||||
.put(SERVICE_INSTANCE_ID_KEY, serviceInstanceId)
|
||||
.build())
|
||||
.registerMetricReader(PeriodicMetricReader.builder(OtlpGrpcMetricExporter.builder()
|
||||
.setEndpoint(NEW_RELIC_MICROMETER_METRICS_ENDPOINT)
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
package com.appsmith.server.configurations;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import static org.springframework.util.CollectionUtils.isEmpty;
|
||||
|
||||
/**
|
||||
* This webfilter copies the value of traceparent-otlp header into traceparent header. This is required because at
|
||||
* the moment the client application has two different services that creates traces and sends to the NewRelic server
|
||||
* - one that gathers web vitals information like LCP, FCP etc. and another one that creates user defined traces. They
|
||||
* both have different traceparent header and hence to overcome this conflict of headers the client has copied the
|
||||
* user defined trace header into traceparent-otlp. However, Micrometer expects the traceparent information to be
|
||||
* present in the traceparent header - hence this method copies the correct header data into traceparent header
|
||||
* before it gets set into Micrometer context.
|
||||
* In cases where traceparent-otlp header is not present but the traceparent header is present, this method removes
|
||||
* the traceparent header because if it is present then the Micrometer trace would use its value for trace id (which
|
||||
* is incorrect).
|
||||
* As per measurement on my local setup this webFilter generally takes around 0.5 milliseconds to complete hence should
|
||||
* not have any practical impact on response times.
|
||||
*/
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
@Component
|
||||
public class MicrometerTraceHeaderWebFilter implements WebFilter {
|
||||
|
||||
public static final String TRACEPARENT_OTLP_HEADER_KEY = "traceparent-otlp";
|
||||
public static final String TRACEPARENT_HEADER_KEY = "traceparent";
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
|
||||
HttpHeaders requestHeaders = serverWebExchange.getRequest().getHeaders();
|
||||
|
||||
if (isTraceparentOtlpHeaderPresent(requestHeaders)) {
|
||||
ServerHttpRequest newRequest = serverWebExchange
|
||||
.getRequest()
|
||||
.mutate()
|
||||
.header(
|
||||
TRACEPARENT_HEADER_KEY,
|
||||
requestHeaders.get(TRACEPARENT_OTLP_HEADER_KEY).get(0))
|
||||
.build();
|
||||
ServerWebExchange newExchange =
|
||||
serverWebExchange.mutate().request(newRequest).build();
|
||||
|
||||
return webFilterChain.filter(newExchange);
|
||||
} else if (isTraceparentHeaderPresent(requestHeaders)) {
|
||||
ServerHttpRequest newRequest = serverWebExchange
|
||||
.getRequest()
|
||||
.mutate()
|
||||
.headers((httpHeader) -> {
|
||||
httpHeader.remove(TRACEPARENT_HEADER_KEY);
|
||||
})
|
||||
.build();
|
||||
ServerWebExchange newExchange =
|
||||
serverWebExchange.mutate().request(newRequest).build();
|
||||
|
||||
return webFilterChain.filter(newExchange);
|
||||
}
|
||||
|
||||
return webFilterChain.filter(serverWebExchange);
|
||||
}
|
||||
|
||||
private boolean isTraceparentHeaderPresent(HttpHeaders requestHeaders) {
|
||||
return requestHeaders != null
|
||||
&& requestHeaders.containsKey(TRACEPARENT_HEADER_KEY)
|
||||
&& !isEmpty(requestHeaders.get(TRACEPARENT_HEADER_KEY));
|
||||
}
|
||||
|
||||
private boolean isTraceparentOtlpHeaderPresent(HttpHeaders requestHeaders) {
|
||||
return requestHeaders != null && requestHeaders.containsKey(TRACEPARENT_OTLP_HEADER_KEY);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,16 +3,10 @@ package com.appsmith.server.configurations;
|
|||
import io.micrometer.observation.Observation;
|
||||
import io.micrometer.observation.ObservationPredicate;
|
||||
import io.micrometer.observation.ObservationView;
|
||||
import io.micrometer.tracing.Span;
|
||||
import io.micrometer.tracing.exporter.SpanExportingPredicate;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.server.reactive.observation.ServerRequestObservationContext;
|
||||
|
||||
import static com.appsmith.external.constants.spans.BaseSpan.APPSMITH_SPAN_PREFIX;
|
||||
import static com.appsmith.external.constants.spans.BaseSpan.AUTHENTICATE;
|
||||
import static com.appsmith.external.constants.spans.BaseSpan.AUTHORIZE;
|
||||
|
||||
/**
|
||||
* This configuration file creates beans that are required to filter just Appsmith specific spans
|
||||
*/
|
||||
|
|
@ -42,19 +36,4 @@ public class TracingConfig {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
SpanExportingPredicate onlyAppsmithSpans() {
|
||||
return (finishedSpan) -> {
|
||||
if ((finishedSpan.getKind() != null && finishedSpan.getKind().equals(Span.Kind.SERVER))
|
||||
|| finishedSpan.getName().startsWith(APPSMITH_SPAN_PREFIX)
|
||||
|| finishedSpan.getName().startsWith(AUTHENTICATE)
|
||||
|| finishedSpan.getName().startsWith(AUTHORIZE)) {
|
||||
// A span is either an http server request root or Appsmith specific or login related or signup related
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.appsmith.server.helpers;
|
||||
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.NonNull;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
|
@ -24,6 +25,8 @@ import static org.apache.commons.lang3.StringUtils.isEmpty;
|
|||
@Component
|
||||
public class RTSCaller {
|
||||
|
||||
private final ObservationRegistry observationRegistry;
|
||||
|
||||
private WebClient webClient;
|
||||
|
||||
@Value("${appsmith.rts.port:}")
|
||||
|
|
@ -31,6 +34,10 @@ public class RTSCaller {
|
|||
|
||||
private static final int MAX_IN_MEMORY_SIZE_IN_BYTES = 16 * 1024 * 1024;
|
||||
|
||||
public RTSCaller(ObservationRegistry observationRegistry) {
|
||||
this.observationRegistry = observationRegistry;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
private void makeWebClient() {
|
||||
if (isEmpty(rtsPort)) {
|
||||
|
|
@ -53,6 +60,7 @@ public class RTSCaller {
|
|||
.build())
|
||||
.clientConnector(new ReactorClientHttpConnector(HttpClient.create(connectionProvider)))
|
||||
.baseUrl("http://127.0.0.1:" + rtsPort)
|
||||
.observationRegistry(observationRegistry)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
spring.application.name=appsmith-server
|
||||
server.port=${PORT:8080}
|
||||
# Allow the Spring context to close all active requests before shutting down the server
|
||||
# Please ref: https://docs.spring.io/spring-boot/docs/2.3.0.RELEASE/reference/html/spring-boot-features.html#boot-features-graceful-shutdown
|
||||
|
|
@ -95,6 +96,16 @@ management.tracing.sampling.probability=${APPSMITH_SAMPLING_PROBABILITY:0.1}
|
|||
management.prometheus.metrics.export.descriptions=true
|
||||
management.metrics.distribution.percentiles-histogram.http.server.requests=true
|
||||
|
||||
# Observability and Micrometer related configs
|
||||
# Keeping this license key around, until later
|
||||
appsmith.newrelic.licensekey=${APPSMITH_NEW_RELIC_OTLP_LICENSE_KEY:}
|
||||
appsmith.observability.deployment.name=${APPSMITH_DEPLOYMENT_NAME:self-hosted}
|
||||
appsmith.observability.service.instance.id=${HOSTNAME:appsmith-0}
|
||||
appsmith.observability.metrics.enabled=${APPSMITH_MICROMETER_METRICS_ENABLED:false}
|
||||
appsmith.observability.tracing.detail.enabled=${APPSMITH_ENABLE_TRACING_DETAIL:false}
|
||||
appsmith.observability.metrics.detail.enabled=${APPSMITH_ENABLE_METRICS_DETAIL:false}
|
||||
appsmith.observability.metrics.interval.millis=${APPSMITH_METRICS_INTERVAL_MILLIS:60000}
|
||||
|
||||
# Support disabling signup with an environment variable
|
||||
signup.disabled = ${APPSMITH_SIGNUP_DISABLED:false}
|
||||
signup.allowed-domains=${APPSMITH_SIGNUP_ALLOWED_DOMAINS:}
|
||||
|
|
@ -117,15 +128,5 @@ appsmith.internal.password=${APPSMITH_INTERNAL_PASSWORD:}
|
|||
# GIT stale index.lock file valid time
|
||||
appsmith.index.lock.file.time=${APPSMITH_INDEX_LOCK_FILE_TIME:300}
|
||||
|
||||
# NewRelic and Micrometer related configs
|
||||
appsmith.newrelic.licensekey=${APPSMITH_NEW_RELIC_OTLP_LICENSE_KEY:}
|
||||
appsmith.newrelic.micrometer.metrics.container.name=${NEW_RELIC_METADATA_KUBERNETES_POD_NAME:appsmith-0}
|
||||
appsmith.newrelic.micrometer.metrics.application.name=${APPSMITH_NEWRELIC_MICROMETER_SERVICE_NAME:}
|
||||
spring.application.name=${OTEL_SERVICE_NAME:appsmith-anonymous}
|
||||
appsmith.micrometer.metrics.enabled=${APPSMITH_MICROMETER_METRICS_ENABLED:false}
|
||||
appsmith.micrometer.tracing.detail.enabled=${APPSMITH_ENABLE_TRACING_DETAIL:false}
|
||||
appsmith.micrometer.metrics.detail.enabled=${APPSMITH_ENABLE_METRICS_DETAIL:false}
|
||||
appsmith.micrometer.metrics.interval.millis=${APPSMITH_METRICS_INTERVAL_MILLIS:60000}
|
||||
|
||||
springdoc.api-docs.path=/v3/docs
|
||||
springdoc.swagger-ui.path=/v3/swagger
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user