import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.volcengine.model.tls.consumer.ConsumerConfig;
import com.volcengine.model.tls.pb.PutLogRequest;
import com.volcengine.service.tls.consumer.Consumer;
import com.volcengine.service.tls.consumer.ConsumerImpl;
import com.volcengine.service.tls.consumer.LogProcessor;
import org.jetbrains.annotations.NotNull;
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.kinesis.producer.*;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Tls2Kinesis implements LogProcessor, AwsCredentials, FutureCallback<UserRecordResult> {
private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
private KinesisProducer kinesisProducer;
private Consumer tlsConsumer;
private ExecutorService executor;
private String streamArn;
public static void main(String[] args) throws Exception {
Tls2Kinesis tls2Kinesis = new Tls2Kinesis();
tls2Kinesis.initKinesisProducer();
tls2Kinesis.initTlsConsumer();
public void process(String topicID, int shardID, PutLogRequest.LogGroupList logGroupList) {
ByteBuffer data = ByteBuffer.allocate(1024);
List<PutLogRequest.LogGroup> logGroups = logGroupList.getLogGroupsList();
for (PutLogRequest.LogGroup logGroup: logGroups) {
List<PutLogRequest.Log> logs = logGroup.getLogsList();
for (PutLogRequest.Log log: logs) {
this.put(data, "__time__", this.dateFormat.format(new Date(log.getTime())));
this.put(data, "__topic_id__", topicID);
this.put(data, "__shard_id__", String.valueOf(shardID));
this.put(data, "__source__", logGroup.getSource());
this.put(data, "__path__", logGroup.getFileName());
for (PutLogRequest.LogTag tag : logGroup.getLogTagsList()) {
this.put(data, tag.getKey(), tag.getValue());
List<PutLogRequest.LogContent> logContents = log.getContentsList();
for (PutLogRequest.LogContent logContent: logContents) {
this.put(data, logContent.getKey(), logContent.getValue());
ListenableFuture<UserRecordResult> f = this.kinesisProducer.addUserRecord(this.streamArn, String.valueOf(shardID), data);
Futures.addCallback(f, this, this.executor);
public void onSuccess(UserRecordResult result) {
System.out.printf("Successfully added user record, shard: %s, number: %s%n", result.getShardId(), result.getSequenceNumber());
public void onFailure(@NotNull Throwable t) {
if (t instanceof KinesisProducerException) {
UserRecord userRecord = ((KinesisProducerException) t).getUserRecord();
if (t instanceof UserRecordFailedException) {
int attempts = ((UserRecordFailedException) t).getResult().getAttempts().size()-1;
Attempt last = ((UserRecordFailedException) t).getResult().getAttempts().get(attempts);
Attempt previous = ((UserRecordFailedException) t).getResult().getAttempts().get(attempts - 1);
System.out.printf("UserRecord %s failed to put - %s : %s. Previous failure - %s : %s%n",
userRecord, last.getErrorCode(), last.getErrorMessage(), previous.getErrorCode(),
previous.getErrorMessage());
System.out.printf("UserRecord %s failed to put - %s : %s.%n",
userRecord, last.getErrorCode(), last.getErrorMessage());
System.out.printf("UserRecord %s failed to put with unexpected error: %s%n",
System.out.println("Failed to add user record: " + t);
public String accessKeyId() {
public String secretAccessKey() {
private void put(ByteBuffer data, String key, String value) {
data.putChar('"').put(key.getBytes(StandardCharsets.UTF_8)).putChar('"')
.putChar('"').put(value.getBytes(StandardCharsets.UTF_8)).putChar('"');
private void initKinesisProducer() {
String awsRegion = "xxx";n
this.streamArn = "xxx";可
KinesisProducerConfiguration config = new KinesisProducerConfiguration()
.setRecordMaxBufferedTime(300)
.setRequestTimeout(60000)
.setCredentialsProvider(StaticCredentialsProvider.create(this));
this.kinesisProducer = new KinesisProducer(config);
this.executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private void initTlsConsumer() throws Exception {
String tlsEndpoint = "xxx";点
String tlsRegion = "xxx";n
String tlsAccessKeyId = "xxx";y
String tlsAccessKeySecret = "xxx";y
String projectID = "xxx";D
String topicId = "xxx";表
String consumerGroupName = "xxx";称
String consumerName = "xxx";称
ConsumerConfig config = new ConsumerConfig(tlsEndpoint, tlsRegion, tlsAccessKeyId, tlsAccessKeySecret);
config.setProjectID(projectID);
config.setTopicIDList(new ArrayList<String>(){{add(topicId);}});
config.setConsumerGroupName(consumerGroupName);
config.setConsumerName(consumerName);
this.tlsConsumer = new ConsumerImpl(config, this);
this.tlsConsumer.start();
private void stop() throws InterruptedException {
this.tlsConsumer.stop();
this.kinesisProducer.flush();
this.kinesisProducer.destroy();
this.executor.shutdown();