Usando Eclipse AspectJ para injetar um Logger que Logs contexto / metadados do código executam?
Sep 21 2020
Estou tentando definir um aspecto para injetar um logger.
Estou procurando criar algo como:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public aspect LogInjector {
private pointcut executionJoinPoints(): !within(LogInjector) && execution (* *.*(..));
before(): executionJoinPoints(){
// Get class name of the executed code
clazz = ...
final Logger logger = LogManager.getLogger(clazz);
// Get method name of the executed code
method = ...
// Get params name, type and values triplet or values at least if the previous is not possible, of the executed code
params = ...
// Get call stack of the executed code
stack = ...
logger.trace("{}.{}({}) - {}", clazz.name(), method.name(), params, stack);
}
after(): executionJoinPoints(){
// Get class name of the executed code
clazz = ...
final Logger logger = LogManager.getLogger(clazz);
// Get method name of the executed code
method = ...
// Get return value or exception of the executed code
result = ...
logger.trace("{}.{} = {}", clazz.name(), method.name(), result);
}
}
Para isso, desejo recuperar metadados de execução / dados de contexto:
- exceções
- valores de retorno
Como posso obter esses metadados / dados de contexto?
Respostas
1 kriegaex Sep 22 2020 at 02:51
Para manter seu aspecto eficiente, recomendo o seguinte:
- Limite seu pointcut aos pacotes e classes de destino que você realmente deseja depurar. Não registre / rastreie o mundo inteiro. Você também pode usar um aspecto de base abstrato com um corte de ponto abstrato e estender o aspecto em um sub-aspecto concreto com um corte de ponto concreto. O último pode até ser fornecido por meio da configuração XML se você usar o entrelaçamento do tempo de carregamento.
- Use um
around()conselho em vez de um parbefore()/after(). Então você só precisa calcular alguns dos valores registrados uma vez e usá-los antes e depois da chamada do método original feita viaproceed(). - Simplesmente registre em
thisJoinPointvez de juntar os bits contidos nele por padrão. Isso já fornecerá o tipo de ponto de junção, assinatura do método, incluindo tipos de parâmetro e valor de retorno. - Não registre nomes de parâmetros, as informações não agregam valor real. Além disso, os nomes dos parâmetros estão sujeitos a refatoração e só estarão presentes se o seu código for compilado com informações de depuração. Mantenha-o simples e registre apenas os valores dos parâmetros.
- No
around()conselho mencionado acima, você pode incluir aproceed()chamadatry-catch-finallye manipular e registrar convenientemente quaisquer exceções e rastreamentos de pilha e / ou agrupar exceções verificadas em AspectJsSoftExceptionou um simplesRuntimeExceptione relançá-las. O que for aplicável à sua situação. - Os resultados da chamada de método são apenas os resultados de
proceed(), que seria você também o que você precisa para retornar doaround()conselho. Você também pode retornar algo diferente (mas deve ter o tipo de retorno correto) ou ignorar completamenteproceed()se, por qualquer motivo, desejar ignorar a execução do método de destino.
Tudo o que acabei de dizer está escrito no manual do AspectJ ou em qualquer outro tutorial do AspectJ. Você pode querer ler alguns deles na próxima vez, antes de fazer uma pergunta geral como esta.
O que significa um erro “Não é possível encontrar o símbolo” ou “Não é possível resolver o símbolo”?
Christopher Nolan uma vez se arrependeu de ter lido o 'roteiro de Pulp Fiction' de Quentin Tarantino