@cryptotaxi247 / netdata-1 / commits / a9e6334ed

apps.plugin logs repeating errors, only once per process; fixes #779

Costa Tsaousis committed Aug 14, 2016 at 15:33 UTC a9e6334edcec1af647e84bd85542fd467d8e9a33
1 file changed +78 -51
src/apps_plugin.c
+78 -51
@@ -394,11 +394,19 @@ int read_apps_groups_conf(const char *name)
394 // data to store for each pid
395 // see: man proc
396
397 +#define PID_LOG_IO 0x00000001
398 +#define PID_LOG_STATM 0x00000002
399 +#define PID_LOG_CMDLINE 0x00000004
400 +#define PID_LOG_FDS 0x00000008
401 +#define PID_LOG_STAT 0x00000010
402 +
403 struct pid_stat {
404 int32_t pid;
405 char comm[MAX_COMPARE_NAME + 1];
406 char cmdline[MAX_CMDLINE + 1];
407
408 + uint32_t log_thrown;
409 +
410 // char state;
411 int32_t ppid;
412 // int32_t pgrp;
@@ -583,7 +591,7 @@ int read_proc_pid_cmdline(struct pid_stat *p) {
591 ssize_t i, bytes = read(fd, p->cmdline, MAX_CMDLINE);
592 close(fd);
593
586 - if(unlikely(bytes <= 0)) goto cleanup;
594 + if(unlikely(bytes < 0)) goto cleanup;
595
596 p->cmdline[bytes] = '\0';
597 for(i = 0; i < bytes ; i++)
@@ -592,7 +600,7 @@ int read_proc_pid_cmdline(struct pid_stat *p) {
600 if(unlikely(debug))
601 fprintf(stderr, "Read file '%s' contents: %s\n", p->cmdline_filename, p->cmdline);
602
595 - return 0;
603 + return 1;
604
605 cleanup:
606 // copy the command to the command line
@@ -603,7 +611,7 @@ cleanup:
611 int read_proc_pid_ownership(struct pid_stat *p) {
612 if(unlikely(!p->stat_filename)) {
613 error("pid %d does not have a stat_filename", p->pid);
606 - return 1;
614 + return 0;
615 }
616
617 // ----------------------------------------
@@ -618,7 +626,7 @@ int read_proc_pid_ownership(struct pid_stat *p) {
626 p->uid = st.st_uid;
627 p->gid = st.st_gid;
628
621 - return 0;
629 + return 1;
630 }
631
632 int read_proc_pid_stat(struct pid_stat *p) {
@@ -749,7 +757,7 @@ int read_proc_pid_stat(struct pid_stat *p) {
757 p->cgtime = 0;
758 }
759
752 - return 0;
760 + return 1;
761
762 cleanup:
763 p->minflt = 0;
@@ -764,7 +772,7 @@ cleanup:
772 p->cgtime = 0;
773 p->num_threads = 0;
774 p->rss = 0;
767 - return 1;
775 + return 0;
776 }
777
778 int read_proc_pid_statm(struct pid_stat *p) {
@@ -792,7 +800,7 @@ int read_proc_pid_statm(struct pid_stat *p) {
800 p->statm_data = strtoull(procfile_lineword(ff, 0, 5), NULL, 10);
801 p->statm_dirty = strtoull(procfile_lineword(ff, 0, 6), NULL, 10);
802
795 - return 0;
803 + return 1;
804
805 cleanup:
806 p->statm_size = 0;
@@ -802,7 +810,7 @@ cleanup:
810 p->statm_lib = 0;
811 p->statm_data = 0;
812 p->statm_dirty = 0;
805 - return 1;
813 + return 0;
814 }
815
816 int read_proc_pid_io(struct pid_stat *p) {
@@ -866,7 +874,7 @@ int read_proc_pid_io(struct pid_stat *p) {
874 p->io_cancelled_write_bytes = 0;
875 }
876
869 - return 0;
877 + return 1;
878
879 cleanup:
880 p->io_logical_bytes_read = 0;
@@ -876,7 +884,7 @@ cleanup:
884 p->io_storage_bytes_read = 0;
885 p->io_storage_bytes_written = 0;
886 p->io_cancelled_write_bytes = 0;
879 - return 1;
887 + return 0;
888 }
889
890 unsigned long long global_utime = 0;
@@ -937,13 +945,13 @@ int read_proc_stat() {
945 global_gtime = 0;
946 }
947
940 - return 0;
948 + return 1;
949
950 cleanup:
951 global_utime = 0;
952 global_stime = 0;
953 global_gtime = 0;
946 - return 1;
954 + return 0;
955 }
956
957
@@ -1248,7 +1256,7 @@ int read_pid_file_descriptors(struct pid_stat *p) {
1256
1257 // else make it positive again, we need it
1258 // of course, the actual file may have changed, but we don't care so much
1251 - // FIXME: we could compare the inode as returned by readdir direct structure
1259 + // FIXME: we could compare the inode as returned by readdir dirent structure
1260 else p->fds[fdid] = -p->fds[fdid];
1261 }
1262 closedir(fds);
@@ -1259,9 +1267,9 @@ int read_pid_file_descriptors(struct pid_stat *p) {
1267 p->fds[c] = 0;
1268 }
1269 }
1262 - else return 1;
1270 + else return 0;
1271
1264 - return 0;
1272 + return 1;
1273 }
1274
1275 // ----------------------------------------------------------------------------
@@ -1571,6 +1579,49 @@ static int compar_pid(const void *pid1, const void *pid2) {
1579 return 1;
1580 }
1581
1582 +static inline int managed_log(struct pid_stat *p, uint32_t log, int status) {
1583 + if(unlikely(!status)) {
1584 + // error("command failed log %u, errno %d", log, errno);
1585 +
1586 + if(unlikely(debug || errno != ENOENT)) {
1587 + if(unlikely(debug || !(p->log_thrown & log))) {
1588 + p->log_thrown |= log;
1589 + switch(log) {
1590 + case PID_LOG_IO:
1591 + error("Cannot process %s/proc/%d/io (command '%s')", host_prefix, p->pid, p->comm);
1592 + break;
1593 +
1594 + case PID_LOG_STATM:
1595 + error("Cannot process %s/proc/%d/statm (command '%s')", host_prefix, p->pid, p->comm);
1596 + break;
1597 +
1598 + case PID_LOG_CMDLINE:
1599 + error("Cannot process %s/proc/%d/cmdline (command '%s')", host_prefix, p->pid, p->comm);
1600 + break;
1601 +
1602 + case PID_LOG_FDS:
1603 + error("Cannot process entries in %s/proc/%d/fd (command '%s')", host_prefix, p->pid, p->comm);
1604 + break;
1605 +
1606 + case PID_LOG_STAT:
1607 + break;
1608 +
1609 + default:
1610 + error("unhandled error for pid %d, command '%s'", p->pid, p->comm);
1611 + break;
1612 + }
1613 + }
1614 + }
1615 + errno = 0;
1616 + }
1617 + else if(unlikely(p->log_thrown & log)) {
1618 + // error("unsetting log %u on pid %d", log, p->pid);
1619 + p->log_thrown &= ~log;
1620 + }
1621 +
1622 + return status;
1623 +}
1624 +
1625 void collect_data_for_pid(pid_t pid) {
1626 if(unlikely(pid <= 0 || pid > pid_max)) {
1627 error("Invalid pid %d read (expected 1 to %d). Ignoring process.", pid, pid_max);
@@ -1586,14 +1637,9 @@ void collect_data_for_pid(pid_t pid) {
1637 // --------------------------------------------------------------------
1638 // /proc/<pid>/stat
1639
1589 - if(unlikely(read_proc_pid_stat(p))) {
1590 - if(errno != ENOENT || debug)
1591 - error("Cannot process %s/proc/%d/stat (command '%s')", host_prefix, pid, p->comm);
1592 - else
1593 - errno = 0;
1640 + if(unlikely(!managed_log(p, PID_LOG_STAT, read_proc_pid_stat(p))))
1641 // there is no reason to proceed if we cannot get its status
1642 return;
1596 - }
1643
1644 read_proc_pid_ownership(p);
1645
@@ -1606,24 +1652,14 @@ void collect_data_for_pid(pid_t pid) {
1652 // --------------------------------------------------------------------
1653 // /proc/<pid>/io
1654
1609 - if(unlikely(read_proc_pid_io(p))) {
1610 - if(errno != ENOENT || debug)
1611 - error("Cannot process %s/proc/%d/io (command '%s')", host_prefix, pid, p->comm);
1612 - else
1613 - errno = 0;
1614 - }
1655 + managed_log(p, PID_LOG_IO, read_proc_pid_io(p));
1656
1657 // --------------------------------------------------------------------
1658 // /proc/<pid>/statm
1659
1619 - if(unlikely(read_proc_pid_statm(p))) {
1620 - if(errno != ENOENT || debug)
1621 - error("Cannot process %s/proc/%d/statm (command '%s')", host_prefix, pid, p->comm);
1622 - else
1623 - errno = 0;
1660 + if(unlikely(!managed_log(p, PID_LOG_STATM, read_proc_pid_statm(p))))
1661 // there is no reason to proceed if we cannot get its memory status
1662 return;
1626 - }
1663
1664 // --------------------------------------------------------------------
1665 // link it
@@ -1632,14 +1668,8 @@ void collect_data_for_pid(pid_t pid) {
1668 // we do this only once, the first time this pid is loaded
1669 if(unlikely(p->new_entry)) {
1670 // /proc/<pid>/cmdline
1635 - if(likely(proc_pid_cmdline_is_needed)) {
1636 - if(unlikely(read_proc_pid_cmdline(p))) {
1637 - if(errno != ENOENT || debug)
1638 - error("Cannot process %s/proc/%d/cmdline (command '%s')", host_prefix, pid, p->comm);
1639 - else
1640 - errno = 0;
1641 - }
1642 - }
1671 + if(likely(proc_pid_cmdline_is_needed))
1672 + managed_log(p, PID_LOG_CMDLINE, read_proc_pid_cmdline(p));
1673
1674 if(unlikely(debug))
1675 fprintf(stderr, "apps.plugin: \tJust added %d (%s)\n", pid, p->comm);
@@ -1675,12 +1705,7 @@ void collect_data_for_pid(pid_t pid) {
1705 // --------------------------------------------------------------------
1706 // /proc/<pid>/fd
1707
1678 - if(unlikely(read_pid_file_descriptors(p))) {
1679 - if(errno != ENOENT || debug)
1680 - error("Cannot process entries in %s/proc/%d/fd (command '%s')", host_prefix, pid, p->comm);
1681 - else
1682 - errno = 0;
1683 - }
1708 + managed_log(p, PID_LOG_FDS, read_pid_file_descriptors(p));
1709
1710 // --------------------------------------------------------------------
1711 // done!
@@ -2752,6 +2777,8 @@ int main(int argc, char **argv)
2777 // set the name for logging
2778 program_name = "apps.plugin";
2779
2780 + info("started on pid %d", getpid());
2781 +
2782 // disable syslog for apps.plugin
2783 error_log_syslog = 0;
2784
@@ -2761,17 +2788,17 @@ int main(int argc, char **argv)
2788
2789 host_prefix = getenv("NETDATA_HOST_PREFIX");
2790 if(host_prefix == NULL) {
2764 - info("NETDATA_HOST_PREFIX is not passed from netdata");
2791 + // info("NETDATA_HOST_PREFIX is not passed from netdata");
2792 host_prefix = "";
2793 }
2767 - else info("Found NETDATA_HOST_PREFIX='%s'", host_prefix);
2794 + // else info("Found NETDATA_HOST_PREFIX='%s'", host_prefix);
2795
2796 config_dir = getenv("NETDATA_CONFIG_DIR");
2797 if(config_dir == NULL) {
2771 - info("NETDATA_CONFIG_DIR is not passed from netdata");
2798 + // info("NETDATA_CONFIG_DIR is not passed from netdata");
2799 config_dir = CONFIG_DIR;
2800 }
2774 - else info("Found NETDATA_CONFIG_DIR='%s'", config_dir);
2801 + // else info("Found NETDATA_CONFIG_DIR='%s'", config_dir);
2802
2803 #ifdef NETDATA_INTERNAL_CHECKS
2804 if(debug_flags != 0) {