import org.apache.log4j.Logger;
import com.baeldung.mdc.TransferService;
public abstract class TransferService {
public boolean transfer(long amount) {
// connects to the remote service to actually transfer money
}
abstract protected void beforeTransfer(long amount);
abstract protected void afterTransfer(long amount, boolean outcome);
}
public class Log4JTransferService extends TransferService {
private Logger logger = Logger.getLogger(Log4JTransferService.class);
@Override
protected void beforeTransfer(long amount) {
logger.info("Preparing to transfer " + amount + "$.");
}
@Override
protected void afterTransfer(long amount, boolean outcome) {
logger.info(
"Has transfer of " + amount + "$ completed successfully ? " + outcome + ".");
}
}
public class TransferDemo {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3);
TransactionFactory transactionFactory = new TransactionFactory();
for (int i = 0; i < 10; i++) {
Transfer tx = transactionFactory.newInstance();
Runnable task = new Log4JRunnable(tx);
executor.submit(task);
}
executor.shutdown();
}
}
public class Log4JRunnable implements Runnable {
private Transfer tx;
public Log4JRunnable(Transfer tx) {
this.tx = tx;
}
public void run() {
log4jBusinessService.transfer(tx.getAmount());
}
}
...
519 [pool-1-thread-3] INFO Log4JBusinessService
- Preparing to transfer 1393$.
911 [pool-1-thread-2] INFO Log4JBusinessService
- Has transfer of 1065$ completed successfully ? true.
911 [pool-1-thread-2] INFO Log4JBusinessService
- Preparing to transfer 1189$.
989 [pool-1-thread-1] INFO Log4JBusinessService
- Has transfer of 1350$ completed successfully ? true.
989 [pool-1-thread-1] INFO Log4JBusinessService
- Preparing to transfer 1178$.
1245 [pool-1-thread-3] INFO Log4JBusinessService
- Has transfer of 1393$ completed successfully ? true.
1246 [pool-1-thread-3] INFO Log4JBusinessService
- Preparing to transfer 1133$.
1507 [pool-1-thread-2] INFO Log4JBusinessService
- Has transfer of 1189$ completed successfully ? true.
1508 [pool-1-thread-2] INFO Log4JBusinessService
- Preparing to transfer 1907$.
1639 [pool-1-thread-1] INFO Log4JBusinessService
- Has transfer of 1178$ completed successfully ? true.
1640 [pool-1-thread-1] INFO Log4JBusinessService
- Preparing to transfer 674$.
...
이러한 상황을 MDC를 사용해 해결할 수 있다.
import org.slf4j.MDC;
public class Slf4jRunnable implements Runnable {
private final Transaction tx;
public Slf4jRunnable(Transaction tx) {
this.tx = tx;
}
public void run() {
MDC.put("transaction.id", tx.getTransactionId());
MDC.put("transaction.owner", tx.getOwner());
new Slf4TransferService().transfer(tx.getAmount());
MDC.clear();
}
}
MDC.put()은 key value를 추가하는데 사용됨MDC.clear()는 MDC 로그를 비우는데 사용<configuration>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%-4r [%t] %5p %c{1} - %m - tx.id=%X{transaction.id} tx.owner=%X{transaction.owner}%n</pattern>
</encoder>
</appender>
<root level="TRACE">
<appender-ref ref="stdout" />
</root>
</configuration>
1020 [pool-1-thread-3] INFO c.b.m.s.Slf4jBusinessService
- Has transfer of 1869$ completed successfully ? true. - tx.id=3 tx.owner=John
1021 [pool-1-thread-3] INFO c.b.m.s.Slf4jBusinessService
- Preparing to transfer 1303$. - tx.id=6 tx.owner=Samantha
1221 [pool-1-thread-1] INFO c.b.m.s.Slf4jBusinessService
- Has transfer of 1498$ completed successfully ? true. - tx.id=4 tx.owner=Marc
1221 [pool-1-thread-1] INFO c.b.m.s.Slf4jBusinessService
- Preparing to transfer 1528$. - tx.id=7 tx.owner=Samantha
1492 [pool-1-thread-2] INFO c.b.m.s.Slf4jBusinessService
- Has transfer of 1110$ completed successfully ? true. - tx.id=5 tx.owner=Samantha
1493 [pool-1-thread-2] INFO c.b.m.s.Slf4jBusinessService
- Preparing to transfer 644$. - tx.id=8 tx.owner=John
MDC.clear()로 MDC의 값을 비워줘야 한다.실제로 회사에서 키바나에 url이 이상하게 찍혔던 적이 있는데, 다음 글에는 이를 해결한 방법을 간단하게 작성해보겠다.