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(); } }