Get Started
Full Preview
This is all you need to run bitryon logger - although much info need to consume.
Configuration file
bitryon:
logger:
file-name: ./logs/${spring.application.name} # will be like ./logs/bitryon-logging-java-spring-example.20250415-161023-565.0.log
file-max-length: 536870912
print-stdout: true # print to console
print-file: true # write to file
log-date-time-format: yyyy-MM-dd HH:mm:ss.SSS # UTC. the time on the head of the log. Leave blank will print System.currentTimeMillis
log-async: true # false blocking IO; true NIO write files, it could lose part of logs if JVM crashes
log-light: false # full step info, or light. true: MedicController.java#io.bitryon.web.controller.MedicController#query#123; no thread info, type JSON->J, false: #.MedicController#query#123 [the sanitizer-patterns may be slightly different].
log-pretty: true # print pretty json and log, by new line and intends. close it in prd if needed.
log-sanitizer-patterns: >
/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)
app-node:
http-header-id-type: 1 # write log/trace id to the http response header; 0 default no write header, 1 trace id, 2 step log id
application-name: ${spring.application.name}
host-id: node-123.test.test # unique, with file to identify unique file
github: # optional
host: https://github.com/
source-paths: >
src/main/java
repository: RepoOwner/${spring.application.name} # project on github
branch: master
commit: xxxxxxx
boot-info: # for info purpose, bitryon don't use it
version: 1.2.3 # the version of the app.
internal-ip: 12.2.2.2
external-ip: 12.2.2.2
program: 1.2.2-1231321.jar
region: use-1
platform:
cloud: aws
Initiate bitryon logger
Initiate logger at the very beginning:
// In Spring
public static void main(String[] args) {
io.bitryon.logger.boostrap.LoggingProxyInitiation.premain(null); // must load before everything.
//or add https://github.com/FrankNPC/bitryon-logging-tracing-examples/blob/master/bitryon-logging-java-spring-example/src/main/resources/META-INF/spring.factories
new SpringApplicationBuilder(ServerBootApplication.class).run(args);
}
// In java
public static void main(String[] args) {
LoggingProxyInitiation.premain(null);
LoggerProvider provider = LoggerProvider.getProvider("bitryon_log.properties", null);
new LoggingMethodIntercepter(provider);
}
Load bitryon logger
Load logger to write and read step log id (trace id) over HTTP:
// write step log id (trace id) header to the HTTP client, in your bean
public class ExampleWebHTTPClient {
@Resource
LoggerProvider bitryonLoggerProvider;
public RestClient getRestClient() {
return RestClient
.builder(new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient())))
.baseUrl(getBaseUrl())
// write step log id to the http request header to the next app/service to form traces
.requestInterceptor(new LoggingHttpClientHeaderWriterInterceptor(bitryonLoggerProvider))
.build();
}
}
// read step log id (trace id) header by filter in spring web
@Configuration
@Import(value= {
AutoConfigurationBitryonLogger.class, // to load the configs from application.yml for logging related beans
})
public class ExampleWebServerConfiguration {
@Resource
LoggerProvider bitryonLoggerProvider;
// read step log id from last app/service/http request header to form traces, and log http payload for specific paths
@Bean
FilterRegistrationBean<LoggingHttpRequestWebFilter> loggingResetInFilter() {
FilterRegistrationBean<LoggingHttpRequestWebFilter> reg = new FilterRegistrationBean<>(
new LoggingHttpRequestWebFilter(bitryonLoggerProvider, true));
reg.setOrder(Ordered.HIGHEST_PRECEDENCE);
reg.addUrlPatterns("/api", "/api/*", "/remote_api/*");
return reg;
}
}
Write logs
Write logs through @Logging and logger.log() both:
package io.bitryon.example.web.service.rpc;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.springframework.stereotype.Service;
import io.bitryon.example.web.model.User;
import io.bitryon.logger.Logger;
import io.bitryon.logger.annotation.Logging;
import io.bitryon.spring.rmi.http.prodiver.Provider;
import jakarta.annotation.Resource;
@Provider("/remote_api/") // RPC service
@Service
@Logging
public class UserServiceImpl { // impelements UserService {
@Resource
Logger logger;
//private static final Logger logger = LoggerFactory.getLogger(); // both work. recommended
public User getById(Long userId){
if (userId==null) {
return null;
}
logger.text("This should be remote service, will be with trace for user {}", userId);
User user = new User();
user.setId(123L);
try {
SimpleDateFormat simpleDateFormater = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
user.setBirthday(simpleDateFormater.parse("2025-08-10T15:42:17.123+02"));
} catch (ParseException e) {
logger.exception(e);
}
user.setDriverLisenceId("a number that you can't know");
user.setName("randome guy probably");
return user;
}
}
Sanitize logs
Specify Logging on methods through annotation:
package io.bitryon.example.web.service;
import org.springframework.stereotype.Service;
import io.bitryon.logger.Logger;
import io.bitryon.logger.annotation.Logging;
import io.bitryon.logger.provider.LoggerFactory;
@Service
public class SMTPEmailService {
private static final Logger logger = LoggerFactory.getLogger();
@Logging(sanitizerPatterns="*/MASK$3(recipient)", skipRandom=Integer.MAX_VALUE >>> 1)// mask the recipient JSON/*EmailService.sendByNoRepply*
public String sendVerificationUrl(String recipient, String verificationUrl) {
recipient = recipient.trim();
String htmlContent =
"<html><body>Please click on the <a href='"+verificationUrl+"'>link</a> "
+ "or copy " + verificationUrl + " to your brower before it expires in 10 minutes.</body></html>";
logger.text(htmlContent);// specially log it but still be count in the traces
return htmlContent;
}
}
Full logs
Some examples from the beginning:
2026-08-05T13:36:07.938Z||Z9z2xqC5hIKa3zYh||CONF||
[{
"BootInfo": {
"program": "1.2.2-1231321.jar",
"region": "use-1",
"version": "1.2.3",
"external-ip": "12.2.2.2",
"internal-ip": "12.2.2.2",
"platform": {
"cloud": "aws"
}
},
"AppNodeConfig": {
"httpHeaderIdType": 1,
"applicationName": "bitryon-logging-java-spring-example",
"hostId": "node-123.test.test"
},
"Github": {
"host": "https://github.com/",
"repository": "RepoOwner/bitryon-logging-java-spring-example",
"branch": "master",
"commit": "xxxxxxx",
"sourcePaths": [
"src/main/java"
]
},
"LoggerConfig": {
"fileName": "./logs/bitryon-logging-java-spring-example",
"fileMaxLength": 536870912,
"logDateTimeFormat": "yyyy-MM-dd HH:mm:ss.SSS",
"loggerSchemaVersion": "1.0",
"logLight": false,
"logPretty": true,
"printFile": true,
"printStdout": true,
"logAsync": true,
"logSanitizerPatterns": [
"/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)"
]
}
}]
2026-08-05 13:36:09.601|http-nio-80-exec-1#40|d21DXYk95tsqlA48XMszjqDyMbz0zesH|1|HTTP|
LoggingHttpRequestWebReader.java#io.bitryon.logger.spring.LoggingHttpRequestWebReader#readHttpRequest#31|
[null,{
"remoteHost": "0:0:0:0:0:0:0:1:64498"
},{
"method": "GET"
},{
"requestURL": "http://localhost/api/user/save"
},{
"headers": {}
},{
"body": {
"name": [
"br***ng"
],
"driverLisenceId": [
"6unq9XnrLfyeBSGpBVBftm"
],
"age": [
"1001"
]
}
}]
2026-08-05 13:36:15.668|http-nio-80-exec-4#43|e4oPCb2nXz6lDwMFzW2YZYDTFlsbr7v5|5|JSON|
MedicService.java#io.bitryon.example.web.service.MedicService#save#48#|
[{
"condition": {
"id": 123,
"deceases": "unko**",
"timeCreated": "1970-01-01 00:00:00.0000",
"userId": 0
}
}]
2026-08-05 13:36:15.669|http-nio-80-exec-4#43|e4oPCb2nXz6lDwMFzW2YZYDTFlsbr7v5|6|JSON|
MedicDAO.java#io.bitryon.example.web.dao.MedicDAO#save#36#|
[{
"condition": {
"id": 123,
"deceases": "unko**",
"timeCreated": "1970-01-01 00:00:00.0000",
"userId": 0
}
}]
2026-08-05 13:36:15.670|http-nio-80-exec-4#43|e4oPCb2nXz6lDwMFzW2YZYDTFlsbr7v5|7|JSON|
MedicDAO.java#io.bitryon.example.web.dao.MedicDAO#save#36#R|
[{
"id": 123,
"deceases": "unko**",
"timeCreated": "1970-01-01 00:00:00.0000",
"userId": 0
}]
2026-08-05 13:36:15.670|http-nio-80-exec-4#43|e4oPCb2nXz6lDwMFzW2YZYDTFlsbr7v5|8|JSON|
MedicService.java#io.bitryon.example.web.service.MedicService#save#54|
[{
"userId": 0
}]
2026-08-05 13:36:15.683|http-nio-80-exec-4#43|e4oPCb2nXz6lDwMFzW2YZYDTFlsbr7v5|9|JSON|
MedicService.java#io.bitryon.example.web.service.MedicService#save#54R|
[{
"name": "ra***ly",
"id": 123,
"driverLisenceId": "WcReqeCH5tn7oeSNcfHyL1Ae04Q0waysU4hlSdiLtYZ",
"age": null
}]
2026-08-05 13:36:15.683|http-nio-80-exec-4#43|e4oPCb2nXz6lDwMFzW2YZYDTFlsbr7v5|10|JSON|
MedicService.java#io.bitryon.example.web.service.MedicService#save#48#R|
[{
"medicConditionDO": {
"id": 123,
"deceases": "unko**",
"timeCreated": "1970-01-01 00:00:00.0000",
"userId": 0
},
"user": {
"name": "ra***ly",
"id": 123,
"driverLisenceId": "WcReqeCH5tn7oeSNcfHyL1Ae04Q0waysU4hlSdiLtYZ",
"age": null
}
}]
Workflow view
Finally, Sign-in and upload logs to portal for workflow-like view: 
✨ Just like thatNow you own trinity observability.