日志同步服务 - Nebula.Log2DB

使用背景:

  • 应用程序将OprLog日志写入到ES中,这些日志包含了用户的访问情况
  • 运营从员希望从SQL数据库中统计应用程序的访问情况

服务用途:

  • 从ES中 持续获取 OprLog,并写入MySQL

实现方法:

  • 先从Redis获取 "上次处理时间",第一次运行取上一个周期时间
  • 根据上次处理时间,查询只到最近 N 分钟前的数据
  • 将查询出来的数据写入 MySQL数据库
  • 将最后的处理时间写回Redis供下次使用
  • 持续执行以上4个步骤



配置文件(ClownFish.App.config)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
        <add key="configServiceUrl" value="http://LinuxTest:8503" />
        <add key="MySqlClientProviderSupport" value="2" />

        <!--后台任务的执行间隔时间,单位:秒-->
        <add key="MainWorker_SleepSeconds" value="3600" />

        <!--日志查询过滤条件,多个名称用分号隔开,可以不指定(表示不做过滤条件) -->
        <add key="QueryFilter_AppNames" value="Uranus.TxApp;Aries.AIReportApp"/>
        
        <!--日志查询过滤条件,多个名称用分号隔开,可以不指定(表示不做过滤条件) -->
        <add key="QueryFilter_OprKinds" value="httpin"/>

        <!--日志查询过滤条件,只允许指定一个,可以不指定(表示不做过滤条件) -->
        <add key="QueryFilter_EnvName" value="MilkyWay"/>

        <!--查询过滤条件,查询几分钟前的数据-->
        <add key="QueryFilter_SecondsAgo" value="180"/>

        <!--数据保存目标-->
        <add key="SaveToDb_ConnName" value="logging-db"/>

    </appSettings>
    
</configuration>



输出表结构

CREATE TABLE `website_oprlog`  (
  `RowId` bigint NOT NULL AUTO_INCREMENT,
  `OprKind` varchar(255)  NOT NULL,
  `OprId` varchar(64)  NOT NULL,
  `OprName` varchar(255)  NOT NULL,
  `ParentId` varchar(64)  NULL,
  `RootId` varchar(64)  NULL,
  `StartTime` datetime(0) NOT NULL,
  `Duration` bigint NOT NULL,
  `Status` int NOT NULL,
  `IsSlow` int NOT NULL,
  `HasError` int NOT NULL,
  `TenantId` varchar(255)  NULL,
  `UserId` varchar(255)  NULL,
  `UserCode` varchar(255)  NULL,
  `UserName` varchar(255)  NULL,
  `UserRole` varchar(255)  NULL,
  `BizId` varchar(255)  NULL,
  `BizName` varchar(255)  NULL,
  `HttpMethod` varchar(255)  NULL,
  `Url` varchar(2048)  NOT NULL,
  `UserAgent` varchar(255)  NULL,
  `HttpRef` varchar(2048)  NULL,
  `Module` varchar(255)  NULL,
  `Controller` varchar(255)  NULL,
  `Action` varchar(255)  NULL,
  `ExType` varchar(255)  NULL,
  `ExMessage` text  NULL,
  `ExAll` longtext  NULL,
  `OprDetails` longtext NULL,
  `CtxData` longtext  NULL,
  `Addition` longtext  NULL,
  `AppName` varchar(255)  NOT NULL,
  `HostName` varchar(255)  NOT NULL,
  `EnvName` varchar(255)  NOT NULL,
  PRIMARY KEY (`RowId`),
  UNIQUE INDEX `OprId_idx`(`OprId`) ,
  INDEX `StartTime_idx`(`StartTime`) ,
  INDEX `AppName_idx`(`AppName`) 
) ENGINE = InnoDB CHARACTER SET = utf8mb4 ;



部署过程

  • 创建一个用于存储日志的数据库,并执行上面的SQL脚本(website_oprlog)
  • 在配置服务中增加一个 “数据库连接” name=logging-db ,指向包含website_oprlog表的数据库
  • 在配置服务中增加一个 "配置文件" name=Nebula.Log2DB.App.Config,内容参考前面的ClownFish.App.config
  • 修改配置服务的 "配置文件" name=Nebula.Juno.ArchiveOption.json,增加对website_oprlog表的定时清理,可参考下面配置
  "Databases": [
   {....现有配置....},
	{
      "DbName": "logging-db",
      "Tables": [
        {
          "TableName": "website_oprlog",
          "IdFieldName": "RowId",
          "TimeFieldName": "StartTime"
        }
      ]
    }
  ]