fix: set SyslogIdentifier for pre-launch hook scripts#334
fix: set SyslogIdentifier for pre-launch hook scripts#334ComixHe merged 1 commit intolinuxdeepin:masterfrom
Conversation
The issue was that when AM (Application Manager) supports pre-launch hooks, a wrapper script is executed before starting the application. However, systemd uses the script name as the SyslogIdentifier in its command line, causing ambiguous identifiers in journalctl logs. To ensure consistent and clear logging, we now explicitly set the SyslogIdentifier to DSG_APP_ID. Changes made: 1. Modified cmdParse() in main.cpp to parse and store the SyslogIdentifier from command line arguments 2. Added logic to append the SyslogIdentifier property to the systemd unit if provided 3. Updated ApplicationService::Launch() to include --SyslogIdentifier parameter with the application ID when constructing the launch command 4. Increased the estimated command size to accommodate the new parameter This ensures that journalctl logs will consistently use the application ID as the identifier, making logs easier to filter and understand regardless of wrapper script names. fix: 为启动前钩子脚本设置系统日志标识符 问题在于当AM支持启动前钩子时,会在启动应用程序前执行一个包装脚本。然 而systemd会使用脚本名称作为命令行中的SyslogIdentifier,导致journalctl 日志中出现歧义的标识符。为确保日志的一致性和清晰度,我们现在明确将 SyslogIdentifier设置为DSG_APP_ID。 具体修改: 1. 修改main.cpp中的cmdParse()函数以解析和存储命令行参数中的 SyslogIdentifier 2. 添加逻辑,在提供SyslogIdentifier时将其附加到systemd单元属性 3. 更新ApplicationService::Launch()方法,在构建启动命令时包含带有应用程 序ID的--SyslogIdentifier参数 4. 增加了预估命令大小以容纳新参数 这确保journalctl日志将始终使用应用程序ID作为标识符,无论包装脚本名称如 何,都能使日志更易于过滤和理解。
Reviewer's GuideEnsures systemd units launched via the app-launch-helper always set SyslogIdentifier explicitly (using the application ID) by propagating a new SyslogIdentifier argument from ApplicationService::Launch through the launch helper, and appending it as a unit property on the D-Bus call. Sequence diagram for launching app with explicit SyslogIdentifiersequenceDiagram
actor User
participant ApplicationService
participant AppLaunchHelper as app-launch-helper
participant systemd
participant journald
User->>ApplicationService: Launch(action, fields, args)
ApplicationService->>ApplicationService: Build newCommands
ApplicationService->>ApplicationService: Add --unitName=app-DDE-id@uuid.service
ApplicationService->>ApplicationService: Add --SyslogIdentifier=applicationId
ApplicationService->>AppLaunchHelper: Exec with newCommands
AppLaunchHelper->>AppLaunchHelper: cmdParse(cmdLines)
AppLaunchHelper->>AppLaunchHelper: Parse SyslogIdentifier from cmdLines
AppLaunchHelper->>AppLaunchHelper: Build D-Bus msg
AppLaunchHelper->>AppLaunchHelper: Append SyslogIdentifier property
AppLaunchHelper->>systemd: sd_bus_call(StartTransientUnit)
systemd->>systemd: Start app unit with SyslogIdentifier=applicationId
systemd->>journald: Send logs tagged with applicationId
journald-->>User: journalctl filter SyslogIdentifier=applicationId
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- If application IDs can contain characters not ideal for systemd/journal identifiers (e.g. spaces, special chars), consider reusing
escapeApplicationId(...)or a similar sanitization for the--SyslogIdentifiervalue instead of passingthis->id()raw. - The
estimatedSizeconstant inApplicationService::Launchis a bit opaque; consider deriving it from named counts (e.g.baseArgs = 3for--unitName,--SyslogIdentifier,--SourcePath) or adding a brief comment so future changes don’t accidentally desync the estimate and the actual arguments appended.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- If application IDs can contain characters not ideal for systemd/journal identifiers (e.g. spaces, special chars), consider reusing `escapeApplicationId(...)` or a similar sanitization for the `--SyslogIdentifier` value instead of passing `this->id()` raw.
- The `estimatedSize` constant in `ApplicationService::Launch` is a bit opaque; consider deriving it from named counts (e.g. `baseArgs = 3` for `--unitName`, `--SyslogIdentifier`, `--SourcePath`) or adding a brief comment so future changes don’t accidentally desync the estimate and the actual arguments appended.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
deepin pr auto review这段代码的修改旨在为应用启动添加 1. 语法逻辑审查
2. 代码质量审查
3. 代码性能审查
4. 代码安全审查
综合改进建议代码
// ... (前略)
// 检查 SyslogIdentifier 是否非空
if (!syslogIdentifier.empty()) {
// 修正后的错误处理逻辑
int ret = sd_bus_message_append(msg,
"(sv)",
"SyslogIdentifier",
"s",
syslogIdentifier.c_str());
if (ret < 0) {
sd_journal_perror("failed to append SyslogIdentifier property.");
return std::nullopt;
}
}
if (ret = processKVPair(msg, props); ret < 0) { // process props
// 建议在此处也添加日志,如果 processKVPair 内部没有的话
// sd_journal_perror("failed to process KV pairs.");
return std::nullopt;
}
// ... (后略)
// ... (前略)
QStringList newCommands;
// 预留空间计算正确
const int estimatedSize = 6 + cmds.size() + task.command.size() + (value.isValid() ? 1 : 0);
newCommands.reserve(estimatedSize);
// 确保 id() 是安全的,或者进行转义/校验
QString appId = this->id();
// 可选:简单的校验示例,确保只包含安全字符
// if (appId.contains(QRegularExpression("[^a-zA-Z0-9._-]"))) { ... handle error ... }
newCommands
<< QStringLiteral("--unitName=app-DDE-%1@%2.service").arg(escapeApplicationId(appId), instanceRandomUUID);
newCommands << QStringLiteral("--SyslogIdentifier=%1").arg(appId);
newCommands << QStringLiteral("--SourcePath=%1").arg(m_desktopSource.sourcePath());
newCommands << std::move(cmds);
// ... (后略)总结这段代码修改在功能上是合理的,主要改进点在于修正 |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: ComixHe, mhduiy The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
此提交为了修复 DDE 的 journalctl 中经常出现
debfix.sh标识符的问题原因
经过分析,systemd会自动捕获stderr和stdout到日志系统,只要dtk程序声明了
DLogManager::registerConsoleAppender();,就会把日志打印到标准输出,从而进入journalctl中。AM启动应用时套用了一个hook,这个hook会wrap启动程序,虽然debFix中使用了exec去启动主程序,但是递给systemd的cmdline已经包含了该脚本名称,根据其文档,会把这个脚本作为标识符传进日志系统中,就导致出现了debfix.sh 这个标识符,下面是systemd拿到的cmdline识别到
SYSLOG_IDENTIFIER=debFix.sh,所以最终就表现为debFix.sh输出,这是不合理的修复方案
只要wrap脚本就可能会出现这样的现象,最好的方式就是手动指定标识符,手动解析cmdline 不太靠谱,在deepin上本身存在一个标识符 DSG_APP_ID,且通过AM启动时默认注入了这个环境变量,所以考虑使用 DSG_APP_ID 作为标识符,大部分情况下他就是应用启动器文件的文件名(经过一些转译)
另外,额外发现大部分通过AM启动的dtk应用会打印两次重复日志,其实一次是systemd捕获标准输出到journalctl的,一个是dtk程序可能会注册
DLogManager::registerJournalAppender();,使用journal的api传递进journal日志系统中,使用的改进方案是当检测到应用由systemd启动、重定向输出并手动开启了journal日志打印,则不向控制台打印日志影响
通过AM启动的应用,重定向标准输出到日志系统的标识符会变为 DSG_APP_ID ,大部分情况下就是其转译后desktop文件的文件名,其余仅通过systemd service 或者 通过journal api 写入的日志不受影响