diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/log/OpsBusinessEventLogDO.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/log/OpsBusinessEventLogDO.java new file mode 100644 index 0000000..5b9028f --- /dev/null +++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/dal/dataobject/log/OpsBusinessEventLogDO.java @@ -0,0 +1,138 @@ +package com.viewsh.module.ops.dal.dataobject.log; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import com.viewsh.framework.mybatis.core.dataobject.BaseDO; +import lombok.*; + +import java.time.LocalDateTime; +import java.util.Map; + +/** + * 通用业务事件日志 DO + *
+ * 用于记录所有模块的业务事件日志,支持多模块(clean/repair/patrol等)
+ * 采用方案A:在记录时��步填充设备/人员名称冗余字段,便于展示时直接查询
+ *
+ * @author lzh
+ */
+@TableName(value = "ops_business_event_log", autoResultMap = true)
+@KeySequence("ops_business_event_log_seq")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OpsBusinessEventLogDO extends BaseDO {
+
+ // ==================== 主键 ====================
+
+ /**
+ * 主键ID
+ */
+ @TableId
+ private Long id;
+
+ // ==================== 时间与级别 ====================
+
+ /**
+ * 事件时间
+ */
+ private LocalDateTime eventTime;
+
+ /**
+ * 日志级别(INFO=信息/WARN=警告/ERROR=错误)
+ */
+ private String eventLevel;
+
+ // ==================== 业务分类 ====================
+
+ /**
+ * 模块标识(clean=保洁/repair=维修/patrol=巡检)
+ */
+ private String module;
+
+ /**
+ * 事件域(DISPATCH=调度/BEACON=信标/TRAFFIC=客流/DEVICE=设备/SYSTEM=系统/AUDIT=审计)
+ */
+ private String eventDomain;
+
+ /**
+ * 事件类型(如:ARRIVE_CONFIRMED/TTS_SENT/AUTO_DISPATCH)
+ */
+ private String eventType;
+
+ // ==================== 设备关联 ====================
+
+ /**
+ * 设备ID(关联 iot_device.id)
+ */
+ private Long deviceId;
+
+ /**
+ * 设备名称(冗余字段,异步填充)
+ */
+ private String deviceName;
+
+ /**
+ * 设备编码(冗余字段,如设备序列号)
+ */
+ private String deviceCode;
+
+ /**
+ * 设备类型(冗余字段,如:BADGE/TRAFFIC_COUNTER/BEACON)
+ */
+ private String deviceType;
+
+ // ==================== 人员关联 ====================
+
+ /**
+ * 人员ID(保洁员/巡检员等)
+ */
+ private Long personId;
+
+ /**
+ * 人员姓名(冗余字段,异步填充)
+ */
+ private String personName;
+
+ /**
+ * 人员类型(冗余字段,如:CLEANER/INSPECTOR)
+ */
+ private String personType;
+
+ // ==================== 业务实体关联 ====================
+
+ /**
+ * 业务实体ID(如工单ID、区域ID)
+ */
+ private Long targetId;
+
+ /**
+ * 业务实体类型(order=工单/area=区域/task=任务)
+ */
+ private String targetType;
+
+ // ==================== 日志内容 ====================
+
+ /**
+ * 事件描述(完整描述)
+ */
+ private String eventMessage;
+
+ /**
+ * 简要摘要(用于列表展示,可选)
+ */
+ private String eventSummary;
+
+ /**
+ * 扩展数据(JSON格式,存储额外结构化信息)
+ */
+ @TableField(typeHandler = JacksonTypeHandler.class)
+ private Map
+ * 用于标识业务事件发生的领域/模块
+ *
+ * @author lzh
+ */
+public enum EventDomain {
+
+ /**
+ * 调度域 - 工单派发、分配等
+ */
+ DISPATCH("dispatch", "调度"),
+
+ /**
+ * 信标域 - 信标检测、到岗确认等
+ */
+ BEACON("beacon", "信标"),
+
+ /**
+ * 客流域 - 客流统计、阈值触发等
+ */
+ TRAFFIC("traffic", "客流"),
+
+ /**
+ * 设备域 - 设备控制、TTS��震动等
+ */
+ DEVICE("device", "设备"),
+
+ /**
+ * 系统域 - 系统级事件
+ */
+ SYSTEM("system", "系统"),
+
+ /**
+ * 审计域 - 审计日志
+ */
+ AUDIT("audit", "审计");
+
+ private final String code;
+ private final String description;
+
+ EventDomain(String code, String description) {
+ this.code = code;
+ this.description = description;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/infrastructure/log/enumeration/EventLevel.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/infrastructure/log/enumeration/EventLevel.java
new file mode 100644
index 0000000..d6dd87a
--- /dev/null
+++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/infrastructure/log/enumeration/EventLevel.java
@@ -0,0 +1,40 @@
+package com.viewsh.module.ops.infrastructure.log.enumeration;
+
+/**
+ * 事件日志级别枚举
+ *
+ * @author lzh
+ */
+public enum EventLevel {
+
+ /**
+ * 信息级别 - 正常业务流程
+ */
+ INFO("INFO", "信息"),
+
+ /**
+ * 警告级别 - 需要关注但不影响流程
+ */
+ WARN("WARN", "警告"),
+
+ /**
+ * 错误级别 - 业务异常或失败
+ */
+ ERROR("ERROR", "错误");
+
+ private final String code;
+ private final String description;
+
+ EventLevel(String code, String description) {
+ this.code = code;
+ this.description = description;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/infrastructure/log/recorder/EventLogPersister.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/infrastructure/log/recorder/EventLogPersister.java
new file mode 100644
index 0000000..ba78a58
--- /dev/null
+++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/infrastructure/log/recorder/EventLogPersister.java
@@ -0,0 +1,29 @@
+package com.viewsh.module.ops.infrastructure.log.recorder;
+
+import com.viewsh.module.ops.dal.dataobject.log.OpsBusinessEventLogDO;
+
+/**
+ * 事件日志持久化接口
+ *
+ * 负责将日志记录持久化到数据库
+ *
+ * @author lzh
+ */
+public interface EventLogPersister {
+
+ /**
+ * 持久化日志记录(同步)
+ *
+ * @param recordDO 日志DO
+ * @return 是否成功
+ */
+ boolean persist(OpsBusinessEventLogDO recordDO);
+
+ /**
+ * 持久化日志记录(异步)
+ *
+ * @param recordDO 日志DO
+ */
+ void persistAsync(OpsBusinessEventLogDO recordDO);
+
+}
diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/infrastructure/log/recorder/EventLogPersisterImpl.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/infrastructure/log/recorder/EventLogPersisterImpl.java
new file mode 100644
index 0000000..324c25d
--- /dev/null
+++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/infrastructure/log/recorder/EventLogPersisterImpl.java
@@ -0,0 +1,40 @@
+package com.viewsh.module.ops.infrastructure.log.recorder;
+
+import com.viewsh.module.ops.dal.dataobject.log.OpsBusinessEventLogDO;
+import com.viewsh.module.ops.dal.mysql.log.OpsBusinessEventLogMapper;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+/**
+ * 事件日志持久化实现
+ *
+ * @author lzh
+ */
+@Slf4j
+@Component
+public class EventLogPersisterImpl implements EventLogPersister {
+
+ @Resource
+ private OpsBusinessEventLogMapper eventLogMapper;
+
+ @Override
+ public boolean persist(OpsBusinessEventLogDO recordDO) {
+ try {
+ int rows = eventLogMapper.insert(recordDO);
+ return rows > 0;
+ } catch (Exception e) {
+ log.error("[EventLogPersister] 持久化失败: module={}, domain={}, type={}",
+ recordDO.getModule(), recordDO.getEventDomain(), recordDO.getEventType(), e);
+ return false;
+ }
+ }
+
+ @Override
+ @Async("ops-task-executor")
+ public void persistAsync(OpsBusinessEventLogDO recordDO) {
+ persist(recordDO);
+ }
+
+}
diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/infrastructure/log/recorder/EventLogRecord.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/infrastructure/log/recorder/EventLogRecord.java
new file mode 100644
index 0000000..dd3ef7d
--- /dev/null
+++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/infrastructure/log/recorder/EventLogRecord.java
@@ -0,0 +1,223 @@
+package com.viewsh.module.ops.infrastructure.log.recorder;
+
+import com.viewsh.module.ops.infrastructure.log.enumeration.EventDomain;
+import com.viewsh.module.ops.infrastructure.log.enumeration.EventLevel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 事件日志记录实体
+ *
+ * 用于记录业务事件日志,包含设备、人员、业务实体的关联信息
+ * 采用方案A:在记录时异步填充名称冗余字段,便于展示时直接查询
+ *
+ * @author lzh
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class EventLogRecord {
+
+ // ==================== 基础分类字段 ====================
+
+ /**
+ * 模块标识(如:clean, repair, patrol)
+ */
+ private String module;
+
+ /**
+ * 事件域
+ */
+ private EventDomain domain;
+
+ /**
+ * 事件类型(如:ARRIVE_CONFIRMED, TTS_SENT, AUTO_DISPATCH)
+ */
+ private String eventType;
+
+ /**
+ * 日志级别
+ */
+ @Builder.Default
+ private EventLevel level = EventLevel.INFO;
+
+ // ==================== 内容字段 ====================
+
+ /**
+ * 事件描述(完整描述)
+ */
+ private String message;
+
+ /**
+ * 简要摘要(用于列表展示,可选)
+ */
+ private String summary;
+
+ // ==================== 设备关联字段 ====================
+
+ /**
+ * 设备ID
+ */
+ private Long deviceId;
+
+ /**
+ * 设备名称(冗余字段,异步填充)
+ */
+ private String deviceName;
+
+ /**
+ * 设备编码(冗余字段,如设备序列号)
+ */
+ private String deviceCode;
+
+ /**
+ * 设备类型(冗余字段,如:BADGE, TRAFFIC_COUNTER)
+ */
+ private String deviceType;
+
+ // ==================== 人员关联字段 ====================
+
+ /**
+ * 人员ID(保洁员、巡检员等)
+ */
+ private Long personId;
+
+ /**
+ * 人员姓名(冗余字段,异步填充)
+ */
+ private String personName;
+
+ /**
+ * 人员类型(冗余字段,如:CLEANER, INSPECTOR)
+ */
+ private String personType;
+
+ // ==================== 业务实体关联字段 ====================
+
+ /**
+ * 业务实体ID(如工单ID、区域ID)
+ */
+ private Long targetId;
+
+ /**
+ * 业务实体类型(如:order, area, task)
+ */
+ private String targetType;
+
+ // ==================== 扩展字段 ====================
+
+ /**
+ * 扩展数据(JSON格式)
+ */
+ @Builder.Default
+ private Map
+ * 提供业务事件日志记录的统一入口
+ *
+ * @author lzh
+ */
+public interface EventLogRecorder {
+
+ /**
+ * 记录事件日志(同步)
+ *
+ * @param record 日志记录
+ */
+ void record(EventLogRecord record);
+
+ /**
+ * 记录事件日志(异步)
+ *
+ * @param record 日志记录
+ */
+ void recordAsync(EventLogRecord record);
+
+ // ==================== 便捷方法:按级别记录 ====================
+
+ /**
+ * 记录信息级别日志
+ *
+ * @param module 模块标识
+ * @param domain 事件域
+ * @param eventType 事件类型
+ * @param message 事件消息
+ */
+ void info(String module, EventDomain domain, String eventType, String message);
+
+ /**
+ * 记录信息级别日志(带设备关联)
+ *
+ * @param module 模块标识
+ * @param domain 事件域
+ * @param eventType 事件类型
+ * @param message 事件消息
+ * @param deviceId 设备ID
+ */
+ void info(String module, EventDomain domain, String eventType, String message, Long deviceId);
+
+ /**
+ * 记录信息级别日志(带工单关联)
+ *
+ * @param module 模块标识
+ * @param domain 事件域
+ * @param eventType 事件类型
+ * @param message 事件消息
+ * @param orderId 工单ID
+ * @param deviceId 设备ID
+ * @param personId 人员ID
+ */
+ void info(String module, EventDomain domain, String eventType, String message,
+ Long orderId, Long deviceId, Long personId);
+
+ /**
+ * 记录警告级别日志
+ *
+ * @param module 模块标识
+ * @param domain 事件域
+ * @param eventType 事件类型
+ * @param message 事件消息
+ */
+ void warn(String module, EventDomain domain, String eventType, String message);
+
+ /**
+ * 记录警告级别日志(带设备关联)
+ *
+ * @param module 模块标识
+ * @param domain 事件域
+ * @param eventType 事件类型
+ * @param message 事件消息
+ * @param deviceId 设备ID
+ */
+ void warn(String module, EventDomain domain, String eventType, String message, Long deviceId);
+
+ /**
+ * 记录错误级别日志
+ *
+ * @param module 模块标识
+ * @param domain 事件域
+ * @param eventType 事件类型
+ * @param message 事件消息
+ * @param throwable 异常信息
+ */
+ void error(String module, EventDomain domain, String eventType, String message, Throwable throwable);
+
+ /**
+ * 记录错误级别日志(带设备关联)
+ *
+ * @param module 模块标识
+ * @param domain 事件域
+ * @param eventType 事件类型
+ * @param message 事件消息
+ * @param deviceId 设备ID
+ * @param throwable 异常信息
+ */
+ void error(String module, EventDomain domain, String eventType, String message,
+ Long deviceId, Throwable throwable);
+
+}
diff --git a/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/infrastructure/log/recorder/EventLogRecorderImpl.java b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/infrastructure/log/recorder/EventLogRecorderImpl.java
new file mode 100644
index 0000000..25c3b10
--- /dev/null
+++ b/viewsh-module-ops/viewsh-module-ops-biz/src/main/java/com/viewsh/module/ops/infrastructure/log/recorder/EventLogRecorderImpl.java
@@ -0,0 +1,250 @@
+package com.viewsh.module.ops.infrastructure.log.recorder;
+
+import com.viewsh.module.ops.dal.dataobject.log.OpsBusinessEventLogDO;
+import com.viewsh.module.ops.infrastructure.log.enumeration.EventDomain;
+import com.viewsh.module.ops.infrastructure.log.enumeration.EventLevel;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+/**
+ * 事件日志记录器实现
+ *
+ * 负责记录业务事件日志,包含:
+ * 1. 将 EventLogRecord 转换为 OpsBusinessEventLogDO
+ * 2. 异步填充设备/人员名称(方案A:冗余存储)
+ * 3. 持久化到数据库
+ * 4. 输出到控制台(用于调试)
+ *
+ * 设计说明:
+ * - record() 方法默认异步执行,不阻塞主业务流程
+ * - recordSync() 方法同步执行,用于需要确认日志写入成功的场景
+ * - recordAsync() 方法保留,语义更明确
+ *
+ * @author lzh
+ */
+@Slf4j
+@Component
+public class EventLogRecorderImpl implements EventLogRecorder {
+
+ @Resource
+ private EventLogPersister persister;
+
+ /**
+ * 异步记录日志(默认方式)
+ *
+ * 使用 @Async 确保日志记录不阻塞主业务流程
+ */
+ @Override
+ @Async("ops-task-executor")
+ public void record(EventLogRecord record) {
+ doRecord(record);
+ }
+
+ /**
+ * 异步记录日志(语义明确的方法名)
+ */
+ @Override
+ @Async("ops-task-executor")
+ public void recordAsync(EventLogRecord record) {
+ doRecord(record);
+ }
+
+ /**
+ * 同步记录日志
+ *
+ * 用于需要确认日志写入成功的场景(如测试、关键业务)
+ */
+ public void recordSync(EventLogRecord record) {
+ doRecord(record);
+ }
+
+ /**
+ * 实际执行记录逻辑
+ */
+ private void doRecord(EventLogRecord record) {
+ try {
+ // 转换为 DO
+ OpsBusinessEventLogDO recordDO = convertToDO(record);
+
+ // TODO: 方案A - 异步填充设备/人员名称
+ // 这里预留接口,后续通过 Feign 调用 IoT/Ops 模块获取名称
+ enrichRecord(recordDO);
+
+ // 持久化(同步写入,但在异步线程中执行)
+ persister.persist(recordDO);
+
+ // 控制台输出(便于调试)
+ logConsole(record);
+
+ } catch (Exception e) {
+ log.error("[EventLogRecorder] 记录失败: module={}, domain={}, type={}",
+ record.getModule(), record.getDomain(), record.getEventType(), e);
+ }
+ }
+
+ @Override
+ public void info(String module, EventDomain domain, String eventType, String message) {
+ record(EventLogRecord.builder()
+ .module(module)
+ .domain(domain)
+ .eventType(eventType)
+ .message(message)
+ .level(EventLevel.INFO)
+ .build());
+ }
+
+ @Override
+ public void info(String module, EventDomain domain, String eventType, String message, Long deviceId) {
+ record(EventLogRecord.builder()
+ .module(module)
+ .domain(domain)
+ .eventType(eventType)
+ .message(message)
+ .deviceId(deviceId)
+ .level(EventLevel.INFO)
+ .build());
+ }
+
+ @Override
+ public void info(String module, EventDomain domain, String eventType, String message,
+ Long orderId, Long deviceId, Long personId) {
+ record(EventLogRecord.builder()
+ .module(module)
+ .domain(domain)
+ .eventType(eventType)
+ .message(message)
+ .targetId(orderId)
+ .targetType("order")
+ .deviceId(deviceId)
+ .personId(personId)
+ .level(EventLevel.INFO)
+ .build());
+ }
+
+ @Override
+ public void warn(String module, EventDomain domain, String eventType, String message) {
+ record(EventLogRecord.builder()
+ .module(module)
+ .domain(domain)
+ .eventType(eventType)
+ .message(message)
+ .level(EventLevel.WARN)
+ .build());
+ }
+
+ @Override
+ public void warn(String module, EventDomain domain, String eventType, String message, Long deviceId) {
+ record(EventLogRecord.builder()
+ .module(module)
+ .domain(domain)
+ .eventType(eventType)
+ .message(message)
+ .deviceId(deviceId)
+ .level(EventLevel.WARN)
+ .build());
+ }
+
+ @Override
+ public void error(String module, EventDomain domain, String eventType, String message, Throwable throwable) {
+ EventLogRecord record = EventLogRecord.builder()
+ .module(module)
+ .domain(domain)
+ .eventType(eventType)
+ .message(message)
+ .level(EventLevel.ERROR)
+ .build();
+ if (throwable != null) {
+ record.putPayload("errorMessage", throwable.getMessage());
+ record.putPayload("errorClass", throwable.getClass().getSimpleName());
+ }
+ record(record);
+ }
+
+ @Override
+ public void error(String module, EventDomain domain, String eventType, String message,
+ Long deviceId, Throwable throwable) {
+ EventLogRecord record = EventLogRecord.builder()
+ .module(module)
+ .domain(domain)
+ .eventType(eventType)
+ .message(message)
+ .deviceId(deviceId)
+ .level(EventLevel.ERROR)
+ .build();
+ if (throwable != null) {
+ record.putPayload("errorMessage", throwable.getMessage());
+ record.putPayload("errorClass", throwable.getClass().getSimpleName());
+ }
+ record(record);
+ }
+
+ /**
+ * 转换为 DO
+ */
+ private OpsBusinessEventLogDO convertToDO(EventLogRecord record) {
+ return OpsBusinessEventLogDO.builder()
+ .eventTime(record.getEventTime())
+ .eventLevel(record.getLevel() != null ? record.getLevel().getCode() : EventLevel.INFO.getCode())
+ .module(record.getModule())
+ .eventDomain(record.getDomain() != null ? record.getDomain().getCode() : null)
+ .eventType(record.getEventType())
+ .deviceId(record.getDeviceId())
+ .deviceName(record.getDeviceName())
+ .deviceCode(record.getDeviceCode())
+ .deviceType(record.getDeviceType())
+ .personId(record.getPersonId())
+ .personName(record.getPersonName())
+ .personType(record.getPersonType())
+ .targetId(record.getTargetId())
+ .targetType(record.getTargetType())
+ .eventMessage(record.getMessage())
+ .eventSummary(record.getSummary())
+ .eventPayload(record.getPayload())
+ .build();
+ }
+
+ /**
+ * 异步填充设备/人员名称(方案A)
+ *
+ * TODO: 后续通过 Feign 调用以下接口异步填充:
+ * - IotDeviceApi.getBasicInfo(deviceId) -> 获取设备名称、编码、类型
+ * - CleanerService.getBasicInfo(personId) -> 获取人员姓名、类型
+ *
+ * 当前先留空,待 Feign 接口创建后再补充
+ */
+ private void enrichRecord(OpsBusinessEventLogDO recordDO) {
+ // 暂不实现异步填充,待后续完成 Feign 接口后再补充
+ // 设计时考虑:
+ // 1. 如果 recordDO.getDeviceId() 不为空,调用 IoT 模块获取设备信息
+ // 2. 如果 recordDO.getPersonId() 不为空,调用 Ops 模块获取人员信息
+ // 3. 填充冗余字段:deviceName, deviceCode, deviceType, personName, personType
+ }
+
+ /**
+ * 控制台输出(便于调试)
+ */
+ private void logConsole(EventLogRecord record) {
+ String deviceInfo = record.getDeviceId() != null
+ ? " [设备:" + record.getDeviceId() + (record.getDeviceName() != null ? "(" + record.getDeviceName() + ")" : "") + "]"
+ : "";
+ String personInfo = record.getPersonId() != null
+ ? " [人员:" + record.getPersonId() + (record.getPersonName() != null ? "(" + record.getPersonName() + ")" : "") + "]"
+ : "";
+ String targetInfo = record.getTargetId() != null
+ ? " [" + record.getTargetType() + ":" + record.getTargetId() + "]"
+ : "";
+
+ log.info("[EventLog] [{}] {} {} {} - {}{}{}",
+ record.getLevel() != null ? record.getLevel().getCode() : "INFO",
+ record.getModule(),
+ record.getDomain() != null ? record.getDomain().getCode() : "UNKNOWN",
+ record.getEventType(),
+ record.getMessage(),
+ deviceInfo,
+ personInfo,
+ targetInfo);
+ }
+
+}