mirror of
https://github.com/apache/nuttx-apps.git
synced 2026-08-24 06:58:35 +00:00
resmonitor: add showinfo/filldisk/fillcpu/fillmem from test/
add cmake support after enable TESTING_RESMONITOR, use showinfo -i 2 can show cpuload to syslog every two seconds. Signed-off-by: buxiasen <buxiasen@xiaomi.com>
This commit is contained in:
parent
a526a4a173
commit
36be4a08ed
8 changed files with 1686 additions and 0 deletions
63
testing/resmonitor/CMakeLists.txt
Normal file
63
testing/resmonitor/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# ##############################################################################
|
||||
# apps/testing/resmonitor/CMakeLists.txt
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
|
||||
# license agreements. See the NOTICE file distributed with this work for
|
||||
# additional information regarding copyright ownership. The ASF licenses this
|
||||
# file to you under the Apache License, Version 2.0 (the "License"); you may not
|
||||
# use this file except in compliance with the License. You may obtain a copy of
|
||||
# the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations under
|
||||
# the License.
|
||||
#
|
||||
# ##############################################################################
|
||||
|
||||
if(CONFIG_TESTING_RESMONITOR)
|
||||
nuttx_add_application(
|
||||
NAME
|
||||
showinfo
|
||||
SRCS
|
||||
showinfo.c
|
||||
STACKSIZE
|
||||
${CONFIG_TESTING_RESMONITOR_STACKSIZE}
|
||||
PRIORITY
|
||||
${CONFIG_TESTING_RESMONITOR_PRIORITY})
|
||||
|
||||
if(CONFIG_TESTING_RESMONITOR_FILL)
|
||||
nuttx_add_application(
|
||||
NAME
|
||||
filldisk
|
||||
SRCS
|
||||
filldisk.c
|
||||
STACKSIZE
|
||||
${CONFIG_TESTING_RESMONITOR_STACKSIZE}
|
||||
PRIORITY
|
||||
${CONFIG_TESTING_RESMONITOR_PRIORITY})
|
||||
|
||||
nuttx_add_application(
|
||||
NAME
|
||||
fillcpu
|
||||
SRCS
|
||||
fillcpu.c
|
||||
STACKSIZE
|
||||
${CONFIG_TESTING_RESMONITOR_STACKSIZE}
|
||||
PRIORITY
|
||||
${CONFIG_TESTING_RESMONITOR_PRIORITY})
|
||||
|
||||
nuttx_add_application(
|
||||
NAME
|
||||
fillmem
|
||||
SRCS
|
||||
fillmem.c
|
||||
STACKSIZE
|
||||
${CONFIG_TESTING_RESMONITOR_STACKSIZE}
|
||||
PRIORITY
|
||||
${CONFIG_TESTING_RESMONITOR_PRIORITY})
|
||||
endif()
|
||||
endif()
|
||||
27
testing/resmonitor/Kconfig
Normal file
27
testing/resmonitor/Kconfig
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
|
||||
config TESTING_RESMONITOR
|
||||
bool "enable resource monitor [showinfo]"
|
||||
default n
|
||||
---help---
|
||||
Enable resource show with specific duration.
|
||||
Should not use with LOW_RESOURCE_TEST at the same time.
|
||||
|
||||
if TESTING_RESMONITOR
|
||||
|
||||
config TESTING_RESMONITOR_PRIORITY
|
||||
int "Task priority"
|
||||
default 100
|
||||
|
||||
config TESTING_RESMONITOR_STACKSIZE
|
||||
int "Stack size"
|
||||
default 4096
|
||||
|
||||
config TESTING_RESMONITOR_FILL
|
||||
bool "[filldisk/fillcpu/fillmem]"
|
||||
default n
|
||||
|
||||
endif
|
||||
24
testing/resmonitor/Make.defs
Normal file
24
testing/resmonitor/Make.defs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
############################################################################
|
||||
# apps/testing/resmonitor/Make.defs
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
#
|
||||
############################################################################
|
||||
|
||||
ifneq ($(CONFIG_TESTING_RESMONITOR),)
|
||||
CONFIGURED_APPS += $(APPDIR)/testing/resmonitor
|
||||
endif
|
||||
33
testing/resmonitor/Makefile
Normal file
33
testing/resmonitor/Makefile
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# apps/testing/resmonitor/Makefile
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
include $(APPDIR)/Make.defs
|
||||
|
||||
PRIORITY = $(CONFIG_TESTING_RESMONITOR_PRIORITY)
|
||||
STACKSIZE = $(CONFIG_TESTING_RESMONITOR_STACKSIZE)
|
||||
MODULE = $(CONFIG_TESTING_RESMONITOR)
|
||||
|
||||
PROGNAME += showinfo
|
||||
MAINSRC += $(CURDIR)/showinfo.c
|
||||
|
||||
ifeq ($(CONFIG_TESTING_RESMONITOR_FILL),y)
|
||||
PROGNAME += filldisk
|
||||
MAINSRC += $(CURDIR)/filldisk.c
|
||||
PROGNAME += fillcpu
|
||||
MAINSRC += $(CURDIR)/fillcpu.c
|
||||
PROGNAME += fillmem
|
||||
MAINSRC += $(CURDIR)/fillmem.c
|
||||
endif
|
||||
|
||||
include $(APPDIR)/Application.mk
|
||||
232
testing/resmonitor/fillcpu.c
Normal file
232
testing/resmonitor/fillcpu.c
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
/****************************************************************************
|
||||
* apps/testing/resmonitor/fillcpu.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define PATH "/proc"
|
||||
#define CPULOAD "cpuload"
|
||||
#define LOADAVG "loadavg"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static int go = 1;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void handler(int sig)
|
||||
{
|
||||
go = 0;
|
||||
}
|
||||
|
||||
static void show_usages(void)
|
||||
{
|
||||
syslog(LOG_WARNING,
|
||||
"Usage: CMD [-c <cpu>] [-f <filepath>] [-a]\n"
|
||||
"\t\t-c: set cpu occupation that you except, default 80\n"
|
||||
"\t\t-f: set write payload path, eg. /tmp/payload, program will "
|
||||
"write to memory if -f not set\n"
|
||||
"\t\t-a: the cpu (set by -c) is the cpu occupied by this program\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static float get_cpu(int pid)
|
||||
{
|
||||
float cpu = 0;
|
||||
char filepath[20];
|
||||
int ret;
|
||||
if (pid <= 0)
|
||||
{
|
||||
ret = snprintf(filepath, 20, "%s/%s", PATH, CPULOAD);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = snprintf(filepath, 20, "%s/%d/%s", PATH, pid, LOADAVG);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
/* syslog(LOG_ERR, "snprintf error\n"); */
|
||||
|
||||
return cpu;
|
||||
}
|
||||
|
||||
FILE *fp = fopen(filepath, "r");
|
||||
if (!fp)
|
||||
{
|
||||
return cpu;
|
||||
}
|
||||
|
||||
char buf[8];
|
||||
fgets(buf, 8, fp);
|
||||
sscanf(buf, "%f", &cpu);
|
||||
fclose(fp);
|
||||
return cpu;
|
||||
}
|
||||
|
||||
static int writefile(char *filepath, char *buffer1, char *buffer2)
|
||||
{
|
||||
if (strlen(filepath) == 0)
|
||||
{
|
||||
memset(buffer2, '*', 1024);
|
||||
memcpy(buffer1, buffer2, 1024);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int fd;
|
||||
memset(buffer1, '*', 1024);
|
||||
if ((fd = open(filepath, O_WRONLY | O_CREAT, 0700)) <= 0)
|
||||
{
|
||||
syslog(LOG_ERR, "open file error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (write(fd, buffer1, 1024) <= 0)
|
||||
{
|
||||
syslog(LOG_ERR, "write file error\n");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char buf1[1024];
|
||||
char buf2[1024];
|
||||
char filepath[40];
|
||||
struct timeval sleeptime;
|
||||
int n = 0;
|
||||
int lowcount = 0;
|
||||
int cpu = 80;
|
||||
bool ispid = false;
|
||||
int time = 10000;
|
||||
float fcpu;
|
||||
int o;
|
||||
|
||||
memset(filepath, 0, 40);
|
||||
go = 1;
|
||||
if (argc == 1)
|
||||
{
|
||||
show_usages();
|
||||
}
|
||||
|
||||
while ((o = getopt(argc, argv, "c:f:a")) != EOF)
|
||||
{
|
||||
switch (o)
|
||||
{
|
||||
case 'c':
|
||||
cpu = atoi(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
snprintf(filepath, 40, "%s", optarg);
|
||||
break;
|
||||
case 'a':
|
||||
ispid = true;
|
||||
break;
|
||||
default:
|
||||
show_usages();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
signal(SIGINT, handler);
|
||||
signal(SIGKILL, handler);
|
||||
|
||||
while (go)
|
||||
{
|
||||
if (time < 1000)
|
||||
{
|
||||
time = 1000;
|
||||
lowcount++;
|
||||
if (lowcount > 4)
|
||||
{
|
||||
lowcount = 0;
|
||||
n += 2;
|
||||
}
|
||||
}
|
||||
|
||||
else if (time > 10000)
|
||||
{
|
||||
time = 10000;
|
||||
n -= 1;
|
||||
n = (n < 0 ? 0 : n);
|
||||
}
|
||||
else
|
||||
{
|
||||
lowcount = 0;
|
||||
}
|
||||
|
||||
sleeptime.tv_sec = 0;
|
||||
sleeptime.tv_usec = time;
|
||||
select(0, NULL, NULL, NULL, &sleeptime);
|
||||
if (ispid)
|
||||
{
|
||||
fcpu = get_cpu(getpid());
|
||||
}
|
||||
else
|
||||
{
|
||||
fcpu = get_cpu(0);
|
||||
}
|
||||
|
||||
if (fcpu > cpu)
|
||||
{
|
||||
time += 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
time -= 1000;
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
if (writefile(filepath, buf1, buf2) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "program complete!\n");
|
||||
return 0;
|
||||
}
|
||||
404
testing/resmonitor/filldisk.c
Normal file
404
testing/resmonitor/filldisk.c
Normal file
|
|
@ -0,0 +1,404 @@
|
|||
/****************************************************************************
|
||||
* apps/testing/resmonitor/filldisk.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/statfs.h>
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define PATHSIZE 70
|
||||
#define FILESIZE 100
|
||||
#define FILENAME "testpayload"
|
||||
#define INTERVAL 0
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static time_t interval = INTERVAL;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static int getdiv(uintmax_t count)
|
||||
{
|
||||
int div = 1000;
|
||||
if (count > 1000)
|
||||
{
|
||||
div = 1000;
|
||||
}
|
||||
else if (count > 100)
|
||||
{
|
||||
div = 100;
|
||||
}
|
||||
else if (count > 10)
|
||||
{
|
||||
div = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
div = 1;
|
||||
}
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
static uintmax_t
|
||||
get_fillsize(char *filepath, int mode, uintmax_t remain, uintmax_t fill)
|
||||
{
|
||||
struct statfs diskinfo;
|
||||
int ret = statfs(filepath, &diskinfo);
|
||||
if (ret != 0)
|
||||
{
|
||||
syslog(LOG_ERR, "statfs fail!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uintmax_t bsize = (uintmax_t)diskinfo.f_bsize;
|
||||
uintmax_t bavail = (uintmax_t)diskinfo.f_bavail;
|
||||
uintmax_t t_size = bsize * bavail;
|
||||
uintmax_t fillsize = 0;
|
||||
if (mode == 1)
|
||||
{
|
||||
fillsize = t_size - remain;
|
||||
}
|
||||
else if (mode == 2)
|
||||
{
|
||||
fillsize = (fill < t_size) ? fill : t_size;
|
||||
}
|
||||
|
||||
return fillsize;
|
||||
}
|
||||
|
||||
static clock_t fill_disk(char *file, uintmax_t bufsize, int mode,
|
||||
uintmax_t remain, uintmax_t fill)
|
||||
{
|
||||
FILE *fp;
|
||||
clock_t start, finish;
|
||||
struct timeval sleeptime;
|
||||
int ret;
|
||||
if ((fp = fopen(file, "a+")) == NULL)
|
||||
{
|
||||
syslog(LOG_ERR, "Fail to open file!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uintmax_t fillsize = get_fillsize(file, mode, remain, fill);
|
||||
if (fillsize <= 0)
|
||||
{
|
||||
syslog(LOG_WARNING, "out of space !!\n");
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *buf = (char *)malloc((size_t)bufsize);
|
||||
if (!buf)
|
||||
{
|
||||
syslog(LOG_ERR, "malloc fail, errno %d\n", errno);
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(buf, 'a', (size_t)bufsize);
|
||||
uintmax_t count = fillsize / bufsize;
|
||||
int div = getdiv(count);
|
||||
start = clock();
|
||||
while (fillsize > bufsize)
|
||||
{
|
||||
ret = fwrite(buf, 1, bufsize, fp);
|
||||
if (ret > 0)
|
||||
{
|
||||
fillsize -= ret;
|
||||
count--;
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_ERR, "write fail \n");
|
||||
fclose(fp);
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sleeptime.tv_sec = interval / 1000000;
|
||||
sleeptime.tv_usec = interval % 1000000;
|
||||
select(0, NULL, NULL, NULL, &sleeptime);
|
||||
if (count % div == 0)
|
||||
{
|
||||
syslog(LOG_INFO, "remain %ju B\n", fillsize);
|
||||
fillsize = get_fillsize(file, mode, remain, fillsize);
|
||||
if (fillsize < 0)
|
||||
{
|
||||
syslog(LOG_WARNING, "out of space !!\n");
|
||||
fclose(fp);
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
count = fillsize / bufsize;
|
||||
div = getdiv(count);
|
||||
}
|
||||
}
|
||||
|
||||
fwrite(buf, 1, fillsize, fp);
|
||||
fflush(fp);
|
||||
finish = clock();
|
||||
syslog(LOG_INFO, "write complete !!!\n");
|
||||
fclose(fp);
|
||||
free(buf);
|
||||
return finish - start;
|
||||
}
|
||||
|
||||
static void show_usages(void)
|
||||
{
|
||||
syslog(LOG_WARNING,
|
||||
"Usage: CMD [-d <dir>] [-f <fill size>] [-r <remain size>] [-b "
|
||||
"<write buf size>] [-n <file nums>] [-i <write interval (us)>]\n"
|
||||
"\t\t-d: set dir to fill (e.g. /data)\n"
|
||||
"\t\t-f: set fill file size, can end with KkMm, (disabled if -r is "
|
||||
"set)\n"
|
||||
"\t\t-n: works only if -f is set, create n files of size -f set, "
|
||||
"default 1\n"
|
||||
"\t\t-r: set remain size, can end with KkMm\n"
|
||||
"\t\t-b: set write buf size, can end with kKMm, default is f_bsize\n"
|
||||
"\t\t-i: set write intervals (us), default 0 us, set only if the "
|
||||
"program killed by wdt\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void double2str(double f, char *s, int len)
|
||||
{
|
||||
int ret = snprintf(s, len, "%.2lf", f);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "double to str fail, ret %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
static uintmax_t bytes(char *s)
|
||||
{
|
||||
uintmax_t n;
|
||||
if (sscanf(s, "%ju", &n) < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((s[strlen(s) - 1] == 'k') || (s[strlen(s) - 1] == 'K'))
|
||||
{
|
||||
n *= 1024;
|
||||
}
|
||||
|
||||
if ((s[strlen(s) - 1] == 'm') || (s[strlen(s) - 1] == 'M'))
|
||||
{
|
||||
n *= (1024 * 1024);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static void print_disk_info(struct statfs *diskinfo)
|
||||
{
|
||||
syslog(LOG_INFO, "\tfs block size : %zu\n", diskinfo->f_bsize);
|
||||
syslog(LOG_INFO,
|
||||
"\tfs block nums : %" PRIu64 "\n",
|
||||
(uint64_t)diskinfo->f_blocks);
|
||||
syslog(LOG_INFO,
|
||||
"\tfs free blocks : %" PRIu64 "\n",
|
||||
(uint64_t)diskinfo->f_bfree);
|
||||
syslog(LOG_INFO,
|
||||
"\tfs free blocks available : %" PRIu64 "\n",
|
||||
(uint64_t)diskinfo->f_bavail);
|
||||
syslog(LOG_INFO,
|
||||
"\tfs total file nodes : %" PRIu64 "\n",
|
||||
(uint64_t)diskinfo->f_files);
|
||||
syslog(LOG_INFO,
|
||||
"\tfs free file nodes : %" PRIu64 "\n",
|
||||
(uint64_t)diskinfo->f_ffree);
|
||||
}
|
||||
|
||||
int main(int argc, FAR char *argv[])
|
||||
{
|
||||
if (argc == 1)
|
||||
{
|
||||
show_usages();
|
||||
return -1;
|
||||
}
|
||||
|
||||
char filepath[PATHSIZE];
|
||||
char sduration_t[15];
|
||||
char sduration_w[15];
|
||||
char sspeed_t[15];
|
||||
char sspeed_w[15];
|
||||
uintmax_t fill = 0;
|
||||
uintmax_t remain = 0;
|
||||
uintmax_t bufsize = 0;
|
||||
int nf = 1;
|
||||
int mode = 0;
|
||||
clock_t write_t = 0;
|
||||
struct statfs diskinfo_old;
|
||||
struct statfs diskinfo_new;
|
||||
uintmax_t fillsize;
|
||||
double duration_t;
|
||||
double speed_t;
|
||||
double duration_w;
|
||||
double speed_w;
|
||||
clock_t start;
|
||||
clock_t finish;
|
||||
clock_t tmp;
|
||||
int ret;
|
||||
int o;
|
||||
|
||||
interval = INTERVAL;
|
||||
memset(filepath, 0, PATHSIZE);
|
||||
while ((o = getopt(argc, argv, "d:f:r:b:i:n:")) != EOF)
|
||||
{
|
||||
switch (o)
|
||||
{
|
||||
case 'd':
|
||||
snprintf(filepath, PATHSIZE, "%s", optarg);
|
||||
break;
|
||||
case 'f':
|
||||
fill = bytes(optarg);
|
||||
if (mode != 1)
|
||||
{
|
||||
mode = 2;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'r':
|
||||
remain = bytes(optarg);
|
||||
mode = 1;
|
||||
break;
|
||||
case 'i':
|
||||
interval = (time_t)bytes(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
bufsize = bytes(optarg);
|
||||
break;
|
||||
case 'n':
|
||||
nf = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
show_usages();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen(filepath) == 0)
|
||||
{
|
||||
syslog(LOG_ERR, "please set dir \n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mode == 0)
|
||||
{
|
||||
syslog(LOG_ERR, "please set -f or -r \n");
|
||||
return -1;
|
||||
}
|
||||
else if (mode != 2)
|
||||
{
|
||||
nf = 1;
|
||||
}
|
||||
|
||||
ret = statfs(filepath, &diskinfo_old);
|
||||
if (ret != 0)
|
||||
{
|
||||
syslog(LOG_ERR, "statfs fail!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bufsize == 0)
|
||||
{
|
||||
bufsize = diskinfo_old.f_bsize;
|
||||
}
|
||||
|
||||
fillsize = get_fillsize(filepath, mode, remain, fill) * nf;
|
||||
syslog(LOG_INFO, "outputfilepath: %s\n", filepath);
|
||||
start = clock();
|
||||
for (int i = 1; i <= nf; i++)
|
||||
{
|
||||
syslog(LOG_INFO, "create file %d, total %d\n", i, nf);
|
||||
char file[FILESIZE];
|
||||
ret = snprintf(file, FILESIZE, "%s/%s%d", filepath, FILENAME, i);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "snprintf err, ret %d\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((tmp = fill_disk(file, bufsize, mode, remain, fill)) > 0)
|
||||
{
|
||||
write_t += tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_ERR, "fill disk error\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
finish = clock();
|
||||
ret = statfs(filepath, &diskinfo_new);
|
||||
if (ret != 0)
|
||||
{
|
||||
syslog(LOG_ERR, "statfs fail!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "***diskinfo before filldisk***\n");
|
||||
print_disk_info(&diskinfo_old);
|
||||
|
||||
syslog(LOG_INFO, "***diskinfo after filldisk***\n");
|
||||
print_disk_info(&diskinfo_new);
|
||||
duration_t = (double)(finish - start) / CLOCKS_PER_SEC;
|
||||
speed_t = fillsize / 1024.0 / duration_t;
|
||||
duration_w = (double)(write_t) / CLOCKS_PER_SEC;
|
||||
speed_w = fillsize / 1024.0 / duration_w;
|
||||
double2str(speed_t, sspeed_t, 15);
|
||||
double2str(speed_w, sspeed_w, 15);
|
||||
double2str(duration_t, sduration_t, 15);
|
||||
double2str(duration_w, sduration_w, 15);
|
||||
syslog(LOG_INFO, "fill buf size: %ju\n", bufsize);
|
||||
syslog(LOG_INFO, "total fill size: %ju\n", fillsize);
|
||||
syslog(LOG_INFO,
|
||||
"write speed (include open and close) %s KB/s, duration %s s\n",
|
||||
sspeed_t,
|
||||
sduration_t);
|
||||
syslog(LOG_INFO,
|
||||
"write speed (only write) %s KB/s, duration %s s\n",
|
||||
sspeed_w,
|
||||
sduration_w);
|
||||
return 0;
|
||||
}
|
||||
255
testing/resmonitor/fillmem.c
Normal file
255
testing/resmonitor/fillmem.c
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
/****************************************************************************
|
||||
* apps/testing/resmonitor/fillmem.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <malloc.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define PAYLOADSIZE 100
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static int go = 1;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void handler(int sig)
|
||||
{
|
||||
go = 0;
|
||||
}
|
||||
|
||||
static void show_usages(void)
|
||||
{
|
||||
syslog(LOG_WARNING,
|
||||
"Usage: CMD [-f <fill size>] [-r <remain size>]\n"
|
||||
"\t\t-f: set fill mem size, can end with KkMm, (disabled if -r "
|
||||
"is set)\n"
|
||||
"\t\t-r: set remain size, can end with KkMm\n"
|
||||
"\t\t-p: set percentage occupancy\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static uintmax_t bytes(char *s)
|
||||
{
|
||||
uintmax_t n;
|
||||
if (sscanf(s, "%ju", &n) < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((s[strlen(s) - 1] == 'k') || (s[strlen(s) - 1] == 'K'))
|
||||
{
|
||||
n *= 1024;
|
||||
}
|
||||
|
||||
if ((s[strlen(s) - 1] == 'm') || (s[strlen(s) - 1] == 'M'))
|
||||
{
|
||||
n *= (1024 * 1024);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct mallinfo g_alloc_info;
|
||||
size_t fill_size = 0;
|
||||
size_t remain_size = 0;
|
||||
size_t free_mem = 0;
|
||||
size_t largest_mem = 0;
|
||||
size_t total_mem = 0;
|
||||
size_t used_mem = 0;
|
||||
float fill_percentage = 0;
|
||||
char *payloads[PAYLOADSIZE];
|
||||
int idx = 0;
|
||||
go = 1;
|
||||
struct timeval sleeptime;
|
||||
memset(payloads, 0, sizeof(payloads));
|
||||
int mode = 0;
|
||||
if (argc == 1)
|
||||
{
|
||||
show_usages();
|
||||
}
|
||||
|
||||
int o;
|
||||
while ((o = getopt(argc, argv, "r:f:p:")) != EOF)
|
||||
{
|
||||
switch (o)
|
||||
{
|
||||
case 'r':
|
||||
remain_size = (size_t)bytes(optarg);
|
||||
mode = 1;
|
||||
break;
|
||||
case 'f':
|
||||
fill_size = (size_t)bytes(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
fill_percentage = atof(optarg);
|
||||
mode = 2;
|
||||
break;
|
||||
default:
|
||||
show_usages();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_alloc_info = mallinfo();
|
||||
total_mem = (size_t)g_alloc_info.arena;
|
||||
free_mem = (size_t)g_alloc_info.fordblks;
|
||||
largest_mem = (size_t)g_alloc_info.mxordblk;
|
||||
used_mem = (size_t)g_alloc_info.uordblks;
|
||||
if (mode == 2)
|
||||
{
|
||||
size_t per_fill = (size_t)total_mem * fill_percentage;
|
||||
syslog(LOG_INFO, "per fill is %zu\n", per_fill);
|
||||
fill_size = per_fill - used_mem;
|
||||
if (fill_size < 0)
|
||||
{
|
||||
syslog(LOG_WARNING,
|
||||
"memory has used %zu, has exceed %f\n",
|
||||
used_mem,
|
||||
fill_percentage);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mode = 0;
|
||||
}
|
||||
|
||||
if (remain_size != 0 || mode == 1)
|
||||
{
|
||||
if (remain_size > free_mem)
|
||||
{
|
||||
syslog(LOG_INFO,
|
||||
"remain is greater than free, remain %zu, free %zu\n",
|
||||
remain_size,
|
||||
free_mem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fill_size = free_mem - remain_size;
|
||||
}
|
||||
|
||||
if (fill_size > free_mem)
|
||||
{
|
||||
syslog(LOG_INFO,
|
||||
"no enough mem, fill %zu, free %zu\n",
|
||||
fill_size,
|
||||
free_mem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
syslog(LOG_INFO,
|
||||
"fill size %zu, free %zu, largest %zu\n",
|
||||
fill_size,
|
||||
free_mem,
|
||||
largest_mem);
|
||||
if (fill_size <= largest_mem)
|
||||
{
|
||||
payloads[0] = malloc(fill_size - 100);
|
||||
if (payloads[0] == NULL)
|
||||
{
|
||||
syslog(LOG_ERR, "malloc fail, errno %d\n", errno);
|
||||
goto END;
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "malloc size %zu\n", fill_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((fill_size > largest_mem) && (idx < PAYLOADSIZE - 1))
|
||||
{
|
||||
if (largest_mem <= 150)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
payloads[idx] = malloc(largest_mem - 100);
|
||||
if (payloads[idx] == NULL)
|
||||
{
|
||||
syslog(LOG_ERR, "malloc fail, errno %d\n", errno);
|
||||
goto END;
|
||||
}
|
||||
|
||||
fill_size -= largest_mem;
|
||||
syslog(LOG_INFO, "idx: %d, malloc size %zu\n", idx, largest_mem);
|
||||
g_alloc_info = mallinfo();
|
||||
largest_mem = (size_t)g_alloc_info.mxordblk;
|
||||
idx++;
|
||||
}
|
||||
|
||||
if (largest_mem > 100)
|
||||
{
|
||||
if (largest_mem - fill_size <= 100)
|
||||
{
|
||||
fill_size = largest_mem - 100;
|
||||
}
|
||||
|
||||
payloads[idx] = malloc(fill_size);
|
||||
if (payloads[idx] == NULL)
|
||||
{
|
||||
syslog(LOG_ERR, "malloc fail, errno %d\n", errno);
|
||||
goto END;
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "idx: %d, malloc size %zu\n", idx, fill_size);
|
||||
}
|
||||
}
|
||||
|
||||
signal(SIGINT, handler);
|
||||
signal(SIGKILL, handler);
|
||||
while (go)
|
||||
{
|
||||
sleeptime.tv_sec = 600;
|
||||
sleeptime.tv_usec = 0;
|
||||
select(0, NULL, NULL, NULL, &sleeptime);
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "program complete!\n");
|
||||
END:
|
||||
for (int i = 0; i < PAYLOADSIZE; i++)
|
||||
{
|
||||
if (payloads[i] != NULL)
|
||||
{
|
||||
free(payloads[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
648
testing/resmonitor/showinfo.c
Normal file
648
testing/resmonitor/showinfo.c
Normal file
|
|
@ -0,0 +1,648 @@
|
|||
/****************************************************************************
|
||||
* apps/testing/resmonitor/showinfo.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <malloc.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/statfs.h>
|
||||
#include <sys/time.h>
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define PATH "/proc"
|
||||
#define CPULOAD "cpuload"
|
||||
#define HEAP "heap"
|
||||
#define STACK "stack"
|
||||
#define LOADAVG "loadavg"
|
||||
#define GROUP "group/status"
|
||||
#define FILELEN 100
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
struct t_info
|
||||
{
|
||||
unsigned long mem_total;
|
||||
unsigned long mem_used;
|
||||
unsigned long mem_maxused;
|
||||
unsigned long mem_free;
|
||||
unsigned long mem_largest;
|
||||
unsigned long mem_nused;
|
||||
unsigned long mem_nfree;
|
||||
char total_cpu[8];
|
||||
};
|
||||
|
||||
struct p_info
|
||||
{
|
||||
unsigned long stack_used;
|
||||
unsigned long heap_used;
|
||||
char cpu[8];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static int go = 1;
|
||||
static int p_head = 1;
|
||||
static int d_head = 1;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void handler(int sig)
|
||||
{
|
||||
go = 0;
|
||||
}
|
||||
|
||||
static void show_usages(void)
|
||||
{
|
||||
syslog(LOG_WARNING,
|
||||
"Usage: CMD [-i <interval>] [-p <pid>] [-a] [-d <dir>] [-l "
|
||||
"<logpath>] [-k <logpath>]\n"
|
||||
"\t\t-i: set refresh interval (s), default 1s\n"
|
||||
"\t\t-p: set pid to monitor, show stack, head and cpu used by pid\n"
|
||||
"\t\t-a: work only if -p is set, show stack, head and cpu used by "
|
||||
"pid group\n"
|
||||
"\t\t-d: print the diskinfo of the dir\n"
|
||||
"\t\t-l: the memory and cpu info output to logpath\n"
|
||||
"\t\t-k: the diskinfo output to logpath\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void get_cpu(int pid, char *buf)
|
||||
{
|
||||
char filepath[FILELEN];
|
||||
int ret;
|
||||
if (pid <= 0)
|
||||
{
|
||||
ret = snprintf(filepath, FILELEN, "%s/%s", PATH, CPULOAD);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = snprintf(filepath, FILELEN, "%s/%d/%s", PATH, pid, LOADAVG);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
/* syslog(LOG_ERR, "snprintf error\n"); */
|
||||
|
||||
snprintf(buf, 8, "%.1f%%", 0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *fp = fopen(filepath, "r");
|
||||
if (!fp)
|
||||
{
|
||||
snprintf(buf, 8, "%.1f%%", 0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
fgets(buf, 8, fp);
|
||||
|
||||
/* sscanf(buf, "%f", &cpu); */
|
||||
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
static void add_cpu(char *a, char *b, char *buf)
|
||||
{
|
||||
if (a == NULL || b == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float fa = 0;
|
||||
float fb = 0;
|
||||
sscanf(a, "%f", &fa);
|
||||
sscanf(b, "%f", &fb);
|
||||
float sum = fa + fb;
|
||||
int ret = snprintf(buf, 8, "%.1f%%", sum);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "add_cpu error\n");
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long get_heap(int pid)
|
||||
{
|
||||
unsigned long heap = 0;
|
||||
char filepath[FILELEN];
|
||||
int ret = snprintf(filepath, FILELEN, "%s/%d/%s", PATH, pid, HEAP);
|
||||
if (ret < 0)
|
||||
{
|
||||
return heap;
|
||||
}
|
||||
|
||||
FILE *fp = fopen(filepath, "r");
|
||||
if (!fp)
|
||||
{
|
||||
return heap;
|
||||
}
|
||||
|
||||
char buf[25];
|
||||
while (fgets(buf, 25, fp) != NULL)
|
||||
{
|
||||
if (strstr(buf, "AllocSize"))
|
||||
{
|
||||
int idx = strcspn(buf, "0123456789");
|
||||
heap = strtoul(&buf[idx], NULL, 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return heap;
|
||||
}
|
||||
|
||||
static unsigned long get_stack(int pid)
|
||||
{
|
||||
unsigned long stack = 0;
|
||||
char filepath[FILELEN];
|
||||
int ret = snprintf(filepath, FILELEN, "%s/%d/%s", PATH, pid, STACK);
|
||||
if (ret < 0)
|
||||
{
|
||||
return stack;
|
||||
}
|
||||
|
||||
FILE *fp = fopen(filepath, "r");
|
||||
if (!fp)
|
||||
{
|
||||
return stack;
|
||||
}
|
||||
|
||||
char buf[25];
|
||||
while (fgets(buf, 25, fp) != NULL)
|
||||
{
|
||||
if (strstr(buf, "StackUsed"))
|
||||
{
|
||||
int idx = strcspn(buf, "0123456789");
|
||||
stack = strtoul(&buf[idx], NULL, 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return stack;
|
||||
}
|
||||
|
||||
static int get_total_info(struct t_info *t_info)
|
||||
{
|
||||
memset(t_info, 0, sizeof(struct t_info));
|
||||
struct mallinfo g_alloc_info = mallinfo();
|
||||
t_info->mem_total = g_alloc_info.arena;
|
||||
t_info->mem_used = g_alloc_info.uordblks;
|
||||
t_info->mem_free = g_alloc_info.fordblks;
|
||||
t_info->mem_largest = g_alloc_info.mxordblk;
|
||||
t_info->mem_nused = g_alloc_info.aordblks;
|
||||
t_info->mem_nfree = g_alloc_info.ordblks;
|
||||
t_info->mem_maxused = g_alloc_info.usmblks;
|
||||
get_cpu(0, t_info->total_cpu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_pid_info(struct p_info *p_info, int pid, bool all)
|
||||
{
|
||||
memset(p_info, 0, sizeof(struct p_info));
|
||||
if (!all)
|
||||
{
|
||||
get_cpu(pid, p_info->cpu);
|
||||
p_info->heap_used = get_heap(pid);
|
||||
p_info->stack_used = get_stack(pid);
|
||||
}
|
||||
else
|
||||
{
|
||||
char filepath[FILELEN];
|
||||
int ret = snprintf(filepath, FILELEN, "%s/%d/%s", PATH, pid, GROUP);
|
||||
if (ret < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
FILE *fp = fopen(filepath, "r");
|
||||
if (!fp)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
char buf[100];
|
||||
while (fgets(buf, 100, fp) != NULL)
|
||||
{
|
||||
if (strstr(buf, "Member IDs"))
|
||||
{
|
||||
int idx = strcspn(buf, ":");
|
||||
char *p = strtok(&buf[idx], " ");
|
||||
while ((p = strtok(NULL, " ")) != NULL)
|
||||
{
|
||||
int gpid = strtoul(p, NULL, 10);
|
||||
char gcpu[8] = "0.0%%";
|
||||
if (gpid > 0)
|
||||
{
|
||||
get_cpu(gpid, gcpu);
|
||||
}
|
||||
|
||||
add_cpu(p_info->cpu, gcpu, p_info->cpu);
|
||||
p_info->heap_used += get_heap(gpid);
|
||||
p_info->stack_used += get_stack(gpid);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
print_result(struct t_info *t_info, struct p_info *p_info, char *logpath)
|
||||
{
|
||||
if (strlen(logpath) != 0)
|
||||
{
|
||||
time_t rawtime = 0;
|
||||
struct tm info;
|
||||
char date[30];
|
||||
time(&rawtime);
|
||||
localtime_r(&rawtime, &info);
|
||||
strftime(date, 30, "[%Y-%m-%d %H:%M:%S] ", &info);
|
||||
FILE *f;
|
||||
if ((f = fopen(logpath, "a+")) != NULL)
|
||||
{
|
||||
if (p_head == 1)
|
||||
{
|
||||
p_head = 0;
|
||||
if (p_info == NULL)
|
||||
{
|
||||
fprintf(f,
|
||||
"%22s%13s%11s%11s%11s%11s%7s%7s%7s\n",
|
||||
"",
|
||||
"total",
|
||||
"used",
|
||||
"free",
|
||||
"maxused",
|
||||
"largest",
|
||||
"nused",
|
||||
"nfree",
|
||||
"cpu");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(f,
|
||||
"%22s%13s%11s%11s%11s%11s%7s%7s%7s%7s%11s%7s\n",
|
||||
"",
|
||||
"total",
|
||||
"used",
|
||||
"free",
|
||||
"maxused",
|
||||
"largest",
|
||||
"nused",
|
||||
"nfree",
|
||||
"cpu",
|
||||
"pstack",
|
||||
"pheap",
|
||||
"pcpu");
|
||||
}
|
||||
}
|
||||
|
||||
if (p_info == NULL)
|
||||
{
|
||||
fprintf(f,
|
||||
"%-22s%13lu%11lu%11lu%11lu%11lu%7lu%7lu%7s\n",
|
||||
date,
|
||||
t_info->mem_total,
|
||||
t_info->mem_used,
|
||||
t_info->mem_free,
|
||||
t_info->mem_maxused,
|
||||
t_info->mem_largest,
|
||||
t_info->mem_nused,
|
||||
t_info->mem_nfree,
|
||||
t_info->total_cpu);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(
|
||||
f,
|
||||
"%-22s%13lu%11lu%11lu%11lu%11lu%7lu%7lu%7s%7lu%11lu%7s\n",
|
||||
date,
|
||||
t_info->mem_total,
|
||||
t_info->mem_used,
|
||||
t_info->mem_free,
|
||||
t_info->mem_maxused,
|
||||
t_info->mem_largest,
|
||||
t_info->mem_nused,
|
||||
t_info->mem_nfree,
|
||||
t_info->total_cpu,
|
||||
p_info->stack_used,
|
||||
p_info->heap_used,
|
||||
p_info->cpu);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_ERR, "fopen logpath %s error \n", logpath);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_info == NULL)
|
||||
{
|
||||
syslog(LOG_INFO,
|
||||
"%11s%11s%11s%11s%11s%7s%7s%7s\n",
|
||||
"total",
|
||||
"used",
|
||||
"free",
|
||||
"maxused",
|
||||
"largest",
|
||||
"nused",
|
||||
"nfree",
|
||||
"cpu");
|
||||
syslog(LOG_INFO,
|
||||
"%11lu%11lu%11lu%11lu%11lu%7lu%7lu%7s\n\n",
|
||||
t_info->mem_total,
|
||||
t_info->mem_used,
|
||||
t_info->mem_free,
|
||||
t_info->mem_maxused,
|
||||
t_info->mem_largest,
|
||||
t_info->mem_nused,
|
||||
t_info->mem_nfree,
|
||||
t_info->total_cpu);
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_INFO,
|
||||
"%11s%11s%11s%11s%11s%7s%7s%7s%7s%11s%7s\n",
|
||||
"total",
|
||||
"used",
|
||||
"free",
|
||||
"maxused",
|
||||
"largest",
|
||||
"nused",
|
||||
"nfree",
|
||||
"cpu",
|
||||
"pstack",
|
||||
"pheap",
|
||||
"pcpu");
|
||||
syslog(LOG_INFO,
|
||||
"%11lu%11lu%11lu%11lu%11lu%7lu%7lu%7s%7lu%11lu%7s\n\n",
|
||||
t_info->mem_total,
|
||||
t_info->mem_used,
|
||||
t_info->mem_free,
|
||||
t_info->mem_maxused,
|
||||
t_info->mem_largest,
|
||||
t_info->mem_nused,
|
||||
t_info->mem_nfree,
|
||||
t_info->total_cpu,
|
||||
p_info->stack_used,
|
||||
p_info->heap_used,
|
||||
p_info->cpu);
|
||||
}
|
||||
}
|
||||
|
||||
static void transfer(uintmax_t value, char *res, int len)
|
||||
{
|
||||
memset(res, 0, len);
|
||||
if (value > 1024 * 1024)
|
||||
{
|
||||
int ret = snprintf(res, len, "%ju", value / 1024 / 1024);
|
||||
if (ret < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
strcat(res, "M");
|
||||
}
|
||||
else if (value > 1024)
|
||||
{
|
||||
int ret = snprintf(res, len, "%ju", value / 1024);
|
||||
if (ret < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
strcat(res, "K");
|
||||
}
|
||||
else
|
||||
{
|
||||
int ret = snprintf(res, len, "%ju", value);
|
||||
if (ret < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
strcat(res, "B");
|
||||
}
|
||||
}
|
||||
|
||||
static void print_diskinfo(char *path, char *logpath)
|
||||
{
|
||||
struct statfs diskinfo;
|
||||
int ret = statfs(path, &diskinfo);
|
||||
if (ret != 0)
|
||||
{
|
||||
syslog(LOG_ERR, "statfs fail!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
char c_tsize[20];
|
||||
char c_asize[20];
|
||||
char c_bsize[20];
|
||||
char c_fsize[20];
|
||||
uintmax_t bsize = (uintmax_t)diskinfo.f_bsize;
|
||||
uintmax_t bavail = (uintmax_t)diskinfo.f_bavail;
|
||||
uintmax_t blocks = (uintmax_t)diskinfo.f_blocks;
|
||||
uintmax_t bfree = (uintmax_t)diskinfo.f_bfree;
|
||||
transfer(bsize * blocks, c_tsize, 20);
|
||||
transfer(bsize * bavail, c_asize, 20);
|
||||
transfer(bsize * bfree, c_fsize, 20);
|
||||
transfer(bsize, c_bsize, 20);
|
||||
if (strlen(logpath) != 0)
|
||||
{
|
||||
time_t rawtime = 0;
|
||||
struct tm info;
|
||||
char date[30];
|
||||
time(&rawtime);
|
||||
localtime_r(&rawtime, &info);
|
||||
strftime(date, 30, "[%Y-%m-%d %H:%M:%S] ", &info);
|
||||
FILE *f;
|
||||
if ((f = fopen(logpath, "a+")) != NULL)
|
||||
{
|
||||
if (d_head == 1)
|
||||
{
|
||||
d_head = 0;
|
||||
fprintf(f,
|
||||
"%22s%11s%11s%11s%11s%11s\n",
|
||||
"",
|
||||
"dir",
|
||||
"total size",
|
||||
"free size",
|
||||
"avail size",
|
||||
"block size");
|
||||
}
|
||||
|
||||
fprintf(f,
|
||||
"%-22s%11s%11s%11s%11s%11s\n",
|
||||
date,
|
||||
path,
|
||||
c_tsize,
|
||||
c_fsize,
|
||||
c_asize,
|
||||
c_bsize);
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_ERR, "fopen logpath %s error \n", logpath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
syslog(LOG_INFO,
|
||||
"%11s%11s%11s%11s%11s\n",
|
||||
"dir",
|
||||
"total size",
|
||||
"free size",
|
||||
"avail size",
|
||||
"block size");
|
||||
syslog(LOG_INFO,
|
||||
"%11s%11s%11s%11s%11s\n\n",
|
||||
path,
|
||||
c_tsize,
|
||||
c_fsize,
|
||||
c_asize,
|
||||
c_bsize);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc == 1)
|
||||
{
|
||||
show_usages();
|
||||
}
|
||||
|
||||
char filepath[FILELEN];
|
||||
char logpath_l[FILELEN];
|
||||
char logpath_k[FILELEN];
|
||||
struct timeval sleeptime;
|
||||
struct t_info total_info;
|
||||
struct p_info pid_info;
|
||||
int interval = 1;
|
||||
int pid = -1;
|
||||
bool all = false;
|
||||
int ret;
|
||||
int o;
|
||||
|
||||
memset(filepath, 0, FILELEN);
|
||||
memset(logpath_l, 0, FILELEN);
|
||||
memset(logpath_k, 0, FILELEN);
|
||||
go = 1;
|
||||
p_head = 1;
|
||||
d_head = 1;
|
||||
while ((o = getopt(argc, argv, "i:p:ad:l:k:")) != EOF)
|
||||
{
|
||||
switch (o)
|
||||
{
|
||||
case 'i':
|
||||
interval = atoi(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
pid = atoi(optarg);
|
||||
break;
|
||||
case 'a':
|
||||
all = true;
|
||||
break;
|
||||
case 'd':
|
||||
snprintf(filepath, FILELEN, "%s", optarg);
|
||||
break;
|
||||
case 'l':
|
||||
snprintf(logpath_l, FILELEN, "%s", optarg);
|
||||
break;
|
||||
case 'k':
|
||||
snprintf(logpath_k, FILELEN, "%s", optarg);
|
||||
break;
|
||||
default:
|
||||
show_usages();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
signal(SIGINT, handler);
|
||||
signal(SIGKILL, handler);
|
||||
while (go)
|
||||
{
|
||||
ret = get_total_info(&total_info);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "get total info fail\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (pid > 0)
|
||||
{
|
||||
ret = get_pid_info(&pid_info, pid, all);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "get pid info fail\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (all || pid > 0)
|
||||
{
|
||||
print_result(&total_info, &pid_info, logpath_l);
|
||||
}
|
||||
else
|
||||
{
|
||||
print_result(&total_info, NULL, logpath_l);
|
||||
}
|
||||
|
||||
if (strlen(filepath) != 0)
|
||||
{
|
||||
print_diskinfo(filepath, logpath_k);
|
||||
}
|
||||
|
||||
sleeptime.tv_sec = interval;
|
||||
sleeptime.tv_usec = 0;
|
||||
select(0, NULL, NULL, NULL, &sleeptime);
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "program complete!\n");
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue