PolarDBforPostgreSQL/external/polar_monitor_preload/polar_procstat.c

168 lines
3.5 KiB
C

/*-------------------------------------------------------------------------
*
* procstat.c
*
* Copyright (c) 2021, Alibaba Group Holding Limited
*
* 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.
*
* IDENTIFICATION
* external/polar_monitor_preload/polar_procstat.c
*
*-------------------------------------------------------------------------
*/
#include <stdlib.h>
#include <string.h>
#include "polar_procstat.h"
#define MAXPATHLENGTH 80
#define MAXSTATLEN 1024
static const char * delim = " ";
static char path[MAXPATHLENGTH];
static char procbuf[MAXSTATLEN];
static char * readone(char* curstr, void *x, PROCARGTYPE argtype) ;
static int parse_proc_pid_stat(int pid, polar_proc_stat *prostat);
static int parse_proc_pid_statm(int pid, polar_proc_stat *stat);
static char * readone(char* curstr, void *x, PROCARGTYPE argtype)
{
char* token = NULL;
char* savestr = NULL;
token = strtok_r (curstr, delim, &savestr);
if(token)
{
switch (argtype)
{
case PROCINT :
*(int *)x = (int)atoi(token);
break;
case PROCNUM :
*(num *)x = (num)atoll(token);
break;
case PROCL :
*(long *)x = (long)atol(token);
break;
case PROCLL :
*(long long *)x = (long long)atoll(token);
break;
case PROCSTR :
strncpy((char *)x, token, savestr-curstr);
break;
default:
break;
}
}
return savestr;
}
/*
* POLAR:
* Parse a proc/[pid]/stat file
* if return 1 ,not find stat file
* return 0, successful!
*/
static int
parse_proc_pid_stat(int pid, polar_proc_stat *prostat)
{
char * curstr = NULL;
char tty_null[64];
FILE *input;
int i;
input = NULL;
memset(path, 0 ,sizeof(path));
sprintf(path,"/proc/%d/stat",pid);
input = fopen(path, "r");
if(!input) {
return 1;
}
if(!fread(procbuf, MAXSTATLEN, 1, input))
{
if(ferror(input))
{
fclose(input);
return 1;
}
}
curstr = readone(procbuf, tty_null, PROCSTR);
curstr = readone(curstr, tty_null, PROCSTR);
/* We don't need extra here */
for (i = 0; i < 11; i++)
curstr = readone(curstr, tty_null, PROCSTR);
curstr = readone(curstr, &prostat->utime, PROCNUM);
curstr = readone(curstr, &prostat->stime, PROCNUM);
return fclose(input);
}
/*
* POLAR:
* Parse a proc/[pid]/statm file
* if return 1 ,not find stat file
* return 0, successful!
*/
static int
parse_proc_pid_statm(int pid, polar_proc_stat *stat)
{
char * curstr = NULL;
char tty_null[64];
FILE *input;
input = NULL;
memset(path, 0 ,sizeof(path));
sprintf(path,"/proc/%d/statm",pid);
input = fopen(path, "r");
if(!input) {
return 1;
}
if(!fread(procbuf, MAXSTATLEN, 1, input))
{
if(ferror(input))
{
fclose(input);
return 1;
}
}
curstr = readone(procbuf, tty_null, PROCSTR);
curstr = readone(curstr, &stat->rss, PROCNUM);
curstr = readone(curstr, &stat->share, PROCNUM);
return fclose(input);
}
int
polar_get_proc_stat(int pid, polar_proc_stat *stat)
{
int ret = parse_proc_pid_stat(pid, stat);
if (ret)
return ret;
return parse_proc_pid_statm(pid, stat);
}