【问题标题】:calling journalctl from java从java调用journalctl
【发布时间】:2014-11-27 20:43:21
【问题描述】:

当我在 Centos 7 linux 终端中以 root 用户身份运行以下命令时,它会产生 57 行输出:

journalctl --output=json-pretty UNIT=firewalld.service  

那么如何更改下面的代码以成功地从 Java 调用它而无需将密码留在文件中?

这是我的尝试。当我执行以下代码时,控制台只输出exit: 1

String s;
Process p;
try {
    p = Runtime.getRuntime().exec("journalctl --output=json-pretty UNIT=firewalld.service");
    BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
    while ((s = br.readLine()) != null)
        System.out.println("line: " + s);
    p.waitFor();
    System.out.println ("exit: " + p.exitValue());
    p.destroy();
} catch (Exception e) {}  

编辑:

当我添加以下内容时:

BufferedReader br2 = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while ((s = br2.readLine()) != null)
    System.out.println("error line: " + s);

生成以下输出:

error line: No journal files were found.
error line: Failed to get realtime timestamp: Cannot assign requested address

问题与权限有关吗?当我从 linux 终端以 root 运行 journalctl --output=json-pretty UNIT=firewalld.service 时,我得到了 57 行输出。但是当我以普通用户身份运行journalctl --output=json-pretty UNIT=firewalld.service 时,终端告诉我没有找到文件。我不想将我的 root 密码放在 java 代码中。有没有其他方法可以从java调用journalctl而不必将系统root密码留在文件中?

【问题讨论】:

  • 退出状态为1 表示错误。您应该阅读错误流 (p.getErrorStream()),它可能包含错误消息。如果你分享它会很有帮助。你是从命令行运行java程序吗?
  • 您刚刚打印了 Stream 对象。我的意思是你必须阅读它 - 这是一个InputStream,你需要打开一个BufferedReader并将每一行打印到System.out或其他东西。
  • 在 CentOS 将他们的文档与现实保持一致之前,您最好的选择是执行 sudo chmod og+s /usr/bin/journalctl 以允许普通用户使用 journalctl。既不能添加到 systemd-journal(根据手册页),也不能根据 pid-eins 添加到 adm 在 CentOS 7 上工作
  • grep 应该与此更改一起工作是不是不足以获取写入日志的单位列表?
  • 我还用 RealSkeptic 的见解更新了我的答案,现在我可以像普通人一样使用 journalctl,这只是 systemd-journal 的成员

标签: java linux centos


【解决方案1】:

您可以使用usermod -a -G systemd-journal <username> 将您的(普通)用户添加到组systemd-journal。注销并登录以使更改生效。这使您的用户可以访问系统日志文件,而无需授予其完整的 root 权限。

对于不同的操作系统设置,该组可能不同。如果/var/log/journal/ 不存在,您可以使用ls -l /var/log/journal/ls -l /run/systemd/journal/ 简单地查看日志文件属于哪个组。

我在 Centos LiveCD 中试过这个,文件所属的组是root。因此,您可以将用户添加到组 root,这与授予其完全 root 权限相同。

尽管如此,我认为更好的方法是在日志文件上设置 ACL 以允许特定组访问它们,因为 root 组可能访问的权限太多了。 systemd-journald.service 的手册给出了这个示例 ACL 修改命令,它授予 wheeladm 对日志的读取访问权限:

setfacl -Rnm g:wheel:rx,d:g:wheel:rx,g:adm:rx,d:g:adm:rx /var/log/journal/

【讨论】:

  • 手册页是这么说的,但这在 CentOS 7 上不起作用(根据pid-eins 添加到组adm 也不起作用。如果你有这个工作在哪一种系统?
  • @Anthon 我对此进行了一些研究并添加到我的答案中。尽管您的信息已被接受,但我认为您可能会发现这些信息很有用(或者您可能希望进一步批评它)。
  • 我的回答并不优雅,它只是有效(而且我理解它的作用;-))。你的方法更好,虽然它并没有完全解决 CentOS 7 上的问题,但它指向了正确的方向(我必须阅读 setfacl)。
【解决方案2】:

虽然journalctl 的手册页告诉您将用户添加到systemd-journal 应该允许他们访问所有期刊,但这在 CentOS 7 上不起作用。我最初通过以下方式解决了这个问题:

chmod +s /usr/bin/journalctl

但这让每个人都可以访问期刊,而这可能不是你想要的

正如@RealSkeptic 指出systemd-journald.serviceman 页面表明,可以向组授予额外的访问权限以阅读日志(并指出将用户添加到systemd-journal 就足够了)。结合你可以做的信息

sudo setfacl -Rnm g:systemd-journal:rx,d:g:systemd-journal:rx /run/log/journal/

然后根据手册页将用户添加到systemd-journal 组就足以允许访问日志:

sudo usermod -a -G systemd-journal your_user_name

【讨论】:

    猜你喜欢
    • 2021-11-20
    • 2023-01-11
    • 2019-03-12
    • 2020-07-07
    • 1970-01-01
    • 2015-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多