# HG changeset patch # User KUBOTA Yuji # Date 1403233855 -32400 # Node ID db8eea95ac52867f9799418f0a1509a2b6e87424 # Parent b1930d079140b450949003e5e76028a88398ed69 Bug 1849: HeapStats agent should collect systemd-journald information reviewed-by: yasuenag diff -r b1930d079140 -r db8eea95ac52 agent/ChangeLog --- a/agent/ChangeLog Wed Jun 18 23:59:21 2014 +0900 +++ b/agent/ChangeLog Fri Jun 20 12:10:55 2014 +0900 @@ -1,3 +1,7 @@ +2014-06-20 KUBOTA Yuji + + * Bug 1849: HeapStats agent should collect systemd-journald information + 2014-06-18 Yasumasa Suenaga * Bug 1683: HeapStats agent should be adapted to JDK-8027746 diff -r b1930d079140 -r db8eea95ac52 agent/src/logManager.cpp --- a/agent/src/logManager.cpp Wed Jun 18 23:59:21 2014 +0900 +++ b/agent/src/logManager.cpp Fri Jun 20 12:10:55 2014 +0900 @@ -31,6 +31,7 @@ #include #include #include +#include #include "logManager.hpp" #include "util.hpp" @@ -1063,8 +1064,6 @@ /* Netstat infomation. */ "/proc/net/tcp", "/proc/net/tcp6", "/proc/net/udp", "/proc/net/udp6", - /* Syslog. */ - "/var/log/messages", /* End flag. */ {0} }; @@ -1078,6 +1077,68 @@ } } + /* Collect Syslog or Systemd-Journald */ + /* + * Try to copy syslog at first, because journal daemon will forward all received + * log messages to a traditional syslog by default. + */ + bool hasSyslog = copyFile("/var/log/messages", basePath); + if (unlikely(!hasSyslog)) { + PRINT_WARN_MSG("Failure copy file. path:\"/var/log/messages\""); + } + + /* Collect systemd-journald instead of syslog when failed to copy syslog, */ + if (!hasSyslog) { + /* + * Select vfork() to run journalctl in a separate process. Unlikely system(), + * this function does not block SIGINT, et al. Unlikely fork(), this function + * does not copy but shares all memory with its parent, including the stack. + */ + pid_t child = vfork(); + if ( child == 0 ) { + /* Child process */ + /* logfile name shows what command is used to output it.*/ + char logfile[PATH_MAX]; + sprintf(logfile, "%s%s", basePath, "/journalctl_-q_--all_--this-boot_--no-pager_-o_verbose.log"); + /* Redirect child process' stdout/stderr to logfile */ + int fd = open(logfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + if (dup2(fd, 1) < 0) { + close(fd); + _exit(EXIT_FAILURE); + } if (dup2(fd, 2) < 0) { + close(fd); + _exit(EXIT_FAILURE); + } + close(fd); + /* Use execve() for journalctl to prevent command injection */ + const char * argv[] = {"journalctl", "-q", "--all", "--this-boot", "--no-pager", "-o", "verbose", NULL}; + extern char **environ; + execve("/bin/journalctl", (char* const*)argv, environ); + /* if execve returns, it has failed */ + _exit(EXIT_FAILURE); + } else if(child < 0) { + /* vfork failed */ + PRINT_WARN_MSG("Failure collect systemd-journald log by vfork()."); + } else { + /* Parent process */ + int status; + /* Wait for the child process to exit. If the child has already exited, + * this returns immediately. */ + if (waitpid(child, &status, 0) < 0) { + PRINT_WARN_MSG("Failure collect systemd-journald log by process error."); + } + if (WIFEXITED(status)) { + /* The child exited normally, get the status as result. */ + if (WEXITSTATUS(status) != 0) { + PRINT_WARN_MSG("Failure collect systemd-journald log."); + } + } else { + /* The child exited with a signal or unknown exit code. */ + PRINT_WARN_MSG("Failure collect systemd-journald log by signal or unknown exit code."); + } + } + } + /* Copy stdout. */ if (unlikely(!copyFile("/proc/self/fd/1", basePath, "fd1"))) { PRINT_WARN_MSG("Failure copy standard output."); @@ -1087,7 +1148,7 @@ if (unlikely(!copyFile("/proc/self/fd/2", basePath, "fd2"))) { PRINT_WARN_MSG("Failure copy standard error."); } - + } /*!