# Kora Aop Logging

> Declarative method logging in Kora via the logging-common module — @Log (args + result), @Log.in / @Log.out / @Log.result, @Log.off to suppress a parameter or method, and @Mdc for Mapped Diagnostic Context (key/value, ${expr} interpolation, global thread scope). Covers the imperative ru.tinkoff.kora.logging.common.MDC API and the SLF4J-MDC import pitfall. Use when adding entry/exit logging to a s…

- **Type:** Skill
- **Install:** `agentstack add skill-kora-projects-kora-skills-kora-aop-logging`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [kora-projects](https://agentstack.voostack.com/s/kora-projects)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [kora-projects](https://github.com/kora-projects)
- **Source:** https://github.com/kora-projects/kora-skills/tree/master/plugins/kora-v1/skills/kora-aop-logging
- **Website:** http://kora-projects.github.io/kora-docs

## Install

```sh
agentstack add skill-kora-projects-kora-skills-kora-aop-logging
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Kora AOP Logging — `@Log` and `@Mdc`

Declarative, compile-time method logging. The annotation processor generates a `*Aspect` class around your method; there is no reflection or runtime proxy. The aspect writes through SLF4J, so your Logback configuration controls the final format.

Use this skill when you need to:
- log method entry/exit with arguments and return value (`@Log`),
- enrich every log line of a call with contextual keys (`@Mdc`),
- suppress credentials or large payloads from log output (`@Log.off`),
- wire `LoggingModule` into a `@KoraApp`.

## Quick Start

### 1. Dependencies

`logging-common` is usually pulled transitively by a logging backend (`logging-logback`). Add it explicitly only if it is missing. All Kora artifacts inherit their version from the `kora-parent` BOM — never pin an individual `ru.tinkoff.kora:*` version.

```groovy
dependencies {
    koraBom platform("ru.tinkoff.kora:kora-parent:1.2.17")

    // Mandatory: without the annotation processor no aspect is generated
    annotationProcessor "ru.tinkoff.kora:annotation-processors"

    implementation "ru.tinkoff.kora:logging-logback" // pulls logging-common transitively
}
```

Kotlin replaces the processor with KSP:

```groovy
ksp "ru.tinkoff.kora:symbol-processors"
implementation "ru.tinkoff.kora:logging-logback"
```

### 2. Enable in the application graph

```java
@KoraApp
public interface Application extends LoggingModule { }
```

### 3. Log a method

The enclosing class must be non-`final` (Java) / `open` (Kotlin) so the aspect can subclass it.

```java
@Component
public class UserService {          // NOT final

    @Log
    public User getUser(String id) {
        return userRepository.findById(id);
    }
}
```

### 4. Enrich with MDC

```java
@Log
public User getUser(@Mdc(key = "userId") String id) {
    return userRepository.findById(id); // every log line in this call carries userId=
}
```

---

## `@Log` family

All annotations live in `ru.tinkoff.kora.logging.common.annotation`.

| Annotation | Effect |
|-----------|--------|
| `@Log` | Log on entry and exit |
| `@Log.in` | Log on method entry only |
| `@Log.out` | Log on method exit only |
| `@Log.result` | Log the return value only |
| `@Log.off` on a **parameter** | Suppress that one value in the log line |
| `@Log.off` on a **method** | Suppress all logging for the method |

### Choosing the level

`@Log`, `@Log.in`, and `@Log.out` accept the level as the **annotation value** — the attribute is `value`, not `level`, and the type is `org.slf4j.event.Level`.

```java
import org.slf4j.event.Level;

@Log(Level.DEBUG)            // value attribute, not level =
public User getUser(String id) { ... }
```

Default level is `INFO` for `@Log`/`@Log.in`/`@Log.out` and `DEBUG` for `@Log.result`.

There is **no `Level.OFF`** — `org.slf4j.event.Level` only has `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`. To disable logging for a method, use `@Log.off` (not a level).

### Output by configured logger level

For `@Log` on `methodWithArgs(String strParam, int numParam)` returning `"testResult"`, the actual output depends on the **logger level** configured in `logback.xml` for that class:

| Logger level | Output |
|--------------|--------|
| `TRACE` / `DEBUG` | `> {data: {strParam: "s", numParam: "4"}}` then `` then ` **Never import `org.slf4j.MDC`.** SLF4J's stock MDC writes into a different thread-local that `KoraAsyncAppender` does not propagate and Kora's encoder does not render — values silently vanish. IDE auto-import picks the SLF4J one by default; verify the import on every `MDC` usage. There is no `MDC.wrap(...)` / `MDC.clear()` in Kora's API.

---

## Combined example

```java
@Component
public class OrderService {                       // NOT final

    @Log                                          // entry + exit
    @Mdc(key = "tenant", value = "${tenantId}")
    @Mdc(key = "operation", value = "create-order")
    public Order create(
        @Mdc String tenantId,                     // value lands in MDC as tenantId
        @Log.off CreateOrderDto body              // body never appears in log output
    ) {
        return repository.save(body.toEntity());
    }
}
```

MDC keys present during the call: `tenant`, `operation`, `tenantId`. The log line shows `tenantId` (and the boundary markers); `body` is suppressed.

---

## Supported signatures

| Java | Kotlin |
|------|--------|
| `T myMethod()` | `fun myMethod(): T` (or `T?`, `Unit`) |
| `Optional myMethod()` | — |
| `CompletionStage myMethod()` | `suspend fun myMethod(): T` |
| `Mono` / `Flux` (needs `io.projectreactor:reactor-core`) | `Flow` (needs `kotlinx-coroutines-core`) |

Java class must be non-`final`; Kotlin class must be `open`.

---

## Common pitfalls

| Symptom | Fix |
|---------|-----|
| `@Log` compiles but nothing is logged | The class is `final` (Java) / not `open` (Kotlin), or the annotation processor / KSP is missing |
| MDC values never appear in output | `org.slf4j.MDC` imported instead of `ru.tinkoff.kora.logging.common.MDC` |
| `@Log(level = ...)` does not compile | The attribute is `value`, not `level`: write `@Log(Level.DEBUG)` |
| Looking for `Level.OFF` | It does not exist; use `@Log.off` to disable a method |
| Want full args but see only `>` / `<` | The logger level for that class is `INFO`; set it to `DEBUG` in `logback.xml` |
| Sensitive argument leaks into logs | Add `@Log.off` to that parameter |
| Global MDC bleeds across requests | Avoid `global = true`, or remove the key with the static `MDC.remove(key)` at the end of the unit of work |

---

## References

- [logging-aspect.md](references/logging-aspect.md) — full `@Log` / `@Mdc` / level reference distilled from the docs
- [logging-mdc.md](references/logging-mdc) — MDC patterns, interpolation, global scope, imperative API
- [logging-performance.md](references/logging-performance.md) — production tuning, `KoraAsyncAppender`, suppressing large payloads

## Assets

- `assets/LoggedService.java.template`, `assets/LoggedService.kt.template` — runnable `@Log` + `@Mdc` service templates. See [assets/README.md](assets/README.md).

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [kora-projects](https://github.com/kora-projects)
- **Source:** [kora-projects/kora-skills](https://github.com/kora-projects/kora-skills)
- **License:** Apache-2.0
- **Homepage:** http://kora-projects.github.io/kora-docs

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-kora-projects-kora-skills-kora-aop-logging
- Seller: https://agentstack.voostack.com/s/kora-projects
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
