diff --git a/persistence-service-v1/persistence-service-processor-v1/build.gradle.kts b/persistence-service-v1/persistence-service-processor-v1/build.gradle.kts
index e5eb6c061..08975e312 100644
--- a/persistence-service-v1/persistence-service-processor-v1/build.gradle.kts
+++ b/persistence-service-v1/persistence-service-processor-v1/build.gradle.kts
@@ -3,14 +3,14 @@ plugins {
id("io.freefair.lombok") version "8.4"
}
-val springBootStarterVersion = "3.1.3"
+val springBootStarterVersion = "3.1.5"
dependencies {
api(project(":persistence-service-external-api-v1"))
api(project(":persistence-service-internal-api-v1"))
api("com.knecon.fforesight:jobs-commons:0.10.0")
- api("com.knecon.fforesight:database-tenant-commons:0.16.0")
- api("com.knecon.fforesight:keycloak-commons:0.18.0")
+ api("com.knecon.fforesight:database-tenant-commons:0.17.0")
+ api("com.knecon.fforesight:keycloak-commons:0.22.0")
api("com.knecon.fforesight:swagger-commons:0.5.0")
api("com.iqser.red.service:pdftron-redaction-service-api-v1:4.38.0")
api("com.iqser.red.service:redaction-service-api-v1:4.177.0")
@@ -24,6 +24,7 @@ dependencies {
api("org.springframework.boot:spring-boot-starter-data-jpa:${springBootStarterVersion}")
api("org.springframework.boot:spring-boot-starter-data-redis:${springBootStarterVersion}")
api("org.springframework.boot:spring-boot-starter-amqp:${springBootStarterVersion}")
+ api("org.springframework.boot:spring-boot-starter-web:${springBootStarterVersion}")
api("com.iqser.red.commons:spring-commons:2.1.0")
api("com.iqser.red.commons:jackson-commons:2.1.0")
api("org.apache.commons:commons-compress:1.21")
@@ -31,7 +32,6 @@ dependencies {
api("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.2")
api("org.postgresql:postgresql:42.2.23")
api("org.apache.commons:commons-lang3:3.12.0")
- api("org.springframework.boot:spring-boot-starter-web:3.1.3")
api("com.iqser.red.commons:spring-boot-starter-web-custom-commons:2.1.0")
api("com.iqser.red.commons:metric-commons:2.1.0")
api("com.opencsv:opencsv:5.4")
diff --git a/persistence-service-v1/persistence-service-server-v1/build.gradle.kts b/persistence-service-v1/persistence-service-server-v1/build.gradle.kts
index 1209feb96..521247b80 100644
--- a/persistence-service-v1/persistence-service-server-v1/build.gradle.kts
+++ b/persistence-service-v1/persistence-service-server-v1/build.gradle.kts
@@ -3,7 +3,7 @@ import org.springframework.boot.gradle.tasks.bundling.BootBuildImage
plugins {
application
id("com.iqser.red.service.java-conventions")
- id("org.springframework.boot") version "3.1.3"
+ id("org.springframework.boot") version "3.1.5"
id("io.spring.dependency-management") version "1.1.3"
id("org.sonarqube") version "4.4.1.3373"
id("io.freefair.lombok") version "8.4"
@@ -11,22 +11,25 @@ plugins {
configurations {
all {
- exclude(group = "org.springframework.boot", module = "spring-boot-starter-logging")
+ exclude(group = "commons-logging", module = "commons-logging")
+ exclude(group = "org.springframework.boot", module = "spring-boot-starter-log4j2")
+ exclude(group = "com.iqser.red.commons", module = "logging-commons")
}
}
dependencies {
api(project(":persistence-service-processor-v1"))
- api("com.iqser.red.commons:storage-commons:2.45.0")
- api("junit:junit:4.13.2")
api(project(":persistence-service-external-api-impl-v1"))
api(project(":persistence-service-external-api-impl-v2"))
api(project(":persistence-service-internal-api-impl-v1"))
+ api("com.iqser.red.commons:storage-commons:2.45.0")
+ api("junit:junit:4.13.2")
+ api("org.apache.logging.log4j:log4j-slf4j-impl:2.19.0")
+ api("net.logstash.logback:logstash-logback-encoder:7.4")
testImplementation("org.springframework.amqp:spring-rabbit-test:3.0.2")
testImplementation("org.springframework.security:spring-security-test:6.0.2")
testImplementation("org.testcontainers:postgresql:1.17.1")
testImplementation("org.springframework.boot:spring-boot-starter-test:3.0.4")
- testImplementation("org.apache.logging.log4j:log4j-slf4j-impl:2.19.0")
testImplementation("com.yannbriancon:spring-hibernate-query-utils:2.0.0")
}
diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/Application.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/Application.java
index d42e3841e..accf2aff2 100644
--- a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/Application.java
+++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/Application.java
@@ -1,5 +1,36 @@
package com.iqser.red.service.peristence.v1.server;
+import java.util.Map;
+import java.util.Optional;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
+import org.springframework.boot.actuate.autoconfigure.tracing.ConditionalOnEnabledTracing;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
+import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Import;
+import org.springframework.http.server.observation.DefaultServerRequestObservationConvention;
+import org.springframework.http.server.observation.ServerRequestObservationContext;
+import org.springframework.http.server.observation.ServerRequestObservationConvention;
+import org.springframework.retry.annotation.EnableRetry;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.web.servlet.HandlerMapping;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
import com.iqser.red.persistence.service.v1.external.api.impl.PersistenceServiceExternalApiConfiguration;
import com.iqser.red.persistence.service.v2.external.api.impl.PersistenceServiceExternalApiConfigurationV2;
import com.iqser.red.service.dictionarymerge.commons.DictionaryMergeService;
@@ -17,27 +48,13 @@ import com.knecon.fforesight.tenantcommons.AsyncConfig;
import com.knecon.fforesight.tenantcommons.MultiTenancyAutoConfiguration;
import com.knecon.fforesight.tenantcommons.MultiTenancyMessagingConfiguration;
import com.knecon.fforesight.tenantcommons.MultiTenancyWebConfiguration;
+
+import io.micrometer.common.KeyValue;
+import io.micrometer.common.KeyValues;
import io.micrometer.core.aop.TimedAspect;
import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.observation.ObservationRegistry;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
-import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
-import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
-import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.cache.annotation.EnableCaching;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Import;
-import org.springframework.retry.annotation.EnableRetry;
-import org.springframework.scheduling.annotation.EnableAsync;
-import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.web.servlet.config.annotation.CorsRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Slf4j
@EnableAsync
@@ -48,7 +65,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@ImportAutoConfiguration({StorageAutoConfiguration.class, JobsAutoConfiguration.class, DatabaseTenantCommonsAutoConfiguration.class, MultiTenancyAutoConfiguration.class, SpringDocAutoConfiguration.class, DefaultKeyCloakCommonsAutoConfiguration.class})
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class, CassandraAutoConfiguration.class, DataSourceAutoConfiguration.class, LiquibaseAutoConfiguration.class})
@Import({PersistenceServiceExternalApiConfigurationV2.class, PersistenceServiceExternalApiConfiguration.class, PersistenceServiceInternalApiConfiguration.class, PersistenceServiceExternalApiCacheConfiguration.class, MultiTenancyWebConfiguration.class, PersistenceServiceProcessorConfiguration.class, MessagingConfiguration.class, AsyncConfig.class, MultiTenancyMessagingConfiguration.class})
-public class Application {
+public class Application implements ApplicationContextAware {
/**
* Entry point to the service application.
@@ -91,4 +108,71 @@ public class Application {
return new DictionaryMergeService();
}
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+
+ var beanFactory = applicationContext.getAutowireCapableBeanFactory();
+
+ try {
+ var observationRegistry = beanFactory.getBean(ObservationRegistry.class);
+
+ beanFactory.initializeBean(observationRegistry, "observationRegistry");
+ } catch (Exception ignored) {
+ }
+ }
+
+
+ @Bean
+ @ConditionalOnEnabledTracing
+ public ServerRequestObservationConvention customTagsRequestObservationConvention(@Value("${kubernetes.namespace}") String namespace,
+ @Value("${project.version}") String version) {
+
+ return new DefaultServerRequestObservationConvention() {
+ @Override
+ public KeyValues getLowCardinalityKeyValues(ServerRequestObservationContext context) {
+ // Make sure that KeyValues entries are already sorted by name for better performance
+ return super.getLowCardinalityKeyValues(context)
+ .and(getValueFromPathVariableOrRequestParam(context, "dossierId"),
+ getValueFromPathVariableOrRequestParam(context, "dossierTemplateId"),
+ getValueFromPathVariableOrRequestParam(context, "fileId"),
+ KeyValue.of("kubernetes.namespace", namespace),
+ KeyValue.of("service.version", version),
+ tenantId(context));
+ }
+
+
+ @Override
+ public KeyValues getHighCardinalityKeyValues(ServerRequestObservationContext context) {
+ // Make sure that KeyValues entries are already sorted by name for better performance
+ return super.getHighCardinalityKeyValues(context)
+ .and(getValueFromPathVariableOrRequestParam(context, "dossierId"),
+ getValueFromPathVariableOrRequestParam(context, "dossierTemplateId"),
+ getValueFromPathVariableOrRequestParam(context, "fileId"),
+ KeyValue.of("kubernetes.namespace", namespace),
+ KeyValue.of("service.version", version),
+ tenantId(context));
+ }
+
+
+ private KeyValue tenantId(ServerRequestObservationContext context) {
+
+ return KeyValue.of("tenantId", Optional.ofNullable(context.getCarrier().getHeader("X-Tenant-Id")).orElse(""));
+ }
+
+
+ private KeyValue getValueFromPathVariableOrRequestParam(ServerRequestObservationContext context, String name) {
+
+ var value = context.getCarrier().getParameter(name);
+ if (value == null) {
+ var pathVariables = (Map) context.getCarrier().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
+ value = pathVariables == null ? null : (String) pathVariables.get(name);
+ }
+
+ return KeyValue.of(name, Optional.ofNullable(value).orElse(""));
+ }
+
+ };
+ }
+
}
diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/resources/application-dev.yaml b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application-dev.yaml
index 1fa635079..0c80ee4d2 100644
--- a/persistence-service-v1/persistence-service-server-v1/src/main/resources/application-dev.yaml
+++ b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application-dev.yaml
@@ -50,3 +50,7 @@ fforesight:
cachePrepStmts: true
prepStmtCacheSize: 1000
prepStmtCacheSqlLimit: 2048
+
+management:
+ tracing:
+ enabled: false
diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yaml b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yaml
index ecf3a41f2..a4ceb784e 100644
--- a/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yaml
+++ b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yaml
@@ -7,6 +7,12 @@ redaction-report-service.url: "http://redaction-report-service-v1:8080"
search-service.url: "http://search-service-v1:8080"
tenant-user-management-service.url: "http://tenant-user-management-service:8080/internal"
+logging.pattern.level: "%5p [${spring.application.name},%X{traceId:-},%X{spanId:-}]"
+
+logging.type : ${LOGGING_TYPE:CONSOLE}
+kubernetes.namespace: ${NAMESPACE:default}
+project.version: 1.0-SNAPSHOT
+
application:
type: "RedactManager"
rss.component-log.enabled: false
@@ -63,6 +69,14 @@ management:
health:
db:
enabled: false
+ tracing:
+ enabled: ${TRACING_ENABLED:false}
+ sampling:
+ probability: ${TRACING_PROBABILITY:1.0}
+ otlp:
+ tracing:
+ endpoint: ${OTLP_ENDPOINT:http://otel-collector-opentelemetry-collector.otel-collector:4318/v1/traces}
+
metrics:
persistence:
diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/resources/log4j2.xml b/persistence-service-v1/persistence-service-server-v1/src/main/resources/log4j2.xml
deleted file mode 100644
index c36f74e82..000000000
--- a/persistence-service-v1/persistence-service-server-v1/src/main/resources/log4j2.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
- ${env:LOGGING_TYPE}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/resources/logback-spring.xml b/persistence-service-v1/persistence-service-server-v1/src/main/resources/logback-spring.xml
new file mode 100644
index 000000000..33b2cef75
--- /dev/null
+++ b/persistence-service-v1/persistence-service-server-v1/src/main/resources/logback-spring.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yaml b/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yaml
index c85f2c996..968397e81 100644
--- a/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yaml
+++ b/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yaml
@@ -65,6 +65,8 @@ metrics:
enabled: false
management:
+ tracing:
+ enabled: false
endpoint:
metrics.enabled: true
health.enabled: true