/** * Copyright 2016, Xiaomi. * All rights reserved. * Author: xiajun@xiaomi.com */ package com.xiaomi.infra.galaxy.lcs.log.core.appender; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOError; import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; import java.util.List; import libthrift091.TException; import com.xiaomi.infra.galaxy.lcs.log.core.ILogger; import com.xiaomi.infra.galaxy.lcs.log.core.thrift.LCSThriftClient; import com.xiaomi.infra.galaxy.lcs.thrift.ErrorCode; import com.xiaomi.infra.galaxy.lcs.thrift.GalaxyLCSException; import com.xiaomi.infra.galaxy.lcs.thrift.LCSThriftService; import com.xiaomi.infra.galaxy.lcs.thrift.Record; import com.xiaomi.infra.galaxy.talos.client.Constants; import com.xiaomi.infra.galaxy.talos.client.serialization.MessageSerialization; import com.xiaomi.infra.galaxy.talos.client.serialization.MessageSerializationFactory; import com.xiaomi.infra.galaxy.talos.thrift.Message; public class LCSThriftAppenderImpl extends LCSAppender { private String lcsAgentHostname; private int lcsAgentPort; private int bufferSize; private ByteArrayOutputStream byteArrayOutputStream; private DataOutputStream dataOutputStream; private LCSThriftClient lcsThriftClient; public LCSThriftAppenderImpl(ILogger logger) { super(logger); this.lcsAgentHostname = "127.0.0.1"; this.lcsAgentPort = -1; // ATTENTION: right we think serialized message never longer than // signalMessageBytes * 2, there is risk that message header is longer // than signalMessageBytes, but this will not happen in the foreseeable // future; this.bufferSize = Constants.TALOS_SINGLE_MESSAGE_BYTES_MAXIMAL * 2; this.byteArrayOutputStream = new ByteArrayOutputStream(bufferSize); this.dataOutputStream = new DataOutputStream(byteArrayOutputStream); } public String getLcsAgentHost() { return lcsAgentHostname; } public void setLcsAgentHost(String lcsAgentHostname) { this.lcsAgentHostname = lcsAgentHostname; } public int getLcsAgentPort() { return lcsAgentPort; } public void setLcsAgentPort(int lcsAgentPort) { this.lcsAgentPort = lcsAgentPort; } @Override protected void doStart() { if (lcsAgentPort == -1) { throw new RuntimeException("please set lcsAgentPort"); } lcsThriftClient = new LCSThriftClient(logger, lcsAgentHostname, lcsAgentPort); } @Override protected void doFlushMessage(List<Message> messageList) throws Exception { Record record = new Record(); record.setTopicName(topicName); List<ByteBuffer> dataList = new ArrayList<ByteBuffer>(); try { for (Message message : messageList) { byteArrayOutputStream.reset(); MessageSerialization.serializeMessage(message, dataOutputStream, MessageSerializationFactory.getDefaultMessageVersion()); dataList.add(ByteBuffer.wrap(byteArrayOutputStream.toByteArray())); } } catch (IOException e) { logger.error("Topic:" + topicName + " serialize message failed", e); throw e; } record.setData(dataList); try { LCSThriftService.Client recordClient = lcsThriftClient.getClient(); if (recordClient == null) { throw new GalaxyLCSException(ErrorCode.AGENT_NOT_READY); } lcsThriftClient.getClient().Record(record); } catch (GalaxyLCSException e) { logger.error("Topic: " + topicName + " sendMessage to LcsAgent: " + lcsThriftClient.getLcsAgentInfo() + " failed", e); throw e; } catch (TException e) { logger.error("Topic: " + topicName + " sendMessage to LcsAgent: " + lcsThriftClient.getLcsAgentInfo() + " failed, may be LcsAgent is not " + "ready", e); lcsThriftClient.resetClient(); throw e; } } @Override protected void doPeriodCheck() { } @Override protected void doClose() { } }