Логирование
Модуль для декларативного логирования аргументов и результата методов с помощью аннотаций аспектов.
Подключение¶
Скорее всего уже транзитивно подключен из других зависимостей либо из 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(): T
suspend myMethod(): T
Kotlin Coroutine (надо подключить зависимость какimplementation
)myMethod(): Flow<T>
Kotlin Coroutine (надо подключить зависимость какimplementation
)