序文
システム運用の過程で、ユーザーが重要なビジネスデータを追加、削除、変更、確認する際に、ユーザーの操作行動を記録し、問題発生時の根拠を把握できるようにしたいと考えています。このログは操作ログです。ビジネスシステムの。
この記事では、一般的な操作ログの実装と実現可能性について説明します
一般的な操作ログの種類
- ユーザーログインログ
- 重要なデータクエリログ(ただし、淘宝網で検索する商品など、eコマースは埋もれる重要なデータではない場合があります。購入しなくても、ホームページは一定期間同様のことを推奨します)
- 重要なデータ変更ログ(パスワードの変更、権限の変更、データの変更など)
- データ削除ログ
- ……。
要約すると、ビジネスのニーズに応じて、操作ログを追加、削除、変更、および確認することが重要です。
実施計画の比較
AOP(アスペクト)の従来の実装スキームに基づく
- 利点:シンプルな実装のアイデア。
- 短所:データベースの負担が増える、フロントエンドパラメータの転送に大きく依存する、不便な拡張、バッチ操作をサポートしない、マルチテーブルの関連付けをサポートしない。
データベースBinlogに基づく
- 利点:データの新旧の変更間の結合が解放され、バッチ操作がサポートされ、マルチテーブルの関連付けの拡張が便利で、開発言語に依存しません。
- 短所:データベーステーブルの設計には、統一された合意が必要です。
スキーム実装の詳細
1.AOPアスペクト+アノテーションに基づく従来のソリューション
従来のアプローチはアスペクト+アノテーションメソッドであり、コードにあまり侵入せず、通常はIP、ビジネスモジュール、オペレーションアカウント、オペレーションシナリオ、オペレーションソースなどを記録します。通常、これらの値はアノテーション+インターセプターで取得されます。 、以下に示すように:
この一般的な方法は一般的に処理できますが、データの変更に関しては、変更前のデータ量や変更後のデータ量など、これ以上の実装方法はありません。
以前に実装した一連のソリューションを使用すると、データ変更に基づく記録方法は、テンプレートを需要側と合意するだけでなく(数百のフィールドを表示および記録することは不可能)、フロントエンドともある程度合意する必要があります。 、たとえば、変更前の値と変更後の値は次のコードを参照してください。
@Valid
@NotNull(message = "新值不能为空")
@UpdateNewDataOperationLog
private T newData;
@Valid
@NotNull(message = "旧值不能为空")
@UpdateOldDataOperationLog
private T oldData;
既存の問題:
- 1.古い値がデータベースに複数回クエリを実行しない場合は、フロントエンドに依存して古い値をoldDataオブジェクトにカプセル化する必要があります。これは、変更前の値ではない可能性があります。
- 2.リストデータのバッチを処理できません。
- 3.マルチテーブル操作をサポートしていません。
別のシーンを例にとると、削除する前に、削除する前に値を記録する必要があります。もう一度確認する必要がありますか?
@PostMapping("/delete")
@ApiOperation(value = "删除用户信息", notes = "删除用户信息")
@DeleteOperationLog(system = SystemNameNewEnum.SYS_JMS_LMDM, module = ModuleNameNewEnum.LMDM_AUTH, table = LogBaseTableNameEnum.TABLE_USER, methodName = "detail")
2、データベースBinlogプログラムに基づく
システムアーキテクチャ図は次のとおりです。
「主に3つの部分に分かれています:」
- 1:ビジネスアプリケーションは、各操作のtraceidを生成し、それを操作のビジネステーブルに更新し、現在の操作のオペレーターに関する情報を含むビジネスメッセージを送信します。
- 2:ログ収集アプリケーションは、ビジネスログと変換されたbinlogログを統合し、外部ログクエリと検索APIを提供します。
- 3:ログ処理アプリケーションは、canalを使用して、ビジネスライブラリのbinlogログを収集および解析し、Kafkaに配信します。解析されたレコードは、削除、変更、追加、新規のレコードなど、現在の操作の操作タイプを記録します。および古い値、次のようにフォーマットします。
{"data":[{"id":"122158992930664499","bill_type":"1","create_time":"2020-04-2609:15:13","update_time":"2020-04-2613:45:46","version":"2","trace_id":"exclude-f04ff706673d4e98a757396efb711173"}],
"database":"yl_spmibill_8",
"es":1587879945200,
"id":17161259,
"isDdl":false,
"mysqlType":{"id":"bigint(20)",
"bill_type":"tinyint(2)",
"create_time":"timestamp",
"update_time":"timestamp",
"version":"int(11)",
"trace_id":"varchar(50)"},
"old":[{"update_time":"2020-04-2613:45:45",
"version":"1",
"trace_id":"exclude-36aef98585db4e7a98f9694c8ef28b8c"}],
"pkNames":["id"],"sql":"",
"sqlType":{"id":-5,"bill_type":-6,"create_time":93,"update_time":93,"version":4,"trace_id":12},
"table":"xxx_transfer_bill_117",
"ts":1587879945698,"type":"UPDATE"}
binlonログ変換処理後の操作ログは以下のとおりです。
{
"id":"120716921250250776",
"relevanceInfo":"XX0000097413282,",
"remark":"签收财务网点编码由【】改为【380000】,
签收网点名称由【】改为【泉州南安网点】,签收网点code由【】改为【2534104】,运单状态code由【204】改为【205】,签收财务网点名称由【】改为【福建代理区】,签收网点id由【0】改为【461】,签收标识,1是,0否由【0】改为【1】,签收时间由【null】改为【2020-04-24 21:09:47】,签收财务网点id由【0】改为【400】,",
"traceId":"120716921250250775"
}
ライブラリテーブルのデザイン
- 1:すべてのビジネスシステムテーブルでtrace_idフィールドを追加する必要があり、各操作でランダムな文字列が生成され、ビジネステーブルに保存されます。
- 2:ログ収集アプリケーションライブラリテーブルの設計
CREATE TABLE `table_config` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`database_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '数据库名',
`table_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ' 数据库表名',
PRIMARY KEY (`id`),
UNIQUE KEY `unq_data_name_table_name` (`database_name`,`table_name`) USING BTREE COMMENT '数据库名表名联合索引'
) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='数据库配置表';
CREATE TABLE `table_field_config` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`table_config_id` bigint(20) DEFAULT NULL,
`field` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字段 数据库',
`field_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '字段 中文名称',
`enum_flag` tinyint(2) DEFAULT NULL COMMENT '是否枚举字段(1:是,0:否)',
`relevance_flag` tinyint(2) DEFAULT NULL COMMENT '是否是关联字段(1:是,0否)',
`sort` int(11) DEFAULT NULL COMMENT '排序',
PRIMARY KEY (`id`),
KEY `idx_table_config_id` (`table_config_id`) USING BTREE COMMENT '表ID索引'
) ENGINE=InnoDB AUTO_INCREMENT=2431 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='数据库字段配置表';
CREATE TABLE `table_field_value` (
`id` bigint(20) NOT NULL,
`field_config_id` bigint(20) DEFAULT NULL,
`field_key` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ' 枚举',
`filed_value` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '枚举名称',
PRIMARY KEY (`id`),
KEY `ids_field_config_id` (`field_config_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='数据字典配置表';
効果
プログラムの将来の計画を実現するためのbinlogに基づく
- ビジネスメッセージの送信の実現を最適化し、アスペクトインターセプトを使用してビジネスコードの侵入を減らします。
- 現在、マルチテーブルアソシエーション操作ログレコードをサポートしていないため、拡張する必要があります。