How log suspend function argument with AOP?

I’m using spring boot and I want to log suspend function call with AOP. for getting function arguments I use as follows:

val methodArgs = joinPoint.args.joinToString()

the result is as follows:

Continuation at kotlin.reflect.full.KCallables.callSuspendBy(KCallables.kt:74)

How can I log suspend function arguments?

You just need to ignore this last parameter which holds a continuation.

However, it won’t be that easy as the execution flow could leave suspend functions and jump back into them. Whenever we suspend, we return from a function and whenever we resume, we call it again. You would have to detect if this is a first call or a resumption.

@broot My question is How? How can I do it?

I won’t provide you a ready to use answer as I don’t know Spring AOP. But it may be annoying to implement and I’m not sure it is worth the effort.

Technically speaking, when calling a function, we check the type of the continuation to determine if this is the first call or resumption. When returning from a function, the return value says if this is a real return or suspension.

1 Like

What do you even mean by this? A suspended function works the same as a normal function; it has a bunch of arguments. Suspended functions are special in that they have an extra argument, the Continuation parameter, so are you saying you want to log the value of that? Why? What value would that give you? The Continuation parameter is used to make coroutines work, and I can’t imagine any scenario where it would be useful for debugging your code.

I want to implement a logger with AOP. By using @Before, before running suspend function, I want to log the function is running with this parameters.

Ok, so let’s say you’ve got a function like this:

@Before
suspend fun foo(bar: String, baz: Int) {
}

runBlocking {
    foo("hello", 5)
}

When your method interceptor intercepts this method, it will actually have three arguments; bar, baz, and Continuation. bar = “hello”, baz = 5, and Continuation = an object with a label and function and stuff.

My point is, when you’re logging these arguments, what useful information do you expect to get out of logging the Continuation parameter? It’s just gonna be information about the internal coroutine workings, so unless you’re trying to debug the specific coroutine execution path, I don’t see any value in it.

Or, is it possible that I’ve misunderstood you, and your question is not about logging the Continuation argument, but rather around “how can I intercept a suspended function and still keep it suspending?”

@Skater901 The actually code is as follows:

suspend fun foo(bar: String, baz: Int) {
}
@Around("@annotation(logMethodCall)")
fun log(joinPoint: ProceedingJoinPoint, logMethodCall: LogMethodCall): Any? {
    val args = joinPoint.args
    // Other codes
}

In this state, args has not 3 arguments, It has 1 argument with type Continuation(Actually is kotlin.reflect.full.KCallables.callSuspendBy)

Hmm, this is unexpected. From this code you should get a function:

foo(Ljava/lang/String;ILkotlin/coroutines/Continuation;)Ljava/lang/Object;

But the args value has 1 arguments:
[Ljava.lang.Object;@3e259c61 and the type of the alone args is: class kotlin.reflect.full.KCallables$callSuspendBy$1

Sorry, That was my mistake. It has function arguments with a Continuation argument. All be well.