cac032087e774753c36df23cb81b723dfc00dd1f
[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
31 import java.time.Duration;
32 import javax.annotation.PostConstruct;
33
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36 import org.springframework.beans.factory.annotation.Value;
37 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
38 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
39 import org.springframework.context.annotation.Bean;
40 import org.springframework.context.annotation.ComponentScan;
41 import org.springframework.context.annotation.Configuration;
42 import org.springframework.http.server.observation.ServerRequestObservationContext;
43 import org.springframework.boot.actuate.autoconfigure.observation.ObservationRegistryCustomizer;
44 import org.springframework.util.AntPathMatcher;
45 import org.springframework.util.PathMatcher;
46
47 @Configuration
48 @ComponentScan(basePackages = {"org.onap.ccsdk.oran.a1policymanagementservice"})
49 public class OtelConfig {
50     private static final Logger logger = LoggerFactory.getLogger(OtelConfig.class);
51
52     public static final int JAEGER_REMOTE_SAMPLER_POLLING_INTERVAL_IN_SECOND = 30;
53
54     @Value("${spring.application.name}")
55     private String serviceId;
56
57     @Value("${otel.exporter.otlp.traces.endpoint}")
58     private String tracingExporterEndpointUrl;
59
60     @Value("${otel.tracing.sampler.jaeger-remote.endpoint}")
61     private String jaegerRemoteSamplerUrl;
62
63     @Value("${otel.exporter.otlp.traces.protocol}")
64     private String tracingProtocol;
65
66     @Value("${otel.sdk.disabled}")
67     private boolean tracingDisabled;
68
69     @Value("${otel.sdk.south}")
70     private boolean southTracingEnabled;
71
72     @PostConstruct
73     public void checkTracingConfig() {
74         logger.info("Application Yaml Tracing Enabled: " + !tracingDisabled);
75     }
76
77     public boolean isTracingEnabled() {
78         return !tracingDisabled;
79     }
80
81     public boolean isSouthTracingEnabled() {
82         return isTracingEnabled() && southTracingEnabled;
83     }
84
85     @Bean
86     @ConditionalOnProperty(prefix = "otel.sdk", name = "disabled", havingValue = "false", matchIfMissing = false)
87     @ConditionalOnExpression("'grpc'.equals('${otel.exporter.otlp.traces.protocol}')")
88     public OtlpGrpcSpanExporter otlpExporterGrpc() {
89         return OtlpGrpcSpanExporter.builder().setEndpoint(tracingExporterEndpointUrl).build();
90     }
91
92     @Bean
93     @ConditionalOnProperty(prefix = "otel.sdk", name = "disabled", havingValue = "false", matchIfMissing = false)
94     @ConditionalOnExpression("'http'.equals('${otel.exporter.otlp.traces.protocol}')")
95     public OtlpHttpSpanExporter otlpExporterHttp() {
96         return OtlpHttpSpanExporter.builder().setEndpoint(tracingExporterEndpointUrl).build();
97     }
98
99     @Bean
100     @ConditionalOnProperty(prefix = "otel.sdk", name = "disabled", havingValue = "false", matchIfMissing = false)
101     public JaegerRemoteSampler jaegerRemoteSampler() {
102         return JaegerRemoteSampler.builder().setEndpoint(jaegerRemoteSamplerUrl)
103                 .setPollingInterval(Duration.ofSeconds(JAEGER_REMOTE_SAMPLER_POLLING_INTERVAL_IN_SECOND))
104                 .setInitialSampler(Sampler.alwaysOff()).setServiceName(serviceId).build();
105     }
106
107     @Bean
108     @ConditionalOnExpression("!${otel.sdk.disabled:true} and ${otel.sdk.south:true}")
109     public SpringWebfluxTelemetry webfluxTelemetry (OpenTelemetry openTelemetry) {
110         return SpringWebfluxTelemetry.builder(openTelemetry).build();
111     }
112
113     @Bean
114     @ConditionalOnProperty(prefix = "otel.sdk", name = "disabled", havingValue = "false", matchIfMissing = false)
115     ObservationRegistryCustomizer<ObservationRegistry> skipActuatorEndpointsFromObservation() {
116         PathMatcher pathMatcher = new AntPathMatcher("/");
117         return registry ->
118             registry.observationConfig().observationPredicate(observationPredicate(pathMatcher));
119     }
120
121     static ObservationPredicate observationPredicate(PathMatcher pathMatcher) {
122         return (name, context) -> {
123             if (context instanceof ServerRequestObservationContext observationContext) {
124                 return !pathMatcher.match("/actuator/**", observationContext.getCarrier().getRequestURI());
125             } else {
126                 return false;
127             }
128         };
129     }
130 }