diff --git a/conf/openmetadata.yaml b/conf/openmetadata.yaml index 72af3ced341..df233a01364 100644 --- a/conf/openmetadata.yaml +++ b/conf/openmetadata.yaml @@ -171,9 +171,9 @@ elasticsearch: batchSize: ${ELASTICSEARCH_BATCH_SIZE:-10} searchIndexMappingLanguage: ${ELASTICSEARCH_INDEX_MAPPING_LANG:-EN} -# eventMonitoringConfiguration: - # eventMonitor: ${EVENT_MONITOR:-prometheus} # Possible values are "prometheus", "cloudwatch" - # batchSize: ${EVENT_MONITOR_BATCH_SIZE:-10} +eventMonitoringConfiguration: + eventMonitor: ${EVENT_MONITOR:-prometheus} # Possible values are "prometheus", "cloudwatch" + batchSize: ${EVENT_MONITOR_BATCH_SIZE:-10} # it will use the default auth provider for AWS services if parameters are not set # parameters: # region: ${OM_MONITOR_REGION:-""} @@ -184,6 +184,7 @@ eventHandlerConfiguration: eventHandlerClassNames: - "org.openmetadata.service.events.AuditEventHandler" - "org.openmetadata.service.events.ChangeEventHandler" + - "org.openmetadata.service.events.WebAnalyticEventHandler" airflowConfiguration: apiEndpoint: ${AIRFLOW_HOST:-http://localhost:8080} diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/events/AuditEventHandler.java b/openmetadata-service/src/main/java/org/openmetadata/service/events/AuditEventHandler.java index 24fab31cb83..fb394fdd4bb 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/events/AuditEventHandler.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/events/AuditEventHandler.java @@ -33,6 +33,10 @@ public class AuditEventHandler implements EventHandler { } public Void process(ContainerRequestContext requestContext, ContainerResponseContext responseContext) { + if (requestContext.getUriInfo().getPath().contains(WebAnalyticEventHandler.WEB_ANALYTIC_ENDPOINT)) { + // we don't want to send web analytic event to the audit log + return null; + } int responseCode = responseContext.getStatus(); String method = requestContext.getMethod(); if (responseContext.getEntity() != null) { diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/events/EventFilter.java b/openmetadata-service/src/main/java/org/openmetadata/service/events/EventFilter.java index e9d9bf4853d..87d1005c302 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/events/EventFilter.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/events/EventFilter.java @@ -30,12 +30,6 @@ import org.openmetadata.service.util.ParallelStreamUtil; @Provider public class EventFilter implements ContainerResponseFilter { private static final List AUDITABLE_METHODS = Arrays.asList("POST", "PUT", "PATCH", "DELETE"); - private static List EXCLUDED_ENDPOINTS = new ArrayList<>(JwtFilter.EXCLUDED_ENDPOINTS); - - static { - EXCLUDED_ENDPOINTS.add("v1/analytics/webAnalyticEvent/collect"); - } - private static final int FORK_JOIN_POOL_PARALLELISM = 20; private final ForkJoinPool forkJoinPool; private final List eventHandlers; @@ -75,7 +69,7 @@ public class EventFilter implements ContainerResponseFilter { .forEach( (eventHandler) -> { UriInfo uriInfo = requestContext.getUriInfo(); - if (EXCLUDED_ENDPOINTS.stream().noneMatch(endpoint -> uriInfo.getPath().contains(endpoint))) { + if (JwtFilter.EXCLUDED_ENDPOINTS.stream().noneMatch(endpoint -> uriInfo.getPath().contains(endpoint))) { ParallelStreamUtil.runAsync(() -> eventHandler.process(requestContext, responseContext), forkJoinPool); } }); diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/events/WebAnalyticEventHandler.java b/openmetadata-service/src/main/java/org/openmetadata/service/events/WebAnalyticEventHandler.java new file mode 100644 index 00000000000..f6ad55e64b7 --- /dev/null +++ b/openmetadata-service/src/main/java/org/openmetadata/service/events/WebAnalyticEventHandler.java @@ -0,0 +1,47 @@ +package org.openmetadata.service.events; + +import io.micrometer.core.instrument.Counter; +import io.micrometer.prometheus.PrometheusMeterRegistry; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.core.UriInfo; +import lombok.extern.slf4j.Slf4j; +import org.jdbi.v3.core.Jdbi; +import org.openmetadata.service.OpenMetadataApplicationConfig; +import org.openmetadata.service.util.MicrometerBundleSingleton; + +@Slf4j +public class WebAnalyticEventHandler implements EventHandler { + private PrometheusMeterRegistry prometheusMeterRegistry; + private String clusterName; + public static final String WEB_ANALYTIC_ENDPOINT = "v1/analytics/webAnalyticEvent/collect"; + private static final String COUNTER_NAME = "web.analytics.events"; + + public void init(OpenMetadataApplicationConfig config, Jdbi jdbi) { + this.prometheusMeterRegistry = MicrometerBundleSingleton.prometheusMeterRegistry; + this.clusterName = config.getClusterName(); + } + + public Void process(ContainerRequestContext requestContext, ContainerResponseContext responseContext) { + UriInfo uriInfo = requestContext.getUriInfo(); + if (uriInfo.getPath().contains(WEB_ANALYTIC_ENDPOINT)) { + String username = "anonymous"; + if (requestContext.getSecurityContext().getUserPrincipal() != null) { + username = requestContext.getSecurityContext().getUserPrincipal().getName(); + } + incrementMetric(username); + } + return null; + } + + private void incrementMetric(String username) { + Counter.builder(COUNTER_NAME) + .tags("clusterName", clusterName, "username", username) + .register(prometheusMeterRegistry) + .increment(); + } + + public void close() { + prometheusMeterRegistry.close(); + } +} diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/analytics/WebAnalyticEventResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/analytics/WebAnalyticEventResource.java index f229a3be6ee..677fd812dd5 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/analytics/WebAnalyticEventResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/analytics/WebAnalyticEventResource.java @@ -52,7 +52,6 @@ import org.openmetadata.service.resources.Collection; import org.openmetadata.service.resources.EntityResource; import org.openmetadata.service.security.Authorizer; import org.openmetadata.service.security.policyevaluator.OperationContext; -import org.openmetadata.service.util.MicrometerBundleSingleton; import org.openmetadata.service.util.RestUtil; import org.openmetadata.service.util.ResultList; @@ -427,15 +426,8 @@ public class WebAnalyticEventResource extends EntityResource { - try { - return dao.addWebAnalyticEventData(webAnalyticEventData); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); + throws IOException { + return dao.addWebAnalyticEventData(webAnalyticEventData); } @DELETE diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/util/MicrometerBundleSingleton.java b/openmetadata-service/src/main/java/org/openmetadata/service/util/MicrometerBundleSingleton.java index d21c65ca178..98433115aa3 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/util/MicrometerBundleSingleton.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/util/MicrometerBundleSingleton.java @@ -26,7 +26,6 @@ public class MicrometerBundleSingleton { public static MicrometerBundle getInstance() { if (INSTANCE == null) { INSTANCE = new MicrometerBundle(); - webAnalyticEvents = MicrometerBundle.prometheusRegistry.timer("web.analytics.events"); // We'll use this registry to add monitoring around Ingestion Pipelines prometheusMeterRegistry = MicrometerBundle.prometheusRegistry; }