亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

我們開發(fā)的業(yè)務(wù)系統(tǒng)通常會提供給很多人使用,那在使用的過程中,日志系統(tǒng)變得非常重要。

日志系統(tǒng)記錄的用戶行為有以下的作用:

  • 從系統(tǒng)用戶角度看:它展示了用戶自身的操作歷史和具體對象的變動歷史,便于用戶進行梳理
  • 從系統(tǒng)管理員角度看:它可以記錄了所有用戶操作,便于我們定位異常行為

例如,在git的project操作中,我們就可以看到這樣的操作日志展示:

如何快速搭建日志系統(tǒng)

 

對于這樣的日志記錄,我們可以在相關(guān)記錄點添加對應(yīng)的日志寫入代碼或者通過切面實現(xiàn)。然而,這樣的日志展示是相對簡單的,只是記錄了操作行為的種類。而有時我們需要記錄每個操作行為對操作對象引發(fā)的具體變動,例如展示出這樣的結(jié)果:

如何快速搭建日志系統(tǒng)

 

這給日志記錄帶來了不小的挑戰(zhàn):

  • 在一個系統(tǒng)中,可能涉及到多種對象(例如,學(xué)生、課程、老師),而每個對象的屬性是完全不一樣的
  • 在一次操作中,可能改變了對象的一個或者多個屬性,這也使得我們極難逐一記錄

而今天,我們要介紹的是一套強大且易用的JAVA對象日志記錄系統(tǒng),支持對象屬性變動的記錄與查詢。借助于它,我們可以方便地實現(xiàn)對象屬性變動的記錄與查詢。

1 系統(tǒng)簡介

ObjectLogger是一套強大且易用的對象日志記錄系統(tǒng)。它能夠?qū)⑷我鈱ο蟮淖儎尤罩居涗浵聛恚⒅С植樵儭?梢詰?yīng)用在用戶操作日志記錄、對象屬性變更記錄等諸多場景中。

該系統(tǒng)具有以下特點:

  • 一站整合:系統(tǒng)支持日志的記錄與查詢,開發(fā)者只需再開發(fā)前端界面即可使用。
  • 完全獨立:與業(yè)務(wù)系統(tǒng)無耦合,可插拔使用,不影響主業(yè)務(wù)流程。
  • 應(yīng)用共享:系統(tǒng)可以同時供多個業(yè)務(wù)系統(tǒng)使用,互不影響。
  • 簡單易用:服務(wù)端直接jar包啟動;業(yè)務(wù)系統(tǒng)有官方Maven插件支持。
  • 自動解析:能自動解析對象的屬性變化,并支持富文本的前后對比。
  • 便于擴展:支持自定義對象變動說明、屬性變動說明。支持更多對象屬性類型的擴展。

整個項目包含四個部分:

  • ObjectLoggerClient:能夠集成到業(yè)務(wù)系統(tǒng)進行日志分析、發(fā)送jar包。可以從Maven官方倉庫引入該jar包。該模塊位于client子包下。
  • ObjectLoggerServer:一個web服務(wù),需要數(shù)據(jù)庫的支持。它能夠接收并保存ObjectLoggerClient發(fā)出的日志信息,支持日志的查詢操作。該模塊位于server子包下。
  • react-object-logger:一個React前端組件,用于進行日志的前端展示。可以從npm官方倉庫引入該組件。該子項目位于react-object-logger。
  • ObjectLoggerDemo:一個業(yè)務(wù)端集成ObjectLoggerClient的示例。該模塊位于demo子包下。

2 快速上手

2.1 創(chuàng)建數(shù)據(jù)庫

使用該項目的/server/database/init_data_table.sql文件初始化兩個數(shù)據(jù)表。

2.2 啟動Server

下載該項目下最新的Server服務(wù)jar包,地址為/server/target/ObjectLoggerServer-*.jar。

啟動下載的jar包。

java -jar ObjectLoggerServer-*.jar --spring.datasource.url=jdbc:{db}://{db_address}/{db_name} --spring.datasource.username={db_username} --spring.datasource.password={db_password}

上述命令中的用戶配置項說明如下:

  • db:數(shù)據(jù)庫類型。如果使用MySQL數(shù)據(jù)庫則為mysql;如果使用SqlServer數(shù)據(jù)庫則為sqlserver。
  • db_address:數(shù)據(jù)庫連接地址。如果數(shù)據(jù)庫在本機則為127.0.0.1。
  • db_name:數(shù)據(jù)庫名,該數(shù)據(jù)庫中需包含上一步初始化的兩個數(shù)據(jù)表。
  • db_username:數(shù)據(jù)庫登錄用戶名。
  • db_password:數(shù)據(jù)庫登錄密碼。

啟動jar成功后可以看到下面的界面:

如何快速搭建日志系統(tǒng)

 

使用瀏覽器訪問下面的頁面可以看到系統(tǒng)歡迎頁面:

http://127.0.0.1:12301/ObjectLoggerServer/

訪問上述地址可以看到下面的歡迎界面:

如何快速搭建日志系統(tǒng)

 

至此,ObjectLoggerServer系統(tǒng)已經(jīng)搭建結(jié)束,可以接受業(yè)務(wù)系統(tǒng)的日志寫入和查詢操作。

3 業(yè)務(wù)系統(tǒng)接入

該部分講解如何配置業(yè)務(wù)系統(tǒng)來將業(yè)務(wù)系統(tǒng)中的對象變化通過ObjectLoggerClient分析,然后記錄到ObjectLoggerServer中。

這一部分的使用可以參照ObjectLoggerDemo項目,該項目給出了業(yè)務(wù)系統(tǒng)集成ObjectLoggerClient的詳細示例。ObjectLoggerDemo的制品包可以從/demo/target/ObjectLoggerDemo-*.jar獲得,無需其他配置直接運行java -jar ObjectLoggerDemo-*.jar便可以直接啟動該項目。

可以直接根據(jù)啟動頁面的提示訪問相關(guān)地址來體驗:

如何快速搭建日志系統(tǒng)

 

3.1 引入依賴包

在pom中增加下面的依賴:

<dependency>
 <groupId>com.github.yeecode.objectlogger</groupId>
 <artifactId>ObjectLoggerClient</artifactId>
 <version>{最新版本}</version>
</dependency>

3.2 添加對ObjectLoggerClient中bean的自動注入

3.2.1 對于SpringBoot應(yīng)用

在SpringBoot的啟動類前添加@ComponentScan注解,并在basePackages中增加ObjectLoggerClient的包地址:com.github.yeecode.objectlogger,如:

@SpringBootApplication
@ComponentScan(basePackages={"{your_beans_root}","com.github.yeecode.objectlogger"})
public class MyBootAppApplication {
public static void main(String[] args) {
 // 省略其他代碼
 }
}

3.2.2 對于Spring應(yīng)用

在applicationContext.xml增加對ObjectLoggerClient包地址的掃描:

<context:component-scan base-package="com.github.yeecode.objectlogger">
</context:component-scan>

3.3 完成配置

在application.properties中增加:

yeecode.objectLogger.serverAddress=http://{ObjectLoggerServer_address}
yeecode.objectLogger.businessAppName={your_app_name}
yeecode.objectLogger.autoLogAttributes=true
  • ObjectLoggerServer_address:屬性指向上一步的ObjectLoggerServer的部署地址,例如:127.0.0.1:12301
  • your_app_name:指當(dāng)前業(yè)務(wù)系統(tǒng)的應(yīng)用名。以便于區(qū)分日志來源,實現(xiàn)同時支持多個業(yè)務(wù)系統(tǒng)
  • yeecode.objectLogger.autoLogAttributes:是否對對象的所有屬性進行變更日志記錄

至此,業(yè)務(wù)系統(tǒng)的配置完成。已經(jīng)實現(xiàn)了和ObjectLoggerServer端的對接。

4 日志查詢

系統(tǒng)運行后,可以通過http://127.0.0.1:12301/ObjectLoggerServer/log/query查詢系統(tǒng)中記錄的日志,并通過傳入?yún)?shù)對日志進行過濾。

如何快速搭建日志系統(tǒng)

 

通過這里,我們可以查詢下一步中寫入的日志。

5 日志展示

ObjectLogger有前端React組件react-object-logger支持,用于進行日志信息的展示。體驗頁面:react-object-logger 示例頁面

展示效果如圖:

如何快速搭建日志系統(tǒng)

 

感興趣的用戶可以前往react-object-logger進行了解。

同時也歡迎各位開發(fā)者開發(fā)面向其它前端技術(shù)棧的組件。

6 日志寫入

業(yè)務(wù)系統(tǒng)在任何需要進行日志記錄的類中引入LogClient。例如:

@Autowired
private LogClient logClient;

6.1 簡單使用

直接將對象的零個、一個、多個屬性變化放入List<BaseAttributeModel>后調(diào)用logAttributes方法發(fā)出即可。List<BaseAttributeModel>置為null則表示此次對象無需要記錄的屬性變動。例如,業(yè)務(wù)應(yīng)用中調(diào)用:

logClient.logAttributes(
 "CleanRoomTask",
 5,
 "Tom",
 "add",
 "Add New Task",
 "Create a cleanRoomTask",
 "taskName is :Demo Task",
 null);

在ObjectLoggerServer中使用如下查詢條件:

http://127.0.0.1:12301/ObjectLoggerServer/log/query?appName=ObjectLoggerDemo&objectName=CleanRoomTask&objectId=5

查詢到日志:

{
 "respMsg": "SUCCESS",
 "respData": [
 {
 "id": 1,
 "appName": "ObjectLoggerDemo",
 "objectName": "CleanRoomTask",
 "objectId": 5,
 "operator": "Jone",
 "operationName": "start",
 "operationAlias": "Start a Task",
 "extraWords": "Begin to clean room...",
 "comment": "Come on and start cleaning up.",
 "operationTime": "2019-07-04T06:53:40.000+0000",
 "attributeModelList": [
 {
 "attributeType": "NORMAL",
 "attributeName": "status",
 "attributeAlias": "Status",
 "oldValue": "TODO",
 "newValue": "DOING",
 "diffValue": null,
 "id": 1,
 "operationId": 1
 }
 ]
 }
 ],
 "respCode": "1000"
}

6.2 對象變動自動記錄

該功能可以自動完成新老對象的對比,并根據(jù)對比結(jié)果,將多個屬性變動一起寫入日志系統(tǒng)中。使用時,要確保傳入的新老對象屬于同一個類。

例如,業(yè)務(wù)系統(tǒng)這樣調(diào)用:

CleanRoomTask oldTask = new CleanRoomTask();
oldTask.setId(5);
oldTask.setTaskName("Demo Task");
oldTask.setStatus("TODO");
oldTask.setDescription("Do something...");
CleanRoomTask newTask = new CleanRoomTask();
newTask.setId(5);
newTask.setTaskName("Demo Task");
newTask.setStatus("DOING");
newTask.setDescription("The main job is to clean the floor.");
newTask.setAddress("Sunny Street");
newTask.setRoomNumber(702);
logClient.logObject(
 cleanRoomTask.getId().toString(),
 "Tom",
 "update",
 "Update a Task",
 null,
 null,
 oldTask,
 newTask);

則我們可以使用下面查詢條件:

http://127.0.0.1:12301/ObjectLoggerServer/log/query?appName=ObjectLoggerDemo&objectName=CleanRoomTask&objectId=5

查詢到如下結(jié)果:

{
 "respMsg": "SUCCESS",
 "respData": [
 {
 "id": 4,
 "appName": "ObjectLoggerDemo",
 "objectName": "CleanRoomTask",
 "objectId": 5,
 "operator": "Tom",
 "operationName": "update",
 "operationAlias": "Update a Task",
 "extraWords": null,
 "comment": null,
 "operationTime": "2019-07-04T07:22:59.000+0000",
 "attributeModelList": [
 {
 "attributeType": "NORMAL",
 "attributeName": "roomNumber",
 "attributeAlias": "roomNumber",
 "oldValue": "",
 "newValue": "702",
 "diffValue": null,
 "id": 5,
 "operationId": 4
 },
 {
 "attributeType": "NORMAL",
 "attributeName": "address",
 "attributeAlias": "address",
 "oldValue": "",
 "newValue": "Sunny Street",
 "diffValue": null,
 "id": 6,
 "operationId": 4
 },
 {
 "attributeType": "NORMAL",
 "attributeName": "status",
 "attributeAlias": "Status",
 "oldValue": "TODO",
 "newValue": "DOING",
 "diffValue": null,
 "id": 7,
 "operationId": 4
 },
 {
 "attributeType": "TEXT",
 "attributeName": "description",
 "attributeAlias": "Description",
 "oldValue": "Do something...",
 "newValue": "The main job is to clean the floor.",
 "diffValue": "Line 1<br/> -: <del> Do something... </del> <br/> +: <u> The main job is to clean the floor. </u> <br/>",
 "id": 8,
 "operationId": 4
 }
 ]
 }
 ],
 "respCode": "1000"
}

7 對象屬性過濾

有些對象的屬性的變動不需要進行日志記錄,例如updateTime、hashCode等。ObjectLoggerClient支持對對象的屬性進行過濾,只追蹤我們感興趣的屬性。

并且,對于每個屬性我們可以更改其記錄到ObjectLoggerClient系統(tǒng)中的具體方式,例如修改命名等。

要想啟用這個功能,首先將配置中的yeecode.objectLogger.autoLogAttributes改為false。

yeecode.objectLogger.autoLogAttributes=true

然后在需要進行變化日志記錄的屬性上增加@LogTag注解。凡是沒有增加該注解的屬性在日志記錄時會被自動跳過。

例如,注解配置如下則id字段的變動將被忽略。

private Integer id;
@LogTag
private String taskName;
@LogTag(alias = "UserId", extendedType = "userIdType")
private int userId;
@LogTag(alias = "Status")
private String status;
@LogTag(alias = "Description", builtinType = BuiltinTypeHandler.TEXT)
private String description;

該注解屬性介紹如下:

  • alias:屬性別名。默認情況下會將屬性名寫入。
  • builtinType:ObjectLoggerClient的內(nèi)置類型,為BuiltinTypeHandler的值。默認為BuiltinTypeHandler.NORMAL。
  • BuiltinTypeHandler.NORMAL:記錄屬性的新值和舊值,對比值為null
  • BuiltinTypeHandler.RICHTEXT: 用戶富文本對比。記錄屬性值的新值和舊值,并將新舊值轉(zhuǎn)化為純文本后逐行對比差異,對比值中記錄差異
  • extendedType:擴展屬性類型。使用ObjcetLogger時,用戶可以擴展某些字段的處理方式,此時,alias等信息均可以被用戶自主覆蓋。

8 屬性處理擴展

很多情況下,用戶希望能夠自主決定某些對象屬性的處理方式。例如,對于例子中Task對象的userId屬性,用戶可能想將其轉(zhuǎn)化為姓名后存入日志系統(tǒng),從而使得日志系統(tǒng)與userId完全解耦。

ObjectLoggerClient完全支持這種情況,可以讓用戶自主決定某些屬性的日志記錄方式。要想實現(xiàn)這種功能,首先在需要進行擴展處理的屬性上為@LogTag的extendedType屬性賦予一個字符串值。例如:

@LogTag(alias = "UserId", extendedType = "userIdType")
private int userId;

然后在業(yè)務(wù)系統(tǒng)中聲明一個Bean繼承BaseExtendedTypeHandler,作為自由擴展的鉤子。代碼如下:

@Service
public class ExtendedTypeHandler implements BaseExtendedTypeHandler {
 @Override
 public BaseAttributeModel handleAttributeChange(String extendedType, String attributeName, String attributeAlias, Object oldValue, Object newValue) {
 // TODO
 }
}

接下來,當(dāng)ObjectLoggerClient處理到該屬性時,會將該屬性的相關(guān)信息傳入到擴展Bean的handleAttributeChange方法中,然后用戶可以自行處理。傳入的四個參數(shù)解釋如下:

  • extendedType:擴展類型值,即@LogTag注解的extendedType值。本示例中為userIdType。
  • attributeName:屬性名。本示例中為userId。
  • attributeAlias:屬性別名,@LogTag注解的alias值。本示例中為UserId。
  • oldValue:該屬性的舊值。
  • newValue:該屬性的新值。

例如我們可以采用如下的方式處理userIdType屬性:

@Service
public class ExtendedTypeHandler implements BaseExtendedTypeHandler {
 @Override
 public BaseAttributeModel handleAttributeChange(String extendedType, String attributeName, String attributeAlias, Object oldValue, Object newValue) {
 BaseAttributeModel baseAttributeModel = new BaseAttributeModel();
 if (extendedType.equals("userIdType")) {
 baseAttributeModel.setOldValue("USER_" + oldValue);
 baseAttributeModel.setNewValue("USER_" + newValue);
 baseAttributeModel.setDiffValue(oldValue + "->" + newValue);
 }
 return baseAttributeModel;
 }
}

9 總結(jié)

怎么樣,是不是有了這一套系統(tǒng)之后,再負責(zé)的日志系統(tǒng)都變得簡單起來。快收藏起來當(dāng)作自己的秘技吧!


易哥,高級軟件架構(gòu)師、網(wǎng)絡(luò)工程師、數(shù)據(jù)庫工程師、注冊電氣工程師。現(xiàn)從事軟件架構(gòu)架構(gòu)設(shè)計工作。

分享架構(gòu)師知識! 歡迎關(guān)注我們,不錯過每期的原創(chuàng)干貨!

分享到:
標(biāo)簽:系統(tǒng) 日志
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定