统一日志框架,居然是这样的!

栏目:云苍穹知识作者:金蝶来源:金蝶云社区发布:2024-09-23浏览:1

统一日志框架,居然是这样的!

在软件开发中,日志记录是非常重要的,可以帮助开发人员追踪和排查问题,了解应用程序的运行情况,提高代码质量。


苍穹系统的原有日志存储并不统一,不同业务在不同的分库中记录着日志表,导致日志管理不方便,业务库存储不断膨胀。


因此,苍穹提供了一个统一的日志框架,可以对日志进行统一存储与管理,同时提供日志表单模型开发功能,减小开发者工作量。


本期我们来唠唠“统一日志框架”,教你高效使用日志!




基本介绍


苍穹平台升级原有的日志存储、查询和管理方案为新的统一日志框架。


该框架分离业务存储和日志存储,为业务运行预留空间,并支持Elasticsearch数据库(以下简称ES)的存储与日志查询,提高大数据下的日志搜索性能。


该框架包括一个日志表单页面模型,两大数据库存储日志:Elasticsearch (ES)和Database (DB),以及三大日志功能:写入、管理和查询。


另外还有六大功能模块:Log元数据、Log序时簿、框架API写入/查找、Log管理、存储设计和管理界面。功能说明如下:


    重要模块

                                                                 说明

   Log元数据

由于ES数据库架构限制,统一日志框架存储支持4类元数据, 对日志存储的命名和字段类型有要求。


1.元数据标识命名规范:

(1)字段名称由数字、字母及下划线组成,由字母开头;

(2)全部小写命名、下划线分割;

(3)总长度不超过32个字符;

(4)不能使用保留字/关键字作为字段名。


2.字段类型支持:整型(integer,long)、字符型(string)、浮点型(float, double)、时间型(date, time, timestamp)。

    Log序时簿

Log序时簿为日志表单,由单据扩展而来,可使用模板创建。与单据的区别为:


1.控件:Log序时簿不支持业务字段、单据体等,支持容器、导航和通用字段;


2.属性:Log序时簿不支持拆分表、单据关联相关属性;


3.Log序时簿不支持扩展继承。

LogORM

日志框架提供统一的API接口记录日志数据,写入到ES或DB日志数据库,进行日志查询。API根据日志开关切换,用户无需关心走DB还是ES。具体请查看下文API介绍说明。

存储设计

ES日志存储按租户隔离,统一存储;DB日志统一存放到Log日志库,降低业务负载。


使用流程


图1 使用流程图


流程总体说明如下:

  • 超级管理员开启或关闭ES数据库日志存储开关,并选择日志存储方式;

  • 由日志表单元模型,创建日志表单,并配置日志表单与控件属性;

  • 使用统一的API接口记录单据的操作等日志数据,并写入到ES或DB日志数据库;

  • 在日志列表中查看日志记录,并支持日志查询。


PS:统一日志框架依赖MC补丁,版本号为4.0.006。在使用统一日志框架之前,需要先更新MC补丁版本。在使用统一日志框架的过程中,需要遵循一定的规范:如,日志如果想要增删改字段,需重新建表记录日志;日志数据库选定ES/DB后,不应随意切换;各业务场景切换日志数据库或变更字段时,需自行考虑历史数据升级;初次使用统一日志框架时,需要依据框架重写日志。

1. 选择日志库


(1)日志需要先由管理员配置,选择用DB或ES存储日志;

(2)平台所有日志存储只能统一选择DB或ES中的一种

(3)启用DB日志库时,关闭【启用ES存储日志】;

(4)启用ES日志库时,开启【启用ES存储日志】。


图2 启用ES存储日志

2. 日志表单开发


统一日志框架为日志开发专门设计了日志表单元模型。日志表单用于记录要写入库的字段。


图3 选择“日志表单”


图4 记录要写入库的字段


(1)日志表单业务逻辑


  • 日志表单由单据扩展而来,可直接在开发平台设计器创建、拖入控件、配置属性;

  • 业务单据通过调用写入API,绑定表单中的字段,写入日志;

  • 一个日志表单通常可以对应一种日志类型;

  • 选择ES存储时,日志表单没有DB库意义上的实体;选择DB存储时,所有日志全部存储到同一个log日志库中。


注意:为防范二次开发风险,日志表单模板中的字段必录。不使用这些字段时,可不写入字段、不在日志列表显示。


(2)日志表单控件约束


由于ES数据库Log元数据类型限制,日志表单仅支持以下控件:

  • 通用字段:

      -文本类:文本、多行文本、大文本;

      -数值类:整数、长整数、小数;

      -时间类:日期、长日期、时间;

      -其他:下拉列表、多选下拉列表;

  • 容器控件;

  • 导航控件。


(3)日志表单属性约束


由于ES数据库架构特点,日志表单相比单据的属性有如下区别:

  • 日志表单根页面属性部分不支持:关联配置,委托关系,业务控制,单据状态字段,单据参数,单据类型参数,拆分表,主键类型,扩展继承;

  • 日志表单无扩展继承;

  • 日志表单无拆分表;

  • 日志表单字段无加密存储。

3. 日志列表开发


日志列表用于日志的显示和查询,点击日志表单的【列表】页签进入。


图5 列表表单模版


(1)列表开发业务逻辑


  • 日志列表默认使用bos_loglist为列表表单模板,页面内容包括:时间过滤、快速搜索、刷新、退出、单据列表、表头过滤等;

  • 此模板适合于简单日志快速使用;

  • 时间筛选可快速下拉选择或自定义;

  • 时间筛选最长支持最近三个月。


(2)列表开发约束规范


  • 文本类模糊搜索支持前2000字符;

  • 不支持带*号搜索;

  • ES数据库不支持自定义排序;

  • 使用bos_loglist时,无法直接在日志列表中添加过滤项。如需求复杂,建议用标准列表表单模板bos_list代替(标准列表表单模板),使用方法和单据列表一致,此时支持快速搜索(模糊搜索)、方案过滤、常用过滤等。


API介绍


统一日志框架提供LogORM接口进行日志表单的查询与写入,开发者无需关心日志单据底层存储实现,根据客户环境部署需求,在MC进行简单配置,就可以将日志写入DB(MySQL/PostgreSQL/Oracle等)或者ES。

1. 接口列表


通过使用LogORM提供的下列接口,可以对插入日志系统的数据进行增删查改操作。


(1)插入接口


/**
 *
批量插入
 
*
 * @param
objects DynamicObject
 * @return
插入数据的主键数组
 
*/
long[] insert(List<DynamicObject> objects);

 

(2)查询接口


/**
  * 查询DynamicObjectCollection
  *
  * @param entityName   单据标识
  * @param selectFields 查询字段
  * @param filters      过滤条件
  * @param limit        limit
  * @param offset       offset
  * @return DynamicObjectCollection
  */
 DynamicObjectCollection query(String entityName, String selectFields, QFilter[] filters, int limit, int offset);
 
 /**
  * 查询DataSet
  *
  * @param entityName   单据标识
  * @param selectFields 查询字段
  * @param filters      过滤条件
  * @param limit        limit
  * @param offset       offset
  * @return DataSet
  */
 DataSet queryDataSet(String entityName, String selectFields, QFilter[] filters, int limit, int offset);
 
 /**
  * 执行简单聚集函数(目前只支持count函数)
  *
  * @param entityName 单据标识
  * @param func       函数名称 例如:count(id)
  * @param filters    过滤条件
  * @return 条数
  */
 long aggregate(String entityName, String func, QFilter[] filters);


(3)更新及删除


/**
  * 批量更新
  *
  * @param objects DynamicObject
  * @return 返回影响的条数
  */
 int update(List<DynamicObject> objects);
 
 /**
  * 按条件删除
  *
  * @param entityName 单据标识
  * @param where      筛选条件
  * @return 删除的记录数量
  */
 int delete(String entityName, QFilter[] where);


2. 接口使用实例


下面展示接口写入与查询日志的代码使用实例。


(1)写入日志


// 根据实体名构建元数据并创建DynamicObject
MainEntityType entityType = EntityMetadataCache.getDataEntityType("entityName");
DynamicObject dynamicObject = new DynamicObject(entityType);
dynamicObject.getDataEntityType().getPrimaryKey().setValueFast(dynamicObject, ID.genLongId());
dynamicObject.set("xx1", "hello world");

// 批量插入,需要保证objects中为同一个单据类型的DynamicObject
List<DynamicObject> objects = new ArrayList<>();
objects.add(dynamicObject);

// 初始化LogORM实例
LogORM logORM = LogORM.create();
// 批量插入
logORM.insert(objects);


(2)查询日志


LogORM logORM = LogORM.create();
 QFilter qFilter = QFilter.of("xx1 = ?", "hello world");
 DataSet ds = logORM.queryDataSet("entityName", "id,xx1", new QFilter[]{qFilter}, 100, 0);
 while (ds.hasNext()) {
   Row row = ds.next();
   System.out.println("LogORM-QueryDataSet:" + row.get(0));
 }

3. 数据类型


为了统一Elastic及DB存储,不同于其它单据,日志框架仅支持以下类型:

(1)文本/长文本/大文本;

(2)对应Java的String类型,文本及长文本最多支持2000字符,请尽量不要使用大文本字段,使用大文本字段时,对大文本字段检索存在限制,ES只能检索前2000字符,部分数据库不支持在TEXT字段上进行模糊查询;

(3)整数;

(4)对应Integer类型;

(5)长日期;

(6)可使用java.sql.Date及java.sql.Timestamp类型;

(7)小数;

(8)可使用float,double及BigDecimal类型,最多只支持15位长度精度。

4. 使用限制


受限于Elastic存储以及基于系统稳定考虑,使用时存在以下限制

(1) QFilter

  • 操作符不支持match,exists,not exists;

  • property只支持属性,不支持复杂表达式;

  • value不支持复杂表达式;

  • like查询时,value值长度不能超过500个字符,ftlike查询时单个值长度也不能超过500个字符;

  • 不支持在like及ftlike中查询带有*的字符串;

(2) 其它

  • 查询字段不支持复杂表达式。


常见问题


问1 支持运行时切换DB及Elastic存储吗?

答1 不支持,该操作可能会造成部分数据存入DB及Elastic,后续无法进行数据合并。


问2 出现Not found ElasticSearch data source异常,如何处理?

答2 请检查MC是否启用了启用ES日志存储按钮,但是没有配置Elastic数据源。


问3 在Elastic数据源时,同样的查询条件,查询返回的数据不一致,如何处理?

答3 请检查是否正确配置了Elastic集群;MC配置Elastic集群时,支持配置多个地址,但是没有对这些地址是否属于同一集群检测。


问4 出现Archive route dataSource not found或者Not found elastic archive data source异常,如何处理?

答4 请检查是否正确配置了Elastic的归档配置及归档数据源。


问5 出现Unknown column [xxxx], did you mean any of [xxxx],如何处理?

答5 请检查是否正确配置了Elastic集群;MC配置Elastic集群时,支持配置多个地址,但是没有对这些地址是否属于同一集群检测。


问6 出现Cannot use field [xxxx] due to ambiguities being mapped as [xxx] incompatible type: xxx,如何处理?

答6 请检查是否正确配置了Elastic集群;MC配置Elastic集群时,支持配置多个地址,但是没有对这些地址是否属于同一集群检测。


划重点


  1. 统一日志框架依赖MC补丁,版本4.0.006及以上。

  2. 初次使用统一日志框架时,需要依据框架重写日志

  3. 在使用统一日志框架的过程中,需要遵循一定的规范,如日志如果想要增删改字段,需重新建表记录日志。

  4. 日志数据库选定ES/DB后,应随意切换

  5. 各业务场景切换日志数据库或变更字段时,需自行考虑历史数据升级

  6. 为防范二次开发风险,日志表单模板中的字段必录。不使用这些字段时,可不写入字段、不在日志列表显示。




#往期推荐#

如何定位及解决分布式锁缓慢问题,看这里!

苍穹分布式ID,你知多少?

手把手教你修改苍穹日志级别

苍穹MQ分区指南,绝不给你“添堵”


更多精彩内容,“码”上了解!↓

上传图片


统一日志框架,居然是这样的!

在软件开发中,日志记录是非常重要的,可以帮助开发人员追踪和排查问题,了解应用程序的运行情况,提高代码质量。苍穹系统的原有日志存储并...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息