Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add trace execution elapsed time logic #497

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import io.seqera.wave.service.persistence.PersistenceService
import io.seqera.wave.service.persistence.WaveBuildRecord
import io.seqera.wave.service.persistence.WaveContainerRecord
import io.seqera.wave.service.persistence.WaveScanRecord
import io.seqera.wave.trace.TraceElapsedTime
import jakarta.inject.Singleton
/**
* Basic persistence for dev purpose
Expand All @@ -32,6 +33,7 @@ import jakarta.inject.Singleton
*/
@Singleton
@CompileStatic
@TraceElapsedTime(thresholdMillis = 100)
class LocalPersistenceService implements PersistenceService {

private Map<String,WaveBuildRecord> buildStore = new HashMap<>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import io.seqera.wave.service.persistence.WaveBuildRecord
import io.seqera.wave.service.persistence.WaveContainerRecord
import io.seqera.wave.service.persistence.WaveScanRecord
import io.seqera.wave.service.scan.ScanVulnerability
import io.seqera.wave.trace.TraceElapsedTime
import io.seqera.wave.util.JacksonHelper
import jakarta.inject.Inject
import jakarta.inject.Singleton
Expand All @@ -49,6 +50,7 @@ import jakarta.inject.Singleton
@Slf4j
@Singleton
@CompileStatic
@TraceElapsedTime(thresholdMillis = 100)
class SurrealPersistenceService implements PersistenceService {

@Inject
Expand Down
41 changes: 41 additions & 0 deletions src/main/groovy/io/seqera/wave/trace/TraceElapsedTime.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Wave, containers provisioning service
* Copyright (c) 2023-2024, Seqera Labs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package io.seqera.wave.trace

import java.lang.annotation.Documented
import java.lang.annotation.Retention
import java.lang.annotation.Target

import io.micronaut.aop.Around
import static java.lang.annotation.ElementType.METHOD
import static java.lang.annotation.ElementType.TYPE
import static java.lang.annotation.RetentionPolicy.RUNTIME
/**
* When applied to a method or a class the elapsed time to carry out the method execution
* is reported in the application log file
*
* @author Paolo Di Tommaso <[email protected]>
*/
@Documented
@Retention(RUNTIME)
@Target([TYPE, METHOD])
@Around
@interface TraceElapsedTime {
int thresholdMillis() default 0
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Wave, containers provisioning service
* Copyright (c) 2023-2024, Seqera Labs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package io.seqera.wave.trace

import java.time.Duration

import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import io.micronaut.aop.InterceptorBean
import io.micronaut.aop.MethodInterceptor
import io.micronaut.aop.MethodInvocationContext
import jakarta.inject.Singleton

/**
* Implements an method interceptor that logs the elapsed time to carry out the execution
* of method invocation.
*
* This interceptor is applied to classes or methods marked in the {@link TraceElapsedTime} annotation
*
* @author Paolo Di Tommaso <[email protected]>
*/
@CompileStatic
@Slf4j
@Singleton
@InterceptorBean(TraceElapsedTime)
class TraceElapsedTimeInterceptor implements MethodInterceptor<Object,Object> {

@Override
Object intercept(MethodInvocationContext<Object, Object> context) {
// get the threshold value from the TraceElapsedTime annotation
final annot = context.getAnnotation(TraceElapsedTime)
final threshold = annot.intValue('thresholdMillis').orElse(0)

// apply it
final begin = System.currentTimeMillis()
try {
return context.proceed()
}
finally {
final delta = System.currentTimeMillis() - begin
if( threshold==0 ) {
log.debug "Method ${trace(context)} elapsed time ${Duration.ofMillis(delta)}"
}
else if( delta>=threshold ) {
log.warn "Method ${trace(context)} elapsed time ${Duration.ofMillis(delta)}"
}
}
}

static private String trace(MethodInvocationContext<Object, Object> context) {
context.getDeclaringType().getSimpleName() + '.' + context.getMethodName() + '(' + context.getParameterValueMap().entrySet().join(',') + ')'
}
}