Add rollout and autoasigments metric (#2344)
Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -10,8 +10,11 @@
|
||||
package org.eclipse.hawkbit.repository.jpa;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.hawkbit.ContextAware;
|
||||
import org.eclipse.hawkbit.repository.RolloutExecutor;
|
||||
@@ -19,6 +22,7 @@ import org.eclipse.hawkbit.repository.RolloutHandler;
|
||||
import org.eclipse.hawkbit.repository.RolloutManagement;
|
||||
import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.eclipse.hawkbit.tenancy.TenantMetricsConfiguration;
|
||||
import org.springframework.integration.support.locks.LockRegistry;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
@@ -34,6 +38,7 @@ public class JpaRolloutHandler implements RolloutHandler {
|
||||
private final LockRegistry lockRegistry;
|
||||
private final PlatformTransactionManager txManager;
|
||||
private final ContextAware contextAware;
|
||||
private final Optional<MeterRegistry> meterRegistry;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -47,13 +52,14 @@ public class JpaRolloutHandler implements RolloutHandler {
|
||||
public JpaRolloutHandler(final TenantAware tenantAware, final RolloutManagement rolloutManagement,
|
||||
final RolloutExecutor rolloutExecutor, final LockRegistry lockRegistry,
|
||||
final PlatformTransactionManager txManager,
|
||||
final ContextAware contextAware) {
|
||||
final ContextAware contextAware, final Optional<MeterRegistry> meterRegistry) {
|
||||
this.tenantAware = tenantAware;
|
||||
this.rolloutManagement = rolloutManagement;
|
||||
this.rolloutExecutor = rolloutExecutor;
|
||||
this.lockRegistry = lockRegistry;
|
||||
this.txManager = txManager;
|
||||
this.contextAware = contextAware;
|
||||
this.meterRegistry = meterRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,6 +80,8 @@ public class JpaRolloutHandler implements RolloutHandler {
|
||||
|
||||
try {
|
||||
log.debug("Trigger handling {} rollouts.", rollouts.size());
|
||||
|
||||
final long startNano = System.nanoTime();
|
||||
rollouts.forEach(rolloutId -> {
|
||||
try {
|
||||
handleRolloutInNewTransaction(rolloutId, handlerId);
|
||||
@@ -81,6 +89,10 @@ public class JpaRolloutHandler implements RolloutHandler {
|
||||
log.error("Failed to process rollout with id {}", rolloutId, throwable);
|
||||
}
|
||||
});
|
||||
meterRegistry
|
||||
.map(mReg -> mReg.timer("hawkbit.rollout.handler", TenantMetricsConfiguration.TENANT_TAG, tenantAware.getCurrentTenant()))
|
||||
.ifPresent(timer -> timer.record(System.nanoTime() - startNano, TimeUnit.NANOSECONDS));
|
||||
|
||||
log.debug("Finished handling of the rollouts.");
|
||||
} finally {
|
||||
if (log.isTraceEnabled()) {
|
||||
@@ -94,29 +106,37 @@ public class JpaRolloutHandler implements RolloutHandler {
|
||||
return tenant + "-rollout";
|
||||
}
|
||||
|
||||
// run in a tenant context, i.e. contextAware.getCurrentTenant() returns the tenant
|
||||
// the rollout is made for
|
||||
// run in a tenant context, i.e. contextAware.getCurrentTenant() returns the tenant the rollout is made for
|
||||
private void handleRolloutInNewTransaction(final long rolloutId, final String handlerId) {
|
||||
final long startNano = System.nanoTime();
|
||||
|
||||
DeploymentHelper.runInNewTransaction(txManager, handlerId + "-" + rolloutId, status -> {
|
||||
rolloutManagement.get(rolloutId).ifPresentOrElse(
|
||||
rollout ->
|
||||
// auditor is retrieved and set on transaction commit
|
||||
// if not overridden, the system user will be the auditor
|
||||
rollout.getAccessControlContext().ifPresentOrElse(
|
||||
context -> // has stored context - executes it with it
|
||||
contextAware.runInContext(
|
||||
context,
|
||||
() -> rolloutExecutor.execute(rollout)),
|
||||
() -> // has no stored context - executes it in the tenant & user scope
|
||||
contextAware.runAsTenantAsUser(
|
||||
contextAware.getCurrentTenant(),
|
||||
rollout.getCreatedBy(), () -> {
|
||||
rolloutExecutor.execute(rollout);
|
||||
return null;
|
||||
})),
|
||||
// auditor is retrieved and set on transaction commit if not overridden, the system user will be the auditor
|
||||
rollout.getAccessControlContext().ifPresentOrElse(
|
||||
context -> // has stored context - executes it with it
|
||||
contextAware.runInContext(
|
||||
context,
|
||||
() -> rolloutExecutor.execute(rollout)),
|
||||
() -> // has no stored context - executes it in the tenant & user scope
|
||||
contextAware.runAsTenantAsUser(
|
||||
contextAware.getCurrentTenant(),
|
||||
rollout.getCreatedBy(), () -> {
|
||||
rolloutExecutor.execute(rollout);
|
||||
return null;
|
||||
})),
|
||||
() -> log.error("Could not retrieve rollout with id {}. Will not continue with execution.",
|
||||
rolloutId));
|
||||
return 0L;
|
||||
});
|
||||
|
||||
meterRegistry
|
||||
.map(mReg -> mReg.timer(
|
||||
"hawkbit.rollout.handler",
|
||||
TenantMetricsConfiguration.TENANT_TAG, tenantAware.getCurrentTenant(),
|
||||
"rollout", String.valueOf(rolloutId)))
|
||||
.ifPresent(timer -> timer.record(System.nanoTime() - startNano, TimeUnit.NANOSECONDS));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import javax.sql.DataSource;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.validation.Validation;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import org.eclipse.hawkbit.ContextAware;
|
||||
import org.eclipse.hawkbit.artifact.repository.ArtifactRepository;
|
||||
import org.eclipse.hawkbit.cache.TenancyCacheManager;
|
||||
@@ -739,8 +740,8 @@ public class RepositoryApplicationConfiguration {
|
||||
@ConditionalOnMissingBean
|
||||
RolloutHandler rolloutHandler(final TenantAware tenantAware, final RolloutManagement rolloutManagement,
|
||||
final RolloutExecutor rolloutExecutor, final LockRegistry lockRegistry,
|
||||
final PlatformTransactionManager txManager, final ContextAware contextAware) {
|
||||
return new JpaRolloutHandler(tenantAware, rolloutManagement, rolloutExecutor, lockRegistry, txManager, contextAware);
|
||||
final PlatformTransactionManager txManager, final ContextAware contextAware, final Optional<MeterRegistry> meterRegistry) {
|
||||
return new JpaRolloutHandler(tenantAware, rolloutManagement, rolloutExecutor, lockRegistry, txManager, contextAware, meterRegistry);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -963,8 +964,8 @@ public class RepositoryApplicationConfiguration {
|
||||
@ConditionalOnProperty(prefix = "hawkbit.autoassign.scheduler", name = "enabled", matchIfMissing = true)
|
||||
AutoAssignScheduler autoAssignScheduler(final SystemManagement systemManagement,
|
||||
final SystemSecurityContext systemSecurityContext, final AutoAssignExecutor autoAssignExecutor,
|
||||
final LockRegistry lockRegistry) {
|
||||
return new AutoAssignScheduler(systemManagement, systemSecurityContext, autoAssignExecutor, lockRegistry);
|
||||
final LockRegistry lockRegistry, final Optional<MeterRegistry> meterRegistry) {
|
||||
return new AutoAssignScheduler(systemManagement, systemSecurityContext, autoAssignExecutor, lockRegistry, meterRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1014,9 +1015,10 @@ public class RepositoryApplicationConfiguration {
|
||||
@ConditionalOnMissingBean
|
||||
@Profile("!test")
|
||||
@ConditionalOnProperty(prefix = "hawkbit.rollout.scheduler", name = "enabled", matchIfMissing = true)
|
||||
RolloutScheduler rolloutScheduler(final SystemManagement systemManagement,
|
||||
final RolloutHandler rolloutHandler, final SystemSecurityContext systemSecurityContext, @Value("${hawkbit.rollout.executor.thread-pool.size:1}") final int threadPoolSize) {
|
||||
return new RolloutScheduler(rolloutHandler, systemManagement, systemSecurityContext, threadPoolSize);
|
||||
RolloutScheduler rolloutScheduler(
|
||||
final SystemManagement systemManagement, final RolloutHandler rolloutHandler, final SystemSecurityContext systemSecurityContext,
|
||||
@Value("${hawkbit.rollout.executor.thread-pool.size:1}") final int threadPoolSize, final Optional<MeterRegistry> meterRegistry) {
|
||||
return new RolloutScheduler(rolloutHandler, systemManagement, systemSecurityContext, threadPoolSize, meterRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,12 +9,16 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.autoassign;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||
import org.eclipse.hawkbit.repository.autoassign.AutoAssignExecutor;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
import org.eclipse.hawkbit.tenancy.TenantMetricsConfiguration;
|
||||
import org.springframework.integration.support.locks.LockRegistry;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
@@ -30,6 +34,7 @@ public class AutoAssignScheduler {
|
||||
private final SystemSecurityContext systemSecurityContext;
|
||||
private final AutoAssignExecutor autoAssignExecutor;
|
||||
private final LockRegistry lockRegistry;
|
||||
private final Optional<MeterRegistry> meterRegistry;
|
||||
|
||||
/**
|
||||
* Instantiates a new AutoAssignScheduler
|
||||
@@ -41,11 +46,12 @@ public class AutoAssignScheduler {
|
||||
*/
|
||||
public AutoAssignScheduler(final SystemManagement systemManagement,
|
||||
final SystemSecurityContext systemSecurityContext, final AutoAssignExecutor autoAssignExecutor,
|
||||
final LockRegistry lockRegistry) {
|
||||
final LockRegistry lockRegistry, final Optional<MeterRegistry> meterRegistry) {
|
||||
this.systemManagement = systemManagement;
|
||||
this.systemSecurityContext = systemSecurityContext;
|
||||
this.autoAssignExecutor = autoAssignExecutor;
|
||||
this.lockRegistry = lockRegistry;
|
||||
this.meterRegistry = meterRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,22 +67,33 @@ public class AutoAssignScheduler {
|
||||
|
||||
@SuppressWarnings("squid:S3516")
|
||||
private Object executeAutoAssign() {
|
||||
// workaround eclipselink that is currently not possible to
|
||||
// execute a query without multitenancy if MultiTenant
|
||||
// annotation is used.
|
||||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=355458. So
|
||||
// iterate through all tenants and execute the rollout check for
|
||||
// each tenant separately.
|
||||
// workaround eclipselink that is currently not possible to execute a query without multitenancy if MultiTenant
|
||||
// annotation is used - https://bugs.eclipse.org/bugs/show_bug.cgi?id=355458. So iterate through all tenants and execute the rollout
|
||||
// check for each tenant separately.
|
||||
final Lock lock = lockRegistry.obtain("autoassign");
|
||||
if (!lock.tryLock()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final long startNano = System.nanoTime();
|
||||
try {
|
||||
log.debug("Auto assign scheduled execution has acquired lock and started for each tenant.");
|
||||
systemManagement.forEachTenant(tenant -> autoAssignExecutor.checkAllTargets());
|
||||
systemManagement.forEachTenant(tenant -> {
|
||||
final long startNanoT = System.nanoTime();
|
||||
|
||||
autoAssignExecutor.checkAllTargets();
|
||||
|
||||
meterRegistry
|
||||
.map(mReg -> mReg.timer(
|
||||
"hawkbit.autoassign.executor",
|
||||
TenantMetricsConfiguration.TENANT_TAG, tenant))
|
||||
.ifPresent(timer -> timer.record(System.nanoTime() - startNanoT, TimeUnit.NANOSECONDS));
|
||||
});
|
||||
} finally {
|
||||
lock.unlock();
|
||||
meterRegistry
|
||||
.map(mReg -> mReg.timer("hawkbit.autoassign.executor.all"))
|
||||
.ifPresent(timer -> timer.record(System.nanoTime() - startNano, TimeUnit.NANOSECONDS));
|
||||
log.debug("Auto assign scheduled execution has released lock and finished.");
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,15 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.rollout;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.hawkbit.repository.RolloutHandler;
|
||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
import org.eclipse.hawkbit.tenancy.TenantMetricsConfiguration;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
@@ -29,14 +34,16 @@ public class RolloutScheduler {
|
||||
private final SystemManagement systemManagement;
|
||||
private final RolloutHandler rolloutHandler;
|
||||
private final SystemSecurityContext systemSecurityContext;
|
||||
private final Optional<MeterRegistry> meterRegistry;
|
||||
private final ThreadPoolTaskExecutor rolloutTaskExecutor;
|
||||
|
||||
public RolloutScheduler(
|
||||
final RolloutHandler rolloutHandler, final SystemManagement systemManagement, final SystemSecurityContext systemSecurityContext,
|
||||
final int threadPoolSize) {
|
||||
final RolloutHandler rolloutHandler, final SystemManagement systemManagement, final SystemSecurityContext systemSecurityContext,
|
||||
final int threadPoolSize, final Optional<MeterRegistry> meterRegistry) {
|
||||
this.systemManagement = systemManagement;
|
||||
this.rolloutHandler = rolloutHandler;
|
||||
this.systemSecurityContext = systemSecurityContext;
|
||||
this.meterRegistry = meterRegistry;
|
||||
rolloutTaskExecutor = threadPoolTaskExecutor(threadPoolSize);
|
||||
|
||||
}
|
||||
@@ -48,6 +55,8 @@ public class RolloutScheduler {
|
||||
@Scheduled(initialDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER, fixedDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER)
|
||||
public void runningRolloutScheduler() {
|
||||
log.debug("rollout schedule checker has been triggered.");
|
||||
final long startNano = System.nanoTime();
|
||||
|
||||
// run this code in system code privileged to have the necessary
|
||||
// permission to query and create entities.
|
||||
systemSecurityContext.runAsSystem(() -> {
|
||||
@@ -56,8 +65,7 @@ public class RolloutScheduler {
|
||||
// annotation is used.
|
||||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=355458. So
|
||||
// iterate through all tenants and execute the rollout check for
|
||||
// each tenant seperately.
|
||||
|
||||
// each tenant separately.
|
||||
systemManagement.forEachTenant(tenant -> {
|
||||
if (rolloutTaskExecutor == null) {
|
||||
handleAll(tenant);
|
||||
@@ -67,15 +75,27 @@ public class RolloutScheduler {
|
||||
});
|
||||
return null;
|
||||
});
|
||||
|
||||
meterRegistry
|
||||
.map(mReg -> mReg.timer("hawkbit.rollout.scheduler.all"))
|
||||
.ifPresent(timer -> timer.record(System.nanoTime() - startNano, TimeUnit.NANOSECONDS));
|
||||
}
|
||||
|
||||
private void handleAll(final String tenant) {
|
||||
log.trace("Handling rollout for tenant: {}", tenant);
|
||||
final long startNano = System.nanoTime();
|
||||
|
||||
try {
|
||||
rolloutHandler.handleAll();
|
||||
} catch (Exception e) {
|
||||
log.error("Error processing rollout for tenant {}", tenant, e);
|
||||
}
|
||||
|
||||
meterRegistry
|
||||
.map(mReg -> mReg.timer(
|
||||
"hawkbit.rollout.scheduler",
|
||||
TenantMetricsConfiguration.TENANT_TAG, tenant))
|
||||
.ifPresent(timer -> timer.record(System.nanoTime() - startNano, TimeUnit.NANOSECONDS));
|
||||
}
|
||||
|
||||
private void handleAllAsync(final String tenant) {
|
||||
@@ -83,10 +103,9 @@ public class RolloutScheduler {
|
||||
handleAll(tenant);
|
||||
return null;
|
||||
}, tenant));
|
||||
|
||||
}
|
||||
|
||||
private ThreadPoolTaskExecutor threadPoolTaskExecutor (final int threadPoolSize) {
|
||||
private ThreadPoolTaskExecutor threadPoolTaskExecutor(final int threadPoolSize) {
|
||||
if (threadPoolSize <= 1) {
|
||||
return null;
|
||||
}
|
||||
@@ -101,5 +120,4 @@ public class RolloutScheduler {
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user