package com.taobao.yugong.common.audit;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import com.taobao.yugong.common.db.meta.ColumnValue;
import com.taobao.yugong.common.model.position.Position;
import com.taobao.yugong.common.model.record.IncrementOpType;
import com.taobao.yugong.common.model.record.IncrementRecord;
import com.taobao.yugong.common.model.record.Record;
/**
* 记录一下同步过程中的record数据
*
* @author agapple 2013-9-23 下午2:13:46
*/
public class RecordDumper {
private static final Logger extractorLogger = LoggerFactory.getLogger("extractor");
private static final Logger applierLogger = LoggerFactory.getLogger("applier");
private static final String SEP = SystemUtils.LINE_SEPARATOR;
private static final String TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss:SSS";
private static String extractor_format = null;
private static String applier_format = null;
private static String record_format = null;
private static int record_default_capacity = 1024; // 预设值StringBuilder,减少扩容影响
static {
extractor_format = "* batchId : [{0}] , total : [{1}] , lastPosition [{2}] , Time : {3} " + SEP;
applier_format = "* batchId : [{0}] , extractorSize : [{1}] , applierSize : [{2}] , ackPosition [{3}] , Time : {4} "
+ SEP;
record_format = "-----------------" + SEP;
record_format += "- Schema: {0} , Table: {1} , Type: {2}" + SEP;
record_format += "-----------------" + SEP;
record_format += "---Pks" + SEP;
record_format += "{3}" + SEP;
record_format += "---Columns" + SEP;
record_format += "{4}" + SEP;
record_format += "---END" + SEP;
}
public static void dumpExtractorInfo(Long batchId, List<Record> records, Position lastPosition, boolean dumpDetail) {
extractorLogger.info(SEP + "****************************************************" + SEP);
Date now = new Date();
SimpleDateFormat format = new SimpleDateFormat(TIMESTAMP_FORMAT);
extractorLogger.info(MessageFormat.format(extractor_format,
String.valueOf(batchId),
records.size(),
ObjectUtils.toString(lastPosition),
format.format(now)));
extractorLogger.info("****************************************************" + SEP);
if (dumpDetail) {// 判断一下是否需要打印详细信息
extractorLogger.info(dumpRecords(records));
extractorLogger.info("****************************************************" + SEP);
}
}
public static void dumpApplierInfo(Long batchId, List<Record> extractorRecords, List<Record> applierRecords,
Position position, boolean dumpDetail) {
applierLogger.info(SEP + "****************************************************" + SEP);
Date now = new Date();
SimpleDateFormat format = new SimpleDateFormat(TIMESTAMP_FORMAT);
applierLogger.info(MessageFormat.format(applier_format,
String.valueOf(batchId),
extractorRecords.size(),
applierRecords.size(),
ObjectUtils.toString(position),
format.format(now)));
applierLogger.info("****************************************************" + SEP);
if (dumpDetail) {// 判断一下是否需要打印详细信息,目前只打印applier信息,分开打印
applierLogger.info(dumpRecords(applierRecords));
applierLogger.info("****************************************************" + SEP);
}
}
public static String dumpRecords(List<Record> records) {
if (CollectionUtils.isEmpty(records)) {
return StringUtils.EMPTY;
}
// 预先设定容量大小
StringBuilder builder = new StringBuilder(record_default_capacity * records.size());
for (Record record : records) {
builder.append(dumpRecord(record));
}
return builder.toString();
}
public static String dumpRecord(Record record) {
IncrementOpType type = IncrementOpType.I;
if (record instanceof IncrementRecord) {
type = ((IncrementRecord) record).getOpType();
}
return MessageFormat.format(record_format,
record.getSchemaName(),
record.getTableName(),
type,
dumpRecordColumns(record.getPrimaryKeys()),
dumpRecordColumns(record.getColumns()));
}
public static String dumpRecordColumns(List<ColumnValue> columns) {
StringBuilder builder = new StringBuilder(record_default_capacity);
int size = columns.size();
for (int i = 0; i < size; i++) {
ColumnValue column = columns.get(i);
builder.append("\t").append(ObjectUtils.toString(column));
if (i < columns.size() - 1) {
builder.append(SEP);
}
}
return builder.toString();
}
}