using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using CanalSharp.Client.Impl;
using CanalSharp.Common.Logging;
using Com.Alibaba.Otter.Canal.Protocol;
using Microsoft.Extensions.Logging;
using NLog;
using NLog.Config;
using NLog.Extensions.Logging;
using ILogger = Microsoft.Extensions.Logging.ILogger;
namespace CanalSharp.SimpleClient
{
static class Program
{
private static ILogger _logger;
static void Main(string[] args)
{
LogManager.Configuration = new XmlLoggingConfiguration("NLog.Config");
//设置 NLog
CanalSharpLogManager.LoggerFactory.AddNLog();
_logger = CanalSharpLogManager.LoggerFactory.CreateLogger("Program");
//canal 配置的 destination,默认为 example
var destination = "example";
//创建一个简单 CanalClient 连接对象(此对象不支持集群)传入参数分别为 canal 地址、端口、destination、用户名、密码
var connector = CanalConnectors.NewSingleConnector("127.0.0.1", 11111, destination, "", "");
//连接 Canal
connector.Connect();
//订阅,同时传入 Filter。Filter是一种过滤规则,通过该规则的表数据变更才会传递过来
//允许所有数据 .*\\..*
//允许某个库数据 库名\\..*
//允许某些表 库名.表名,库名.表名
connector.Subscribe(".*\\..*");
while (true)
{
//获取数据 1024表示数据大小 单位为字节
var message = connector.Get(1024);
//批次id 可用于回滚
var batchId = message.Id;
if (batchId == -1 || message.Entries.Count <= 0)
{
Thread.Sleep(300);
continue;
}
PrintEntry(message.Entries);
}
}
///
/// 输出数据
///
/// 一个entry表示一个数据库变更
private static void PrintEntry(List entrys)
{
foreach (var entry in entrys)
{
if (entry.EntryType == EntryType.Transactionbegin || entry.EntryType == EntryType.Transactionend)
{
continue;
}
RowChange rowChange = null;
try
{
//获取行变更
rowChange = RowChange.Parser.ParseFrom(entry.StoreValue);
}
catch (Exception e)
{
_logger.LogError(e.ToString());
}
if (rowChange != null)
{
//变更类型 insert/update/delete 等等
EventType eventType = rowChange.EventType;
//输出binlog信息 表名 数据库名 变更类型
_logger.LogInformation(
$"================> binlog[{entry.Header.LogfileName}:{entry.Header.LogfileOffset}] , name[{entry.Header.SchemaName},{entry.Header.TableName}] , eventType :{eventType}");
//输出 insert/update/delete 变更类型列数据
foreach (var rowData in rowChange.RowDatas)
{
if (eventType == EventType.Delete)
{
PrintColumn(rowData.BeforeColumns.ToList());
}
else if (eventType == EventType.Insert)
{
PrintColumn(rowData.AfterColumns.ToList());
}
else
{
_logger.LogInformation("-------> before");
PrintColumn(rowData.BeforeColumns.ToList());
_logger.LogInformation("-------> after");
PrintColumn(rowData.AfterColumns.ToList());
}
}
}
}
}
///
/// 输出每个列的详细数据
///
///
private static void PrintColumn(List columns)
{
foreach (var column in columns)
{
//输出列明 列值 是否变更
Console.WriteLine($"{column.Name} : {column.Value} update= {column.Updated}");
}
}
}
}