Логирование
Модуль для декларативного логирования аргументов и результата методов с помощью аннотаций аспектов.
Подключение¶
Скорее всего уже транзитивно подключен из других зависимостей либо из Logback, в противном случае требуется подключить:
Зависимость build.gradle:
Модуль:
Зависимость build.gradle.kts:
Модуль:
Логирование¶
Предполагается использовать специальные комбинации аннотаций для настройки логирование методов.
Аргументов¶
| Уровень логгирования | Лог |
|---|---|
| TRACE, DEBUG |
DEBUG [main] r.t.e.e.Example.doWork: > {data: {numParam: "4"}} |
| INFO |
INFO [main] r.t.e.e.Example.doWork: > |
Результата¶
| Уровень логгирования | Лог |
|---|---|
| TRACE, DEBUG |
DEBUG [main] r.t.e.e.Example.doWork: < {data: {out: "testResult"}} |
| INFO |
INFO [main] r.t.e.e.Example.doWork: < |
Аргументов и результата¶
| Уровень логгирования | Лог |
|---|---|
| TRACE, DEBUG |
DEBUG [main] r.t.e.e.Example.doWork: > {data: {strParam: "s", numParam: "4"}} DEBUG [main] r.t.e.e.Example.doWork: < {data: {out: "testResult"}} |
| INFO |
INFO [main] r.t.e.e.Example.doWork: > INFO [main] r.t.e.e.Example.doWork: < |
Выборочное логирование¶
| Уровень логгирования | Лог |
|---|---|
| TRACE, DEBUG |
INFO [main] r.t.e.e.Example.doWork: < |
| INFO |
INFO [main] r.t.e.e.Example.doWork: < |
Структурированный параметр¶
В случае если представление параметра как строкой не является желаемым поведением,
его можно реализовать интерфейс StructuredArgument и параметр научится логировать себя сам:
public record Entity(String name, String code) implements StructuredArgument {
@Override
public String fieldName() {
return "name";
}
@Override
public void writeTo(JsonGenerator generator) throws IOException {
generator.writeString(name);
}
}
@Log.in
public String doWork(Entity entity) {
return "testResult";
}
| Уровень логгирования | Лог |
|---|---|
| TRACE, DEBUG |
INFO [main] r.t.e.e.Example.doWork: > data={"entity":"Bob"} |
| INFO |
INFO [main] r.t.e.e.Example.doWork: > data={"entity":"Bob"} |
Конвертация параметров¶
В случае если представление параметра как строкой не является желаемым поведением,
его можно переназначить через указание StructuredArgumentMapper напротив желаемого аргумента:
public record Entity(String name, String code) { }
public final class EntityLogMapper implements StructuredArgumentMapper<Entity> {
public void write(JsonGenerator gen, Entity value) throws IOException {
gen.writeString(value.name());
}
}
@Log.in
public String doWork(@Mapping(EntityLogMapper.class) Entity entity) {
return "testResult";
}
data class Entity(val name: String, val code: String)
class EntityLogMapper : StructuredArgumentMapper<Entity> {
@Throws(IOException::class)
override fun write(gen: JsonGenerator, value: Entity) = gen.writeString(value.name)
}
@Log.`in`
fun doWork(@Mapping(EntityLogMapper::class) entity: Entity): String {
return "testResult"
}
| Уровень логгирования | Лог |
|---|---|
| TRACE, DEBUG |
INFO [main] r.t.e.e.Example.doWork: > data={"entity":"Bob"} |
| INFO |
INFO [main] r.t.e.e.Example.doWork: > data={"entity":"Bob"} |
Сигнатуры¶
Доступные сигнатуры для методов которые поддерживают аннотации из коробки:
Класс не должен быть final, чтобы аспекты работали.
Под T подразумевается тип возвращаемого значения, либо Void.
T myMethod()Optional<T> myMethod()CompletionStage<T> myMethod()CompletionStageMono<T> myMethod()Project Reactor (надо подключить зависимость)Flux<T> myMethod()Project Reactor (надо подключить зависимость)
Класс должен быть open, чтобы аспекты работали.
Под T подразумевается тип возвращаемого значения, либо T?, либо Unit.
myMethod(): Tsuspend myMethod(): TKotlin Coroutine (надо подключить зависимость какimplementation)myMethod(): Flow<T>Kotlin Coroutine (надо подключить зависимость какimplementation)