Apache Commons IO cung cấp lớp Tailer để theo dõi nội dung tập tin động, mô phỏng hành vi của lệnh tail -f trên Unix. Công cụ này sử dụng luồng nền để quét định kỳ, phát hiện nội dung mới thêm vào, phù hợp cho giám sát log, xử lý dữ liệu thời gian thực. Dưới đây là cách triển khai và tối ưu hiệu năng.
Tính năng chính
- Theo dõi thay đổi nội dung
- Kiểm tra định kỳ (mặc định 1 giây) để phát hiện dòng mới.
- Hỗ trợ bắt đầu từ đầu hoặc cuối tập tin.
- Cấu hình linh hoạt
- Độ trễ (delayMillis): Khoảng thời gian quét, mặc định 1000ms.
- Mã hóa (Charset): Chọn định dạng tập tin (UTF-8, ISO-8859-1...).
- Bộ đệm (bufferCapacity): Kích thước bộ đệm đọc, mặc định 8192 byte.
- Xử lý xoay vòng tập tin (reOpen): Tự động mở lại tập tin khi bị cắt (logrotate).
- Cơ chế sự kiện
- Giao diện TailerListener hoặc lớp hỗ trợ TailerListenerAdapter nhận sự kiện:
- handle(String content): Khi đọc được dòng mới.
- fileNotFound(): Tập tin không tồn tại.
- fileRotated(): Tập tin bị xoay vòng.
- handle(Exception ex): Xử lý lỗi.
Triển khai cơ bản
import org.apache.commons.io.input.Tailer;
import org.apache.commons.io.input.TailerListenerAdapter;
import java.io.File;
import java.nio.charset.StandardCharsets;
public class FileMonitor {
public static void main(String[] args) {
File appLog = new File("/var/log/app.log");
TailerListenerAdapter eventHandler = new TailerListenerAdapter() {
@Override
public void handle(String line) {
System.out.println("New entry: " + line);
}
};
Tailer monitor = new Tailer(
appLog,
StandardCharsets.UTF_8,
eventHandler,
500,
true,
true
);
Thread watchThread = new Thread(monitor);
watchThread.setDaemon(true);
watchThread.start();
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
Cấu hình nâng cao
Dùng Builder pattern (từ phiên bản 2.21.0+):
import org.apache.commons.io.input.Tailer;
import java.io.File;
import java.nio.charset.StandardCharsets;
public class AdvancedMonitor {
public static void main(String[] args) {
File logFile = new File("/var/log/app.log");
Tailer monitor = Tailer.builder()
.setFile(logFile)
.setCharset(StandardCharsets.UTF_8)
.setListener(new TailerListenerAdapter() {
@Override
public void handle(String line) {
System.out.println("Processed: " + line);
}
})
.setDelayMillis(300)
.setFollowEnd(true)
.setReOpen(true)
.setBufferSize(32768)
.get();
Thread monitorThread = new Thread(monitor);
monitorThread.start();
}
}
Lưu ý quan trọng
- Quyền truy cập tập tin: Đảm bảo ứng dụng có quyền đọc tập tin, tránh sự kiện fileNotFound().
- Xử lý log rotate: Bật reOpen=true hoặc ghi đè fileRotated() khi tập tin bị cắt.
- Tối ưu hiệu năng:
- Độ trễ: 300-500ms cho log dày đặc, 1-3s cho log thưa thớt.
- Bộ đệm: Tăng lên 32KB/64KB cho tập tin lớn.
- Xử lý lỗi: Ghi đè handle(Exception) để không ngắt luồng.
- Giải phóng tài nguyên: Gọi monitor.stop() khi dừng, hoặc dùng setDaemon(true).
- An toàn đa luồng: Tailer an toàn đa luồng, nhưng TailerListener phải đảm bảo đồng bộ.
Trường hợp áp dụng
- Giám sát log ứng dụng (Nginx, Tomcat) thời gian thực.
- Xử lý dữ liệu mới trong ETL pipeline.
- Xây dựng công cụ phân tích log đơn giản với lọc từ khóa.
Phù hợp phiên bản
- Apache Commons IO 2.0+: Hỗ trợ cơ bản.
- Apache Commons IO 2.21.0+: Ưu tiên dùng Builder pattern.
Sử dụng Tailer kết hợp TailerListenerAdapter giúp triển khai theo dõi tập tin hiệu quả, tối ưu hóa code và dễ bảo trì. Trong môi trường sản xuất, kết hợp với framework log (SLF4J) và quản lý luồng để nâng cao độ tin cậy.