a66bc062ad4b888290eeec7037092e585f706c50
[ccsdk/oran.git] /
1 /*-
2  * ========================LICENSE_START=================================
3  * ONAP : ccsdk oran
4  * ======================================================================
5  * Copyright (C) 2024 OpenInfra Foundation Europe. All rights reserved.
6  * ======================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ========================LICENSE_END===================================
19  */
20 package org.onap.ccsdk.oran.a1policymanagementservice.configuration;
21
22 import io.micrometer.observation.ObservationPredicate;
23 import io.micrometer.observation.ObservationRegistry;
24 import io.opentelemetry.api.OpenTelemetry;
25 import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
26 import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
27 import io.opentelemetry.instrumentation.spring.webflux.v5_3.SpringWebfluxTelemetry;
28 import io.opentelemetry.sdk.extension.trace.jaeger.sampler.JaegerRemoteSampler;
29 import io.opentelemetry.sdk.trace.samplers.Sampler;
30 import lombok.Getter;
31 import reactor.core.publisher.Hooks;
32
33 import java.time.Duration;
34
35 import javax.annotation.PostConstruct;
36
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39 import org.springframework.beans.factory.annotation.Value;
40 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
41 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
42 import org.springframework.context.annotation.Bean;
43 import org.springframework.context.annotation.ComponentScan;
44 import org.springframework.context.annotation.Configuration;
45 import org.springframework.http.server.observation.ServerRequestObservationContext;
46 import org.springframework.boot.actuate.autoconfigure.observation.ObservationRegistryCustomizer;
47 import org.springframework.util.AntPathMatcher;
48 import org.springframework.util.PathMatcher;
49
50 @Configuration
51 @ComponentScan(basePackages = {"org.onap.ccsdk.oran.a1policymanagementservice"})
52 public class OtelConfig {
53     private static final Logger logger = LoggerFactory.getLogger(OtelConfig.class);
54
55     public static final int JAEGER_REMOTE_SAMPLER_POLLING_INTERVAL_IN_SECOND = 30;
56
57     @Value("${spring.application.name}")
58     private String serviceId;
59
60     @Value("${management.tracing.exporter.endpoint}")
61     private String tracingExporterEndpointUrl;
62
63     @Value("${management.tracing.sampler.jaeger-remote.endpoint}")
64     private String jaegerRemoteSamplerUrl;
65
66     @Value("${management.tracing.exporter.protocol}")
67     private String tracingProtocol;
68
69     @Getter
70     @Value("${management.tracing.enabled}")
71     private boolean tracingEnabled;
72
73     @PostConstruct
74     public void checkTracingConfig() {
75         logger.info("Application Yaml Tracing Enabled: " + tracingEnabled);
76     }
77
78     @Bean
79     @ConditionalOnProperty(prefix = "management.tracing", name = "enabled", havingValue = "true", matchIfMissing = false)
80     @ConditionalOnExpression("'grpc'.equals('${management.tracing.exporter.protocol}')")
81     public OtlpGrpcSpanExporter otlpExporterGrpc() {
82         return OtlpGrpcSpanExporter.builder().setEndpoint(tracingExporterEndpointUrl).build();
83     }
84
85     @Bean
86     @ConditionalOnProperty(prefix = "management.tracing", name = "enabled", havingValue = "true", matchIfMissing = false)
87     @ConditionalOnExpression("'http'.equals('${management.tracing.exporter.protocol}')")
88     public OtlpHttpSpanExporter otlpExporterHttp() {
89         return OtlpHttpSpanExporter.builder().setEndpoint(tracingExporterEndpointUrl).build();
90     }
91
92     @Bean
93     @ConditionalOnProperty(prefix = "management.tracing", name = "enabled", havingValue = "true", matchIfMissing = false)
94     public JaegerRemoteSampler jaegerRemoteSampler() {
95         return JaegerRemoteSampler.builder().setEndpoint(jaegerRemoteSamplerUrl)
96                 .setPollingInterval(Duration.ofSeconds(JAEGER_REMOTE_SAMPLER_POLLING_INTERVAL_IN_SECOND))
97                 .setInitialSampler(Sampler.alwaysOff()).setServiceName(serviceId).build();
98     }
99
100     @Bean
101     @ConditionalOnProperty(prefix = "management.tracing", name = "enabled", havingValue = "true", matchIfMissing = false)
102     public SpringWebfluxTelemetry webfluxTelemetry (OpenTelemetry openTelemetry) {
103         //enables automatic context propagation to ThreadLocals used by FLUX and MONO operators
104         Hooks.enableAutomaticContextPropagation();
105         return SpringWebfluxTelemetry.builder(openTelemetry).build();
106     }
107
108     @Bean
109     @ConditionalOnProperty(prefix = "management.tracing", name = "enabled", havingValue = "true", matchIfMissing = false)
110     ObservationRegistryCustomizer<ObservationRegistry> skipActuatorEndpointsFromObservation() {
111         PathMatcher pathMatcher = new AntPathMatcher("/");
112         return registry ->
113             registry.observationConfig().observationPredicate(observationPredicate(pathMatcher));
114     }
115
116     static ObservationPredicate observationPredicate(PathMatcher pathMatcher) {
117         return (name, context) -> {
118             if (context instanceof ServerRequestObservationContext observationContext) {
119                 return !pathMatcher.match("/actuator/**", observationContext.getCarrier().getRequestURI());
120             } else {
121                 return false;
122             }
123         };
124     }
125 }