# LogMessage
[LogMessage.java](../../oblogclient-common/src/main/java/com/oceanbase/oms/logmessage/LogMessage.java) defines `LogMessage` as the structure of the log records. During the running of the program, the client will convert the received log data into LogMessage objects, and users can use them to customize their own processing logic.
## Struct
When we fetch log data from OceanBase, the data will firstly be serialized using [oblogmsg](https://github.com/oceanbase/oblogmsg), and eventually be converted into LogMessage struct in the client. For specific field information, please refer to oblogmsg.
There are the common fields of LogMessage:
Field |
Getter |
Type |
Description |
byteBuf |
getRawData |
byte[] |
The original log data in byte array format. |
srcType |
getDbType |
DbTypeEnum |
Type of datasource, OceanBase versions before 1.0 correspond to OB_05 , versions 1.0 and later correspond to OB_MYSQL and OB_ORACLE . |
op |
getOpt |
DataMessage.Record.Type |
The type of log data, OceanBase mainly involves BEGIN , COMMIT , INSERT , UPDATE , DELETE , DDL , HEARTBEAT . |
timestamp |
getTimestamp |
String |
The timestamp of data change execution time. |
dbName |
getDbName |
String |
Database name of log data. Note that this value contains the tenant name in the format of tenant_name.db_name . |
tableName |
getTableName |
String |
Table name of log data. |
The field list of DML and DDL can be obtained through the `getFieldList` method. The following are commonly used fields in the Field struct:
Field |
Getter |
Type |
Description |
primaryKey |
isPrimary |
boolean |
Flag of whether this field is a primary key of not null unique key. |
name |
getFieldname |
String |
Field name. |
type |
getType |
DataMessage.Record.Field.Type |
Field type. |
encoding |
getEncoding |
String |
Field encoding. |
value |
getValue |
ByteString |
Field value in ByteString type. |
prev |
isPrev |
boolean |
Flag of whether it is a old value. It is true if this field is the value before the change, and false if it is the value after the change. |
## Usage
Please refer to [LogProxyClientTest.java](../../oblogclient-logproxy/src/test/java/com/oceanbase/clogproxy/client/LogProxyClientTest.java).
### Safe Checkpoint
LogMessage provides `safeTimestamp` to indicate the safe checkpoint for data reception, that is to say, LogMessage committed earlier than this timestamp has been received by the client.
When a application consumes data, it generally maintains a safe checkpoint for data processing. For LogMessage, we should use HEARTBEAT `timestamp` as the safe checkpoint. LogMessage contains two kinds of timestamp:
- HEARTBEAT type: the value of the `timestamp` field is the timestamp corresponding to the safe checkpoint.
- Other types: the value of the `timestamp` field is the execution time of the data change, and the `fileNameOffset` field corresponds to the latest HEARTBEAT timestamp. Since `libobcdc` does not guarantee that the fetched data changes are in timestamp order, so for DDL and DML types of LogMessage, `fileNameOffset` should be used as safe checkpoint instead of `timestamp`.
The following code can be used to obtain the safe checkpoint corresponding to the current data:
```java
long checkpoint;
if (DataMessage.Record.Type.HEARTBEAT.equals(message.getOpt())) {
checkpoint = Long.parseLong(message.getTimestamp());
} else {
checkpoint = message.getFileNameOffset();
}
```