Пример #1
0
int
main (int argc, char **argv)
{
  int c, err;
  bool verbose, cpu_model, per_cpu_stats;
  unsigned long len, i, count, delay;
  char *critical = NULL, *warning = NULL;
  char *p = NULL, *cpu_progname;
  nagstatus currstatus, status;
  thresholds *my_threshold = NULL;

  float cpu_perc = 0.0;
  unsigned int tog = 0;		/* toggle switch for cleaner code */
  struct cpu_desc *cpudesc = NULL;

  set_program_name (argv[0]);

  len = strlen (program_name);
  if (len > 6 && !strncmp (program_name, "check_", 6))
    p = (char *) program_name + 6;
  else
    plugin_error (STATE_UNKNOWN, 0,
		  "bug: the plugin does not have a standard name");

  if (!strncmp (p, "iowait", 6))	/* check_iowait --> cpu_iowait */
    {
      cpu_progname = xstrdup ("iowait");
      program_shorthelp =
        xstrdup ("This plugin checks I/O wait bottlenecks\n");
    }
  else				/* check_cpu --> cpu_user (the default) */
    {
      cpu_progname = xstrdup ("user");;
      program_shorthelp =
        xstrdup ("This plugin checks the CPU (user mode) utilization\n");
    }

  err = cpu_desc_new (&cpudesc);
  if (err < 0)
    plugin_error (STATE_UNKNOWN, err, "memory exhausted");

  /* default values */
  verbose = per_cpu_stats = false;
  cpu_model = true;

  while ((c = getopt_long (
		argc, argv, "c:w:vifmp"
		GETOPT_HELP_VERSION_STRING, longopts, NULL)) != -1)
    {
      switch (c)
	{
	default:
	  usage (stderr);
	case 'i':
	  cpu_desc_read (cpudesc);
	  cpu_desc_summary (cpudesc);
	  return STATE_UNKNOWN;
	case 'm':
	  cpu_model = false;
	  break;
	case 'p':
	  per_cpu_stats = true;
	  break;
	case 'c':
	  critical = optarg;
	  break;
	case 'w':
	  warning = optarg;
	  break;
	case 'v':
	  verbose = true;
	  break;

	case_GETOPT_HELP_CHAR
	case_GETOPT_VERSION_CHAR

	}
    }

  delay = DELAY_DEFAULT, count = COUNT_DEFAULT;
  if (optind < argc)
    {
      delay = strtol_or_err (argv[optind++], "failed to parse argument");

      if (delay < 1)
	plugin_error (STATE_UNKNOWN, 0, "delay must be positive integer");
      else if (DELAY_MAX < delay)
	plugin_error (STATE_UNKNOWN, 0,
		      "too large delay value (greater than %d)", DELAY_MAX);
    }

  if (optind < argc)
    {
      count = strtol_or_err (argv[optind++], "failed to parse argument");
      if (COUNT_MAX < count)
	plugin_error (STATE_UNKNOWN, 0,
		      "too large count value (greater than %d)", COUNT_MAX);
    }

  status = set_thresholds (&my_threshold, warning, critical);
  if (status == NP_RANGE_UNPARSEABLE)
    usage (stderr);

  int ncpus = per_cpu_stats ? get_processor_number_total () + 1 : 1;

  jiff duser[ncpus], dsystem[ncpus], didle[ncpus],
       diowait[ncpus], dsteal[ncpus], ratio[ncpus];
  int debt[ncpus];			/* handle idle ticks running backwards */
  struct cpu_time cpuv[2][ncpus];
  jiff *cpu_value = strncmp (p, "iowait", 6) ? duser : diowait;
  const char *cpuname;

  cpu_stats_get_time (cpuv[0], ncpus);

  for (c = 0; c < ncpus; c++)
    {
      duser[c]   = cpuv[0][c].user + cpuv[0][c].nice;
      dsystem[c] = cpuv[0][c].system + cpuv[0][c].irq + cpuv[0][c].softirq;
      didle[c]   = cpuv[0][c].idle;
      diowait[c] = cpuv[0][c].iowait;
      dsteal[c]  = cpuv[0][c].steal;

      debt[c] = 0;
      ratio[c] = duser[c] + dsystem[c] + didle[c] + diowait[c] + dsteal[c];
      if (!ratio[c])
	ratio[c] = 1, didle[c] = 1;
    }

  for (i = 1; i < count; i++)
    {
      sleep (delay);
      tog = !tog;
      cpu_stats_get_time (cpuv[tog], ncpus);

      for (c = 0; c < ncpus; c++)
	{
	  duser[c] =
	    cpuv[tog][c].user - cpuv[!tog][c].user +
	    cpuv[tog][c].nice - cpuv[!tog][c].nice;
	  dsystem[c] =
	    cpuv[tog][c].system  - cpuv[!tog][c].system +
	    cpuv[tog][c].irq     - cpuv[!tog][c].irq +
	    cpuv[tog][c].softirq - cpuv[!tog][c].softirq;
	  didle[c]   = cpuv[tog][c].idle   - cpuv[!tog][c].idle;
	  diowait[c] = cpuv[tog][c].iowait - cpuv[!tog][c].iowait;
	  dsteal[c]  = cpuv[tog][c].steal  - cpuv[!tog][c].steal;

	  /* idle can run backwards for a moment -- kernel "feature" */
	  if (debt[c])
	    {
	      didle[c] = (int) didle[c] + debt[c];
	      debt[c] = 0;
	    }
	  if ((int) didle[c] < 0)
	    {
	      debt[c] = (int) didle[c];
	      didle[c] = 0;
	    }

	  ratio[c] = duser[c] + dsystem[c] + didle[c] + diowait[c] + dsteal[c];
	  if (!ratio[c])
	    ratio[c] = 1, didle[c] = 1;

	  if (NULL == (cpuname = cpuv[0][c].cpuname))
	    cpuname = "n/a";

	  if (verbose)
	    printf
	     ("%s_user=%.1f%%, %s_system=%.1f%%, %s_idle=%.1f%%, "
	      "%s_iowait=%.1f%%, %s_steal=%.1f%%\n"
	      , cpuname, 100.0 * duser[c]   / ratio[c]
	      , cpuname, 100.0 * dsystem[c] / ratio[c]
	      , cpuname, 100.0 * didle[c]   / ratio[c]
	      , cpuname, 100.0 * diowait[c] / ratio[c]
	      , cpuname, 100.0 * dsteal[c]  / ratio[c]);

	  dbg ("sum (%s_*) = %.1f%%\n", cpuname, (100.0 * duser[c] / ratio[c]) +
	       (100.0 * dsystem[c] / ratio[c]) + (100.0 * didle[c]  / ratio[c]) +
	       (100.0 * diowait[c] / ratio[c]) + (100.0 * dsteal[c] / ratio[c]));
	}
    }

  for (c = 0, status = STATE_OK; c < ncpus; c++)
    {
      cpu_perc = (100.0 * (cpu_value[c]) / ratio[c]);
      currstatus = get_status (cpu_perc, my_threshold);
      if (currstatus > status)
	status = currstatus;
    }

  cpu_desc_read (cpudesc);
  char *cpu_model_str =
    cpu_model ?	xasprintf ("(%s) ",
			   cpu_desc_get_model_name (cpudesc)) : NULL;

  printf ("%s %s%s - cpu %s %.1f%% |"
	  , program_name_short, cpu_model ? cpu_model_str : ""
	  , state_text (status), cpu_progname, cpu_perc);
  for (c = 0; c < ncpus; c++)
    {
      if ((cpuname = cpuv[0][c].cpuname))
        printf (" %s_user=%.1f%% %s_system=%.1f%% %s_idle=%.1f%%"
		" %s_iowait=%.1f%% %s_steal=%.1f%%"
		, cpuname, 100.0 * duser[c]   / ratio[c]
		, cpuname, 100.0 * dsystem[c] / ratio[c]
		, cpuname, 100.0 * didle[c]   / ratio[c]
		, cpuname, 100.0 * diowait[c] / ratio[c]
		, cpuname, 100.0 * dsteal[c]  / ratio[c]);
    }
  putchar ('\n');

  cpu_desc_unref (cpudesc);
  return status;
}
Пример #2
0
void
cpu_desc_read (struct cpu_desc *cpudesc)
{
  char *line = NULL, *buf;
  FILE *fp;
  size_t len = 0;
  ssize_t chread;
  struct utsname utsbuf;

  if (cpudesc == NULL)
    return;

  if ((fp = fopen (PATH_PROC_CPUINFO,  "r")) == NULL)
    plugin_error (STATE_UNKNOWN, errno, "error opening %s", PATH_PROC_CPUINFO);

  if (uname (&utsbuf) == -1)
    plugin_error (STATE_UNKNOWN, errno, "uname() failed");
  cpudesc->arch = xstrdup (utsbuf.machine);

  cpudesc->ncpus = get_processor_number_total ();
  cpudesc->ncpuspos = get_processor_number_kernel_max ();

  cpudesc->mode = 0;
#if defined(__alpha__) || defined(__ia64__)
  cpudesc->mode |= MODE_64BIT;		/* 64bit platforms only */
#endif
  /* platforms with 64bit flag in /proc/cpuinfo, define
   * 32bit default here */
#if defined(__i386__) || defined(__x86_64__) || \
    defined(__s390x__) || defined(__s390__) || defined(__sparc_v9__)
  cpudesc->mode |= MODE_32BIT;
#endif

  while ((chread = getline (&line, &len, fp)) != -1)
    {
      if (linelookup (line, "vendor", &cpudesc->vendor));
      else if (linelookup (line, "vendor_id", &cpudesc->vendor));
      else if (linelookup (line, "family", &cpudesc->family));
      else if (linelookup (line, "cpu family", &cpudesc->family));
      else if (linelookup (line, "model", &cpudesc->model));
      else if (linelookup (line, "model name", &cpudesc->modelname)) ;
      else if (linelookup (line, "cpu MHz", &cpudesc->mhz)) ;
      else if (linelookup (line, "flags", &cpudesc->flags)) ;	/* x86 */
      else
	continue;
    }

  if (cpudesc->flags)
    {
      size_t buflen = strlen (cpudesc->flags) + 2;
      buf = xmalloc (buflen);

      snprintf (buf, buflen, " %s ", cpudesc->flags);
      if (strstr (buf, " svm "))
        cpudesc->virtflag = xstrdup ("svm");
      else if (strstr (buf, " vmx "))
        cpudesc->virtflag = xstrdup ("vmx");
      if (strstr (buf, " lm "))
        cpudesc->mode |= MODE_32BIT | MODE_64BIT;  /* x86_64 */
      if (strstr (buf, " zarch "))
        cpudesc->mode |= MODE_32BIT | MODE_64BIT;  /* s390x */
      if (strstr (buf, " sun4v ") || strstr (buf, " sun4u "))
        cpudesc->mode |= MODE_32BIT | MODE_64BIT;  /* sparc64 */
  
      free (buf);
    }

  free (line);
}