40

In a CentOS 7 server, I want to get the list of selectable units for which journalctl can produce logs. How can I change the following code to accomplish this?

journalctl --output=json-pretty | grep -f UNIT | sort -u  

In the CentOS 7 terminal, the above code produces grep: UNIT: No such file or directory.

EDIT:

The following java program is terminating without printing any output from the desired grep. How can I change things so that the java program works in addition to the terminal version?

    String s;
    Process p;
    String[] cmd = {"journalctl --output=json-pretty ","grep UNIT ","sort -u"};
    try {
        p = Runtime.getRuntime().exec(cmd);
        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.getErrorStream());
        BufferedReader br2 = new BufferedReader(new InputStreamReader(p.getErrorStream()));
        while ((s = br2.readLine()) != null)
            System.out.println("error line: " + s);
        p.waitFor();
        p.destroy();
    } catch (Exception e) {}  
3
  • "but not when i call it from the a java program" and the Java program?
    – Braiam
    Nov 28, 2014 at 0:18
  • There is a typo in that, it should be grep -F
    – Anthon
    Nov 28, 2014 at 6:31
  • @don_crissti As you wish.
    – CodeMed
    Oct 26, 2015 at 17:42

2 Answers 2

50

journalctl can display logs for all units - whether these units write to the log is a different matter.

To list all available units and therefore all available for journalctl to use:

systemctl list-unit-files --all

As to your java code, in order to make pipes work with Runtime.exec() you could either put the command in a script and invoke the script or use a string array, something like:

String[] cmd = {"sh", "-c", "command1 | command2 | command3"};
p = Runtime.getRuntime().exec(cmd);

or:

Runtime.getRuntime().exec(new String[]{"sh", "-c", "command1 | command2 | command3"});
1
  • list-unit-files doesn't show instantiated units and transient units.
    – Evgeny
    Oct 30, 2015 at 10:52
33

man journalctl says:

-F, --field= Print all possible data values the specified field can take in all entries of the journal.

So, you can run:

journalctl --field _SYSTEMD_UNIT

to get the list of selectable units for which journalctl can produce logs

(by default, only root and users who are members of a few special groups are granted access to the system journal and the journals of other users. Members of the groups systemd-journal, adm, and wheel can read all journal files. )

8
  • You must be a superuser to run that command. So make it sudo journalctl --field _SYSTEMD_UNIT. But otherwise thank you and +1 for adding insight.
    – CodeMed
    Oct 30, 2015 at 16:36
  • Actually if you don't sudo you can use journalctl but you only get a tiny list of units that are directly related to your user's session.
    – dragon788
    Jan 29, 2018 at 16:42
  • 2
    This should be the accepted answer as systemd 219 does not support the arguments list-unit-files --all provided in the currently accepted answer.
    – Petrus K.
    Feb 7, 2018 at 15:36
  • 1
    list-unit-files just shows the unit files. You can get a similar list by just typing "systemctl" with no arguments. Most of them do not support journald so that command is of no use.
    – fred
    Jan 15, 2019 at 20:17
  • Very much seems this is the correct answer. Not clear if sudo is needed on some distributions. ~ journalctl --field _SYSTEMD_UNIT | wc -l 100 ~ sudo journalctl --field _SYSTEMD_UNIT | wc -l 100 ~ lsb_release -d Description: Pop!_OS 20.10 Jan 4, 2021 at 6:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .