Mercurial > hg > release > heapstats-1.1
changeset 25:b8a514c97fb7
Bug 1849: HeapStats agent should collect systemd-journald information
reviewed-by: yasuenag
author | KUBOTA Yuji <kubota.yuji@lab.ntt.co.jp> |
---|---|
date | Fri, 20 Jun 2014 11:58:32 +0900 |
parents | a3d52921b48f |
children | 8008ab68f482 |
files | agent/ChangeLog agent/src/logManager.cpp |
diffstat | 2 files changed, 78 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/agent/ChangeLog Thu Jun 19 00:01:36 2014 +0900 +++ b/agent/ChangeLog Fri Jun 20 11:58:32 2014 +0900 @@ -1,3 +1,7 @@ +2014-06-20 KUBOTA Yuji <kubota.yuji@lab.ntt.co.jp> + + * Bug 1849: HeapStats agent should collect systemd-journald information + 2014-06-18 Yasumasa Suenaga <yasuenag@gmail.com> * Bug 1683: HeapStats agent should be adapted to JDK-8027746
--- a/agent/src/logManager.cpp Thu Jun 19 00:01:36 2014 +0900 +++ b/agent/src/logManager.cpp Fri Jun 20 11:58:32 2014 +0900 @@ -31,6 +31,7 @@ #include <limits.h> #include <sys/stat.h> #include <sys/types.h> +#include <sys/wait.h> #include <dirent.h> #include <errno.h> @@ -1250,8 +1251,6 @@ /* Netstat infomation. */ "/proc/net/tcp", "/proc/net/tcp6", "/proc/net/udp", "/proc/net/udp6", - /* Syslog. */ - "/var/log/messages", /* End flag. */ {0} }; @@ -1277,7 +1276,79 @@ } } - + + /* 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. + */ + result = copyFile("/var/log/messages", basePath); + if (unlikely(result != 0)) { + PRINT_WARN_MSG_AND_ERRNO("Failure copy file. path:\"/var/log/messages\"", result); + /* If disk is full. */ + if(unlikely(isRaisedDiskFull(result))){ + return result; + } + } + + /* Collect systemd-journald instead of syslog when failed to copy syslog, */ + if (result != 0) { + /* + * 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(errno); + } if (dup2(fd, 2) < 0) { + close(fd); + _exit(errno); + } + 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(errno); + } else if(child < 0) { + /* vfork failed */ + result = errno; + PRINT_WARN_MSG_AND_ERRNO("Failure collect systemd-journald log by vfork().", result); + } else { + /* Parent process */ + int status; + if (waitpid(child, &status, 0) < 0) { + /* The child process failed. */ + result = errno; + PRINT_WARN_MSG_AND_ERRNO("Failure collect systemd-journald log by process error.", result); + /* If disk is full. */ + if(unlikely(isRaisedDiskFull(result))){ + return result; + } + } + if (WIFEXITED(status)) { + /* The child exited normally, get the returns as result. */ + result = WEXITSTATUS(status); + if (result != 0) { + PRINT_WARN_MSG_AND_ERRNO("Failure collect systemd-journald log.", result); + } + } 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 */ result = copyFile("/proc/self/fd/1", basePath, "fd1"); if(unlikely(result != 0)){