Skip to content

feat: add eventlogger.hpp header for DDE applications#185

Merged
Ivy233 merged 1 commit intolinuxdeepin:masterfrom
Ivy233:feat/add-eventlogger-header
Apr 23, 2026
Merged

feat: add eventlogger.hpp header for DDE applications#185
Ivy233 merged 1 commit intolinuxdeepin:masterfrom
Ivy233:feat/add-eventlogger-header

Conversation

@Ivy233
Copy link
Copy Markdown
Contributor

@Ivy233 Ivy233 commented Apr 23, 2026

Add a C++ header-only event logger that can be used by DDE applications to log user behavior events. The logger uses dlopen to dynamically load libdeepin-event-log.so library at runtime.

Features:

  • Header-only implementation, no linking required
  • Dynamic library loading with QLibrary
  • System edition check (only UosProfessional enabled by default)
  • Debug mode macro for testing on other editions

添加用于DDE应用程序的事件日志头文件。日志记录器使用dlopen在运行时动态加载
libdeepin-event-log.so库。

Log: 添加事件日志头文件
PMS: TASK-388657

Summary by Sourcery

Add a header-only C++ event logging utility for DDE applications and ensure it is installed as part of the development artifacts.

New Features:

  • Introduce a DDE_EventLogger C++ API for writing structured user behavior events via a dynamically loaded libdeepin-event-log.so library.

Enhancements:

  • Adjust the Makefile install and build targets to install the new C++ event logger header into the system include path for consumers.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 23, 2026

Reviewer's Guide

Adds a header-only C++ event logger for DDE applications that dynamically loads libdeepin-event-log.so at runtime, wires its installation into the build system, and restricts logging to specific UOS editions by default.

Sequence diagram for EventLogger initialization and logging

sequenceDiagram
    actor App
    participant EventLogger as DDE_EventLogger_EventLogger
    participant DSysInfo as DSysInfo_uosEditionType
    participant QLibrary as QLibrary_loader
    participant Lib as libdeepin_event_log_so

    App->>EventLogger: instance()
    Note over EventLogger: Singleton constructor invoked on first call
    EventLogger->>QLibrary: load(/usr/lib/libdeepin-event-log.so)
    QLibrary-->>EventLogger: load result
    EventLogger->>QLibrary: resolve(Initialize)
    QLibrary-->>EventLogger: Initialize*
    EventLogger->>QLibrary: resolve(WriteEventLog)
    QLibrary-->>EventLogger: WriteEventLog*

    App->>EventLogger: init(package_id, enable_sig)
    EventLogger->>DSysInfo: uosEditionType()
    DSysInfo-->>EventLogger: edition_type
    alt shouldEnableEventLog() is false
        EventLogger-->>App: false
    else shouldEnableEventLog() is true
        EventLogger->>EventLogger: check m_initialize,m_writeEventLog
        alt function pointers missing
            EventLogger-->>App: false
        else function pointers available
            EventLogger->>Lib: Initialize(package_id, enable_sig)
            Lib-->>EventLogger: initialized_flag
            EventLogger-->>App: initialized_flag
        end
    end

    App->>EventLogger: writeEventLog(tid, target, key, value)
    EventLogger->>DSysInfo: uosEditionType()
    DSysInfo-->>EventLogger: edition_type
    alt shouldEnableEventLog() is false
        EventLogger-->>App: return
    else shouldEnableEventLog() is true
        EventLogger->>EventLogger: lock m_mutex
        EventLogger->>EventLogger: check m_initialized
        alt not initialized
            EventLogger-->>App: return
        else initialized
            EventLogger->>EventLogger: structToJson(EventLoggerData)
            EventLogger->>Lib: WriteEventLog(json_string)
            Lib-->>EventLogger: ack
            EventLogger-->>App: return
        end
    end
Loading

Class diagram for new DDE_EventLogger C++ API

classDiagram
    direction LR

    class DDE_EventLogger {
    }

    namespace DDE_EventLogger {
        class EventLoggerData {
            +qint64 tid
            +QString target
            +QMap~QString,QString~ message
            +EventLoggerData()
            +EventLoggerData(qint64 tid, QString target, QMap~QString,QString~ message)
            +EventLoggerData operator=(EventLoggerData data)
        }

        class EventLogger {
            +static EventLogger &instance()
            +void writeEventLog(EventLoggerData data)
            +void writeEventLog(qint64 tid, QString target, QString key, QString value)
            +bool init(QString package_id, bool enable_sig)
            -EventLogger()
            -~EventLogger()
            -EventLogger(EventLogger other)
            -EventLogger &operator=(EventLogger other)
            -QJsonDocument structToJson(EventLoggerData data)
            -std::mutex m_mutex
            -bool m_initialized
            -Initialize m_initialize
            -WriteEventLog m_writeEventLog
            -QLibrary m_library
        }

        class shouldEnableEventLog {
        }
    }

    EventLoggerData <.. EventLogger : uses
Loading

File-Level Changes

Change Details Files
Add a header-only C++ event logging facility that dynamically loads libdeepin-event-log.so and exposes a singleton API for structured JSON event logging.
  • Introduce EventLoggerData struct to represent thread id, target, and key-value message payloads.
  • Implement EventLogger singleton that loads libdeepin-event-log.so via QLibrary and resolves Initialize and WriteEventLog symbols.
  • Gate logging and initialization behind a shouldEnableEventLog() helper that enables logging only for UosProfessional edition unless a debug macro is defined.
  • Provide JSON serialization of EventLoggerData using QJsonDocument/QJsonObject and convenience overload to log single key-value events.
  • Protect initialization and logging operations with a std::mutex and track library initialization state.
cpp-include/eventlogger.hpp
Integrate installation of the new C++ header into the existing build and packaging system.
  • Define CPP_INCLUDE_DIR and add an install-misc target to copy eventlogger.hpp into /usr/include/dde-api.
  • Make the out/bin/% rule depend on prepare via an order-only prerequisite and simplify build-binary to depend directly on generated binaries.
  • Extend the install target to also run install-misc so the header is installed with the rest of the dev artifacts.
  • Ensure the dev package picks up the new header via the Debian packaging config (dde-api-dev.install).
Makefile
debian/dde-api-dev.install

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • Since this is a header-only singleton used across multiple translation units, consider avoiding a non-trivial destructor with side effects (library unload) in the header to reduce ODR and static-destruction-order risks; you could rely on process teardown or wrap QLibrary in a separate .cpp-managed helper.
  • The implementation mixes QLibrary with POSIX dynamic loading headers (<dlfcn.h>, <unistd.h>) and doesn’t use the latter, so it’s clearer and safer to remove the unused C headers or switch fully to one mechanism.
  • Library loading and symbol resolution happen unconditionally in the constructor even when shouldEnableEventLog() would later disable logging; to minimize overhead and spurious errors on non-UosProfessional systems, consider deferring load/resolve until init() and guarding it with shouldEnableEventLog().
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Since this is a header-only singleton used across multiple translation units, consider avoiding a non-trivial destructor with side effects (library unload) in the header to reduce ODR and static-destruction-order risks; you could rely on process teardown or wrap QLibrary in a separate .cpp-managed helper.
- The implementation mixes QLibrary with POSIX dynamic loading headers (<dlfcn.h>, <unistd.h>) and doesn’t use the latter, so it’s clearer and safer to remove the unused C headers or switch fully to one mechanism.
- Library loading and symbol resolution happen unconditionally in the constructor even when shouldEnableEventLog() would later disable logging; to minimize overhead and spurious errors on non-UosProfessional systems, consider deferring load/resolve until init() and guarding it with shouldEnableEventLog().

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread cpp-include/eventlogger.hpp Outdated
@Ivy233 Ivy233 force-pushed the feat/add-eventlogger-header branch from 9ba869b to a0a55d9 Compare April 23, 2026 13:03
Add a C++ header-only event logger that can be used by DDE applications
to log user behavior events. The logger uses dlopen to dynamically load
libdeepin-event-log.so library at runtime.

Features:
- Header-only implementation, no linking required
- Dynamic library loading with QLibrary
- System edition check (only UosProfessional enabled by default)
- Debug mode macro for testing on other editions
- LGPL-3.0-or-later license for easy integration

添加用于DDE应用程序的事件日志头文件。日志记录器使用dlopen在运行时动态加载
libdeepin-event-log.so库。

Log: 添加事件日志头文件
PMS: TASK-388657
@Ivy233 Ivy233 force-pushed the feat/add-eventlogger-header branch from a0a55d9 to bb041e9 Compare April 23, 2026 13:26
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

感谢您分享的代码差异。我仔细审查了这些更改,主要涉及添加LGPL-3.0-or-later许可证文件、修改Makefile以安装C++头文件,以及新增一个事件日志记录器的C++头文件。以下是我的审查意见:

1. 语法逻辑审查

eventlogger.hpp:

  • 整体语法正确,C++代码结构清晰
  • 使用了单例模式实现EventLogger类,这是合理的
  • 使用了互斥锁(m_mutex)来保护共享资源,防止多线程竞争
  • 正确地禁用了拷贝构造函数和赋值运算符

Makefile:

  • 修改看起来正确,添加了install-misc目标来安装C++头文件
  • 修改了build-binary目标,添加了prepare作为依赖,确保在构建前准备好环境

2. 代码质量审查

eventlogger.hpp:

  • 代码有良好的注释,特别是SPDX许可证标识
  • 命名清晰,使用了有意义的变量和函数名
  • 使用了RAII原则管理资源(QLibrary在析构函数中自动卸载)
  • 有调试模式开关DDE_EVENTLOG_DEBUG_ENABLE_CURRENT_VERSION,便于开发调试

建议改进:

  1. 考虑将structToJson方法设为static,因为它不依赖于类的实例状态
  2. writeEventLog方法中,可以考虑添加错误日志记录,而不仅仅是初始化失败时记录
  3. 可以考虑使用QMap<QString, QString>const引用作为参数,避免不必要的拷贝

3. 代码性能审查

eventlogger.hpp:

  • 使用了互斥锁保护关键区域,这是必要的,但可能会影响性能
  • structToJson方法中使用了QMapIterator遍历,这是合理的
  • 每次调用writeEventLog都会创建JSON文档,这是必要的,但可以考虑优化频繁调用的情况

建议改进:

  1. 考虑使用QJsonObjectfromVariantMap方法来简化JSON构建
  2. 如果writeEventLog会被频繁调用,可以考虑添加一个批量写入的接口,减少锁竞争

4. 代码安全审查

eventlogger.hpp:

  • 使用了动态加载库的方式,这增加了灵活性,但也引入了潜在的安全风险
  • 没有对输入参数进行验证,例如package_id可能包含恶意内容
  • 使用了QLibrary加载外部库,但没有验证库的完整性和来源

建议改进:

  1. package_id参数进行验证,确保它不包含路径遍历或其他恶意内容
  2. 考虑添加对加载库的完整性检查,例如使用哈希值验证
  3. writeEventLog方法中,考虑添加对event_data的大小限制,防止潜在的拒绝服务攻击
  4. 考虑添加对库加载失败的更详细的错误处理

5. 其他审查意见

许可证文件:

  • 添加LGPL-3.0-or-later许可证是正确的,这允许库被链接到专有软件中,同时保持库本身的自由
  • 确保所有使用此头文件的代码都遵循LGPL-3.0-or-later许可证的要求

Makefile:

  • 确保在安装头文件时设置了正确的权限
  • 考虑添加一个目标来卸载头文件,以便于清理

总体评价

这些更改整体上是合理的,添加了事件日志记录功能,并正确地处理了许可证和安装问题。代码质量较高,但在安全性和性能方面有一些改进空间。建议在合并前考虑上述改进意见,特别是关于输入验证和库加载安全性的改进。

如果您需要更详细的代码示例来实现这些改进,或者有其他问题,请随时告诉我。

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Ivy233, mhduiy

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@Ivy233 Ivy233 merged commit e6c55a2 into linuxdeepin:master Apr 23, 2026
16 of 18 checks passed
@Ivy233 Ivy233 deleted the feat/add-eventlogger-header branch April 23, 2026 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants