Logging
The primary annotation for specify logs.
Annotation @Logging
Annotation methods or classes
import io.bitryon.logger.annotation.Logging;
@Logging
public class UserServiceImpl { // impelements UserService {
public User getById(Long userId){
return user;
}
@Logging(sanitizerPatterns="*/MASK$3(recipient)", skipRandom=Integer.MAX_VALUE >>> 1)// mask the recipient JSON/*EmailService.sendByNoRepply*
public String sendVerificationUrl(String recipient, String verificationUrl) {
return htmlContent;
}
}
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| parameters | boolean | true |
Log parameters when call to the method, or the methods of the class |
| returns | boolean | true |
Log return values of the method |
| returnsAndParameters | boolean | false |
Log return values and parameters both when the method returns. |
| reset | boolean | false | Reset the log/trace id, so the next call could be in new traces. |
| step | String | "" | The step of the code to print logs. Leave empty to let logger create the step of line of code as a stack. |
| catchExceptions | Class<? extends Throwable>[] | { Exception.class }; | Log exception of the method. |
| skipThrow | boolean | false | to throw exception when caught and logged. true will not throw the exception when caught and logged. |
| skipStacks | int | 0 |
skip specified number of stacks when trace back the thread stack. |
| skipRandom | int | Integer.MAX_VALUE |
the possibility to write logs for the method. will skip return and error as well. |
| sanitizerPatterns | String[] | {} | Patterns to sanitize sensitive info. If it starts with /, it must follow with a full pattern [/JSON/xxxx.method/X/MASK(key)], otherwise [X/MASK(key)]. multiple groups accepted [X/MASK(key1)/X/MASK(key2)]. |
| catchLogging | boolean | false | the catcher of the method annotated Logging. The catcher can be Logging.parameters/returns/parametersAndReturns false. |
| catchClasses | Class<?>[] | {} | the catcher classes. |
| catchPackages | String[] | {} | the catcher packages. It must be exact match. |
Sanitizer Pattern tokens
start with /, not end with /; can place multiple groups; $ is to pass parameters.
Or, start without / to match specified method by @Logging;
Sanitizer template: /TYPE/Step/[placeholder: *]/FUNC(key1|key2) /TYPE/Step/[placeholder: *]/MD5(key1|key2)/[placeholder: KEY-base62]/AES(key1|key2) Real case: /JSON/*Service*.java*.service.*UserService*#*/MTIzNDU2NzgxMjM0NTY3ODEyMzQ1Njc4/AES(driverLisenceId)/*/MASK$2(name)//SKIP(birthday), /JSON/*MedicService*#*/MTIzNDU2NzgxMjM0NTY3ODEyMzQ1Njc4/AES(driverLisenceId)/*/MASK$2(name)//SKIP(birthday), /JSON/*.java*.Medic*#*/*/MASK$4(deceases)/yyyy-MM-dd HH:mm:ss.ssss/DATE_FORMATER(timeCreated), /HTTP/*LoggingHttpRequestWebReader#readHttpRequest*/MTIzNDU2NzgxMjM0NTY3ODEyMzQ1Njc4/AES(driverLisenceId)/*/MASK$2(name)//SKIP(birthday)
| Token | Default | Description |
|---|---|---|
%TYPE | JSON / J |
CONF("C"), -- configuration log. must be the first line of log for each file. repeatable.
METRIC("M"), -- reserved
TEXT("T"), -- print text only log
EXCEP("E"), -- print java exceptions into log
JSON("J"), -- print json log
HTTP("H"); -- print HTPP log
|
%Step | "" | support wildcard match: /JSON/*Controller.java*controller.*Controller#*/*/MASK(encryptionKey)/*/MD5(sessionId|session_id) |
%placeholder | * | for AES it's the key in base64. |
%FUNC | FUNC$1, 1 is to pass to the function, MD5$3. See details below. |
Sanitizer Pattern functions
Functions won't change the value but only covert to the new.
EMPTY, -- set the string value of the keys to empty string
SKIP, -- skip the value of the key so the log doesn't print it.
POPULAR, -- capture it then scan the entire log to replace all. can use with others: POPULAR(MASK(key1))
AES, -- AES encryption.
MD5, -- MD5(key1) -> XWvr4b7h0XBFB79Irz1ny; MD5$1(key1) -> XWvr4b7h0XBFB79Irz1ny-423; 423 is the length of the original text
SHA1, -- similar with MD5
SHA256, -- similar with MD5
MASK, -- Mask the value of the key:
*/MASK(key1) -> ***123456 -> *****;
*/MASK$3(key1) -> 12345678 ->123***678; 12345 -> 123***45
DATE_FORMATER: -- yyyy-hh-mm HH:MM:ss.ssss/DATE_FORMATER(key); the placeholder is the formatter. See java.text.SimpleDateFormat
FLOAT_FORMATER: -- #,##0.00/FLOAT_FORMATER(key); the placeholder is the formatter. See java.text.DecimalFormat
DECIMAL_FORMATER: -- same with FLOAT_FORMATER
LoggingUnit
It's a direct transformation of @Logging for the classes or interfaces can't annotate.
import io.bitryon.logger.annotation.LoggingUnit;
import io.bitryon.logger.spring.LoggingMethodPointcut;
public class UserServiceImpl { // impelements UserService {
@Resource
LoggingMethodPointcut loggingMethodPointcut;
@Bean
UserService getUserRPCService() {
return (UserService) loggingMethodPointcut.proxyBeanInstance(// Pointcut to intercept the methods if log on interfaces or class without @Logging.
LoggingUnit.Builder().catchPackages("io.bitryon.example.web.service").build(), //catchLoggingMethod(true)
this.getProxyFactoryBean(UserService.class, this), UserService.class);
}
}