mirror of
https://github.com/lxsang/sysmond.git
synced 2024-12-25 18:58:20 +01:00
add unix domain socket support
This commit is contained in:
parent
dc4f5e252d
commit
7850c941c7
541
sysmon.c
541
sysmon.c
@ -14,59 +14,64 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
#include "ini.h"
|
#include "ini.h"
|
||||||
|
#ifndef PREFIX
|
||||||
|
#define PREFIX
|
||||||
|
#endif
|
||||||
#define DEFAULT_CONF_FILE (PREFIX "/etc/sysmond.conf")
|
#define DEFAULT_CONF_FILE (PREFIX "/etc/sysmond.conf")
|
||||||
#define MODULE_NAME "sysmon"
|
#define MODULE_NAME "sysmon"
|
||||||
// #define DEFAULT_INPUT "/sys/class/hwmon/hwmon2/device/in3_input"
|
|
||||||
#define NET_INF_STAT_PT "/sys/class/net/%s/statistics/%s"
|
#define NET_INF_STAT_PT "/sys/class/net/%s/statistics/%s"
|
||||||
|
|
||||||
#define LOG_INIT(m) do { \
|
#define LOG_INIT(m) \
|
||||||
setlogmask (LOG_UPTO (LOG_NOTICE)); \
|
do \
|
||||||
openlog ((m), LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER); \
|
{ \
|
||||||
} while(0)
|
setlogmask(LOG_UPTO(LOG_NOTICE)); \
|
||||||
|
openlog((m), LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define M_LOG(m, a, ...) syslog((LOG_NOTICE), m "_log@[%s: %d]: " a "\n", __FILE__, \
|
||||||
|
__LINE__, ##__VA_ARGS__)
|
||||||
|
|
||||||
#define M_LOG(m, a,...) syslog ((LOG_NOTICE),m "_log@[%s: %d]: " a "\n", __FILE__, \
|
#define M_ERROR(m, a, ...) syslog((LOG_ERR), m "_error@[%s: %d]: " a "\n", __FILE__, \
|
||||||
__LINE__, ##__VA_ARGS__)
|
__LINE__, ##__VA_ARGS__)
|
||||||
|
|
||||||
#define M_ERROR(m, a,...) syslog ((LOG_ERR),m "_error@[%s: %d]: " a "\n", __FILE__, \
|
#define JSON_FMT "{" \
|
||||||
__LINE__, ##__VA_ARGS__)
|
"\"stamp_sec\": %lu," \
|
||||||
|
"\"stamp_usec\": %lu," \
|
||||||
#define JSON_FMT "{" \
|
"\"battery\": %.3f," \
|
||||||
"\"stamp_sec\": %lu," \
|
"\"battery_percent\": %.3f," \
|
||||||
"\"stamp_usec\": %lu," \
|
"\"battery_max_voltage\": %d," \
|
||||||
"\"battery\": %.3f," \
|
"\"battery_min_voltage\": %d," \
|
||||||
"\"battery_percent\": %.3f," \
|
"\"cpu_temp\": %d," \
|
||||||
"\"battery_max_voltage\": %d," \
|
"\"gpu_temp\": %d," \
|
||||||
"\"battery_min_voltage\": %d," \
|
"\"cpu_usages\":[%s]," \
|
||||||
"\"cpu_temp\": %d," \
|
"\"mem_total\": %lu," \
|
||||||
"\"gpu_temp\": %d," \
|
"\"mem_free\": %lu," \
|
||||||
"\"cpu_usages\":[%s]," \
|
"\"mem_used\": %lu," \
|
||||||
"\"mem_total\": %lu," \
|
"\"mem_buff_cache\": %lu," \
|
||||||
"\"mem_free\": %lu," \
|
"\"mem_available\": %lu," \
|
||||||
"\"mem_used\": %lu," \
|
"\"mem_swap_total\": %lu," \
|
||||||
"\"mem_buff_cache\": %lu," \
|
"\"mem_swap_free\": %lu," \
|
||||||
"\"mem_available\": %lu," \
|
"\"disk_total\": %lu," \
|
||||||
"\"mem_swap_total\": %lu," \
|
"\"disk_free\": %lu," \
|
||||||
"\"mem_swap_free\": %lu," \
|
"\"net\":[%s]" \
|
||||||
"\"disk_total\": %lu," \
|
"}"
|
||||||
"\"disk_free\": %lu," \
|
|
||||||
"\"net\":[%s]" \
|
|
||||||
"}"
|
|
||||||
|
|
||||||
#define JSON_NET_FMT "{" \
|
#define JSON_NET_FMT "{" \
|
||||||
"\"name\":\"%s\"," \
|
"\"name\":\"%s\"," \
|
||||||
"\"rx\": %lu," \
|
"\"rx\": %lu," \
|
||||||
"\"tx\": %lu," \
|
"\"tx\": %lu," \
|
||||||
"\"rx_rate\": %.3f," \
|
"\"rx_rate\": %.3f," \
|
||||||
"\"tx_rate\": %.3f" \
|
"\"tx_rate\": %.3f" \
|
||||||
"},"
|
"},"
|
||||||
|
|
||||||
#define MAX_BUF 256
|
#define MAX_BUF 256
|
||||||
#define EQU(a,b) (strncmp(a,b,MAX_BUF) == 0)
|
#define EQU(a, b) (strncmp(a, b, MAX_BUF) == 0)
|
||||||
#define MAX_NETWORK_INF 8
|
#define MAX_NETWORK_INF 8
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char bat_in[MAX_BUF];
|
char bat_in[MAX_BUF];
|
||||||
@ -86,7 +91,8 @@ typedef struct
|
|||||||
uint16_t gpu;
|
uint16_t gpu;
|
||||||
} sys_temp_t;
|
} sys_temp_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
char name[32];
|
char name[32];
|
||||||
unsigned long tx;
|
unsigned long tx;
|
||||||
unsigned long rx;
|
unsigned long rx;
|
||||||
@ -94,7 +100,8 @@ typedef struct {
|
|||||||
float tx_rate;
|
float tx_rate;
|
||||||
} sys_net_inf_t;
|
} sys_net_inf_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
uint8_t n_intf;
|
uint8_t n_intf;
|
||||||
/*Monitor up to 8 interfaces*/
|
/*Monitor up to 8 interfaces*/
|
||||||
sys_net_inf_t interfaces[MAX_NETWORK_INF];
|
sys_net_inf_t interfaces[MAX_NETWORK_INF];
|
||||||
@ -107,13 +114,14 @@ typedef struct
|
|||||||
float percent;
|
float percent;
|
||||||
} sys_cpu_t;
|
} sys_cpu_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
char mount_path[MAX_BUF];
|
char mount_path[MAX_BUF];
|
||||||
unsigned long d_total;
|
unsigned long d_total;
|
||||||
unsigned long d_free;
|
unsigned long d_free;
|
||||||
} sys_disk_t;
|
} sys_disk_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
unsigned long m_total;
|
unsigned long m_total;
|
||||||
unsigned long m_free;
|
unsigned long m_free;
|
||||||
@ -124,11 +132,12 @@ typedef struct
|
|||||||
unsigned long m_swap_free;
|
unsigned long m_swap_free;
|
||||||
} sys_mem_t;
|
} sys_mem_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct
|
||||||
|
{
|
||||||
char conf_file[MAX_BUF];
|
char conf_file[MAX_BUF];
|
||||||
char data_file_out[MAX_BUF];
|
char data_file_out[MAX_BUF];
|
||||||
sys_bat_t bat_stat;
|
sys_bat_t bat_stat;
|
||||||
sys_cpu_t* cpus;
|
sys_cpu_t *cpus;
|
||||||
sys_mem_t mem;
|
sys_mem_t mem;
|
||||||
sys_temp_t temp;
|
sys_temp_t temp;
|
||||||
sys_net_t net;
|
sys_net_t net;
|
||||||
@ -158,39 +167,41 @@ static void help(const char *app)
|
|||||||
app);
|
app);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void map(app_data_t* opt)
|
static void map(app_data_t *opt)
|
||||||
{
|
{
|
||||||
float volt = opt->bat_stat.read_voltage*opt->bat_stat.ratio;
|
float volt = opt->bat_stat.read_voltage * opt->bat_stat.ratio;
|
||||||
if(volt < opt->bat_stat.min_voltage)
|
if (volt < opt->bat_stat.min_voltage)
|
||||||
{
|
{
|
||||||
opt->bat_stat.percent = 0.0;
|
opt->bat_stat.percent = 0.0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float result = 101 - (101 / pow(1 + pow(1.33 * (volt - opt->bat_stat.min_voltage) /
|
float result = 101 - (101 / pow(1 + pow(1.33 * (volt - opt->bat_stat.min_voltage) /
|
||||||
(opt->bat_stat.max_voltage - opt->bat_stat.min_voltage), 4.5), 3));
|
(opt->bat_stat.max_voltage - opt->bat_stat.min_voltage),
|
||||||
if(result > 100.0)
|
4.5),
|
||||||
|
3));
|
||||||
|
if (result > 100.0)
|
||||||
result = 100.0;
|
result = 100.0;
|
||||||
|
|
||||||
opt->bat_stat.percent = result;
|
opt->bat_stat.percent = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int guard_write(int fd, void* buffer, size_t size)
|
static int guard_write(int fd, void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
int write_len;
|
int write_len;
|
||||||
int st;
|
int st;
|
||||||
while(n != (int)size)
|
while (n != (int)size)
|
||||||
{
|
{
|
||||||
write_len = (int)size - n;
|
write_len = (int)size - n;
|
||||||
st = write(fd,buffer + n,write_len);
|
st = write(fd, buffer + n, write_len);
|
||||||
if(st == -1)
|
if (st == -1)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME,"Unable to write to #%d: %s", fd, strerror(errno));
|
M_ERROR(MODULE_NAME, "Unable to write to #%d: %s", fd, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(st == 0)
|
if (st == 0)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME,"Endpoint %d is closed", fd);
|
M_ERROR(MODULE_NAME, "Endpoint %d is closed", fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
n += st;
|
n += st;
|
||||||
@ -198,6 +209,27 @@ static int guard_write(int fd, void* buffer, size_t size)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int open_unix_socket(char *path)
|
||||||
|
{
|
||||||
|
struct sockaddr_un address;
|
||||||
|
address.sun_family = AF_UNIX;
|
||||||
|
(void)memset(address.sun_path, 0, sizeof(address.sun_path));
|
||||||
|
(void)memcpy(address.sun_path, path, sizeof(address.sun_path));
|
||||||
|
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (fd == -1)
|
||||||
|
{
|
||||||
|
M_ERROR(MODULE_NAME, "Unable to create Unix domain socket: %s", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (connect(fd, (struct sockaddr *)(&address), sizeof(address)) == -1)
|
||||||
|
{
|
||||||
|
M_ERROR(MODULE_NAME, "Unable to connect to socket '%s': %s", address.sun_path, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
M_LOG(MODULE_NAME, "Socket %s is created successfully", path);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
static int read_line(int fd, char *buf, int size)
|
static int read_line(int fd, char *buf, int size)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -218,22 +250,22 @@ static int read_line(int fd, char *buf, int size)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_voltage(app_data_t* opts)
|
static int read_voltage(app_data_t *opts)
|
||||||
{
|
{
|
||||||
int fd, ret;
|
int fd, ret;
|
||||||
if(opts->bat_stat.bat_in[0] == '\0')
|
if (opts->bat_stat.bat_in[0] == '\0')
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
fd = open(opts->bat_stat.bat_in, O_RDONLY);
|
fd = open(opts->bat_stat.bat_in, O_RDONLY);
|
||||||
if(fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to open input: %s", opts->bat_stat.bat_in);
|
M_ERROR(MODULE_NAME, "Unable to open input: %s", opts->bat_stat.bat_in);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
(void)memset(buf, '\0', sizeof(buf));
|
(void)memset(buf, '\0', sizeof(buf));
|
||||||
ret = read(fd, buf, sizeof(buf));
|
ret = read(fd, buf, sizeof(buf));
|
||||||
if(ret > 0)
|
if (ret > 0)
|
||||||
{
|
{
|
||||||
opts->bat_stat.read_voltage = atoi(buf);
|
opts->bat_stat.read_voltage = atoi(buf);
|
||||||
map(opts);
|
map(opts);
|
||||||
@ -242,14 +274,14 @@ static int read_voltage(app_data_t* opts)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_cpu_info(app_data_t* opts)
|
static int read_cpu_info(app_data_t *opts)
|
||||||
{
|
{
|
||||||
int fd, ret, j, i = 0;
|
int fd, ret, j, i = 0;
|
||||||
const char d[2] = " ";
|
const char d[2] = " ";
|
||||||
char* token;
|
char *token;
|
||||||
unsigned long sum = 0, idle = 0;
|
unsigned long sum = 0, idle = 0;
|
||||||
fd = open("/proc/stat", O_RDONLY);
|
fd = open("/proc/stat", O_RDONLY);
|
||||||
if(fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to open stat: %s", strerror(errno));
|
M_ERROR(MODULE_NAME, "Unable to open stat: %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
@ -257,22 +289,23 @@ static int read_cpu_info(app_data_t* opts)
|
|||||||
for (i = 0; i < opts->n_cpus; i++)
|
for (i = 0; i < opts->n_cpus; i++)
|
||||||
{
|
{
|
||||||
ret = read_line(fd, buf, MAX_BUF);
|
ret = read_line(fd, buf, MAX_BUF);
|
||||||
if(ret > 0 && buf[0] == 'c' && buf[1] == 'p' && buf[2] == 'u')
|
if (ret > 0 && buf[0] == 'c' && buf[1] == 'p' && buf[2] == 'u')
|
||||||
{
|
{
|
||||||
token = strtok(buf,d);
|
token = strtok(buf, d);
|
||||||
sum = 0;
|
sum = 0;
|
||||||
j = 0;
|
j = 0;
|
||||||
while(token!=NULL)
|
while (token != NULL)
|
||||||
{
|
{
|
||||||
token = strtok(NULL,d);
|
token = strtok(NULL, d);
|
||||||
if(token!=NULL){
|
if (token != NULL)
|
||||||
|
{
|
||||||
sum += strtoul(token, NULL, 10);
|
sum += strtoul(token, NULL, 10);
|
||||||
if(j==3)
|
if (j == 3)
|
||||||
idle = strtoul(token, NULL, 10);
|
idle = strtoul(token, NULL, 10);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
opts->cpus[i].percent = 100 - (idle-opts->cpus[i].last_idle)*100.0/(sum-opts->cpus[i].last_sum);
|
opts->cpus[i].percent = 100 - (idle - opts->cpus[i].last_idle) * 100.0 / (sum - opts->cpus[i].last_sum);
|
||||||
opts->cpus[i].last_idle = idle;
|
opts->cpus[i].last_idle = idle;
|
||||||
opts->cpus[i].last_sum = sum;
|
opts->cpus[i].last_sum = sum;
|
||||||
}
|
}
|
||||||
@ -282,8 +315,8 @@ static int read_cpu_info(app_data_t* opts)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void) close(fd);
|
(void)close(fd);
|
||||||
if(i==0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "No CPU info found");
|
M_ERROR(MODULE_NAME, "No CPU info found");
|
||||||
return -1;
|
return -1;
|
||||||
@ -291,23 +324,24 @@ static int read_cpu_info(app_data_t* opts)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_mem_info(app_data_t* opts)
|
static int read_mem_info(app_data_t *opts)
|
||||||
{
|
{
|
||||||
int fd, ret;
|
int fd, ret;
|
||||||
const char d[2] = " ";
|
const char d[2] = " ";
|
||||||
unsigned long data[7];
|
unsigned long data[7];
|
||||||
char* token;
|
char *token;
|
||||||
fd = open("/proc/meminfo", O_RDONLY);
|
fd = open("/proc/meminfo", O_RDONLY);
|
||||||
if(fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to open meminfo: %s", strerror(errno));
|
M_ERROR(MODULE_NAME, "Unable to open meminfo: %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 7; i++) {
|
for (int i = 0; i < 7; i++)
|
||||||
ret = read_line(fd,buf,MAX_BUF);
|
{
|
||||||
token = strtok(buf,d);
|
ret = read_line(fd, buf, MAX_BUF);
|
||||||
token = strtok(NULL,d);
|
token = strtok(buf, d);
|
||||||
if(token != NULL)
|
token = strtok(NULL, d);
|
||||||
|
if (token != NULL)
|
||||||
{
|
{
|
||||||
data[i] = (unsigned long)strtoul(token, NULL, 10);
|
data[i] = (unsigned long)strtoul(token, NULL, 10);
|
||||||
}
|
}
|
||||||
@ -315,25 +349,25 @@ static int read_mem_info(app_data_t* opts)
|
|||||||
{
|
{
|
||||||
data[i] = 0;
|
data[i] = 0;
|
||||||
}
|
}
|
||||||
if(i == 4)
|
if (i == 4)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 9; j++) {
|
for (int j = 0; j < 9; j++)
|
||||||
ret = read_line(fd,buf,MAX_BUF);
|
{
|
||||||
|
ret = read_line(fd, buf, MAX_BUF);
|
||||||
// skip 10 line
|
// skip 10 line
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
opts->mem.m_total = data[0];
|
opts->mem.m_total = data[0];
|
||||||
opts->mem.m_free = data[1];
|
opts->mem.m_free = data[1];
|
||||||
opts->mem.m_available = data[2];
|
opts->mem.m_available = data[2];
|
||||||
opts->mem.m_buffer = data[3];
|
opts->mem.m_buffer = data[3];
|
||||||
opts->mem.m_cache = data[4];
|
opts->mem.m_cache = data[4];
|
||||||
opts->mem.m_swap_total = data[5];
|
opts->mem.m_swap_total = data[5];
|
||||||
opts->mem.m_swap_free = data[6];
|
opts->mem.m_swap_free = data[6];
|
||||||
(void)ret;
|
(void)ret;
|
||||||
(void)close(fd);
|
(void)close(fd);
|
||||||
|
|
||||||
|
|
||||||
/*printf("total: %d used: %d, free: %d buffer/cache: %d, available: %d \n",
|
/*printf("total: %d used: %d, free: %d buffer/cache: %d, available: %d \n",
|
||||||
opts->mem.m_total / 1024,
|
opts->mem.m_total / 1024,
|
||||||
(opts->mem.m_total - opts->mem.m_free - opts->mem.m_buffer-opts->mem.m_cache)/1024,
|
(opts->mem.m_total - opts->mem.m_free - opts->mem.m_buffer-opts->mem.m_cache)/1024,
|
||||||
@ -343,98 +377,98 @@ static int read_mem_info(app_data_t* opts)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_temp_file(const char* file, uint16_t* output)
|
static int read_temp_file(const char *file, uint16_t *output)
|
||||||
{
|
{
|
||||||
int fd, ret;
|
int fd, ret;
|
||||||
if(file[0] != '\0')
|
if (file[0] != '\0')
|
||||||
{
|
{
|
||||||
fd = open(file, O_RDONLY);
|
fd = open(file, O_RDONLY);
|
||||||
if(fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to open temp file %s : %s", file, strerror(errno));
|
M_ERROR(MODULE_NAME, "Unable to open temp file %s : %s", file, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
(void)memset(buf, '\0', sizeof(buf));
|
(void)memset(buf, '\0', sizeof(buf));
|
||||||
ret = read(fd, buf, MAX_BUF);
|
ret = read(fd, buf, MAX_BUF);
|
||||||
if(ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to read temperature: %s", strerror(errno));
|
M_ERROR(MODULE_NAME, "Unable to read temperature: %s", strerror(errno));
|
||||||
(void) close(fd);
|
(void)close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*output = (uint16_t)atoi(buf);
|
*output = (uint16_t)atoi(buf);
|
||||||
(void) close(fd);
|
(void)close(fd);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_cpu_temp(app_data_t* opts)
|
static int read_cpu_temp(app_data_t *opts)
|
||||||
{
|
{
|
||||||
if(read_temp_file(opts->temp.cpu_temp_file, &opts->temp.cpu) == -1)
|
if (read_temp_file(opts->temp.cpu_temp_file, &opts->temp.cpu) == -1)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return read_temp_file(opts->temp.gpu_temp_file, &opts->temp.gpu);
|
return read_temp_file(opts->temp.gpu_temp_file, &opts->temp.gpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_net_statistic(app_data_t* opts)
|
static int read_net_statistic(app_data_t *opts)
|
||||||
{
|
{
|
||||||
int fd, ret;
|
int fd, ret;
|
||||||
float period;
|
float period;
|
||||||
long unsigned int bytes;
|
long unsigned int bytes;
|
||||||
|
|
||||||
period = ((float)opts->sample_period.it_value.tv_nsec) / 1.0e9;
|
period = ((float)opts->sample_period.it_value.tv_nsec) / 1.0e9;
|
||||||
for (int i = 0; i < opts->net.n_intf; i++)
|
for (int i = 0; i < opts->net.n_intf; i++)
|
||||||
{
|
{
|
||||||
// rx
|
// rx
|
||||||
(void)snprintf(buf, MAX_BUF-1, NET_INF_STAT_PT, opts->net.interfaces[i].name, "rx_bytes");
|
(void)snprintf(buf, MAX_BUF - 1, NET_INF_STAT_PT, opts->net.interfaces[i].name, "rx_bytes");
|
||||||
fd = open(buf, O_RDONLY);
|
fd = open(buf, O_RDONLY);
|
||||||
if(fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to open %s: %s", buf, strerror(errno));
|
M_ERROR(MODULE_NAME, "Unable to open %s: %s", buf, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// read data to buff
|
// read data to buff
|
||||||
(void)memset(buf,'\0', MAX_BUF);
|
(void)memset(buf, '\0', MAX_BUF);
|
||||||
ret = read(fd, buf, MAX_BUF);
|
ret = read(fd, buf, MAX_BUF);
|
||||||
(void)close(fd);
|
(void)close(fd);
|
||||||
if(ret <= 0)
|
if (ret <= 0)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to read RX data of %s: %s", opts->net.interfaces[i].name, strerror(errno));
|
M_ERROR(MODULE_NAME, "Unable to read RX data of %s: %s", opts->net.interfaces[i].name, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
bytes = (unsigned long) strtoul(buf, NULL, 10);
|
bytes = (unsigned long)strtoul(buf, NULL, 10);
|
||||||
opts->net.interfaces[i].rx_rate = ((float)(bytes - opts->net.interfaces[i].rx) / period);
|
opts->net.interfaces[i].rx_rate = ((float)(bytes - opts->net.interfaces[i].rx) / period);
|
||||||
opts->net.interfaces[i].rx = bytes;
|
opts->net.interfaces[i].rx = bytes;
|
||||||
|
|
||||||
(void)snprintf(buf, MAX_BUF-1, NET_INF_STAT_PT, opts->net.interfaces[i].name, "tx_bytes");
|
(void)snprintf(buf, MAX_BUF - 1, NET_INF_STAT_PT, opts->net.interfaces[i].name, "tx_bytes");
|
||||||
fd = open(buf, O_RDONLY);
|
fd = open(buf, O_RDONLY);
|
||||||
if(fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to open %s: %s", buf, strerror(errno));
|
M_ERROR(MODULE_NAME, "Unable to open %s: %s", buf, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// read data to buff
|
// read data to buff
|
||||||
(void)memset(buf,'\0', MAX_BUF);
|
(void)memset(buf, '\0', MAX_BUF);
|
||||||
ret = read(fd, buf, MAX_BUF);
|
ret = read(fd, buf, MAX_BUF);
|
||||||
(void)close(fd);
|
(void)close(fd);
|
||||||
if(ret <= 0)
|
if (ret <= 0)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to read TX data of %s: %s", opts->net.interfaces[i].name, strerror(errno));
|
M_ERROR(MODULE_NAME, "Unable to read TX data of %s: %s", opts->net.interfaces[i].name, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
bytes = (unsigned long) strtoul(buf, NULL, 10);
|
bytes = (unsigned long)strtoul(buf, NULL, 10);
|
||||||
opts->net.interfaces[i].tx_rate = ((float)(bytes - opts->net.interfaces[i].tx) / period);
|
opts->net.interfaces[i].tx_rate = ((float)(bytes - opts->net.interfaces[i].tx) / period);
|
||||||
opts->net.interfaces[i].tx = bytes ;
|
opts->net.interfaces[i].tx = bytes;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_disk_usage(app_data_t* opts)
|
static int read_disk_usage(app_data_t *opts)
|
||||||
{
|
{
|
||||||
struct statvfs stat;
|
struct statvfs stat;
|
||||||
int ret = statvfs(opts->disk.mount_path, &stat);
|
int ret = statvfs(opts->disk.mount_path, &stat);
|
||||||
if(ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to query disk usage of %s: %s", opts->disk.mount_path, strerror(errno));
|
M_ERROR(MODULE_NAME, "Unable to query disk usage of %s: %s", opts->disk.mount_path, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
@ -444,96 +478,118 @@ static int read_disk_usage(app_data_t* opts)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int log_to_file(app_data_t* opts)
|
static int log_to_file(app_data_t *opts)
|
||||||
{
|
{
|
||||||
int ret,fd;
|
int ret, fd = -1, use_stdout = 0;
|
||||||
char out_buf[1024];
|
char out_buf[1024];
|
||||||
char net_buf[MAX_BUF];
|
char net_buf[MAX_BUF];
|
||||||
if(opts->data_file_out[0] == '\0')
|
(void)memset(out_buf, 0, sizeof(out_buf));
|
||||||
|
(void)memset(net_buf, 0, sizeof(net_buf));
|
||||||
|
if (opts->data_file_out[0] == '\0')
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
fd = open(opts->data_file_out, O_CREAT|O_WRONLY|O_APPEND | O_NONBLOCK, 0644);
|
// check if we use stdout
|
||||||
if(fd < 0)
|
if (strncmp(opts->data_file_out, "stdout", 6) == 0)
|
||||||
|
{
|
||||||
|
// out put to stdout
|
||||||
|
use_stdout = 1;
|
||||||
|
}
|
||||||
|
else if (strncmp(opts->data_file_out, "sock:", 5) == 0)
|
||||||
|
{
|
||||||
|
// Unix domain socket
|
||||||
|
fd = open_unix_socket(opts->data_file_out + 5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// open regular file
|
||||||
|
fd = open(opts->data_file_out, O_CREAT | O_WRONLY | O_APPEND | O_NONBLOCK, 0644);
|
||||||
|
}
|
||||||
|
if (fd < 0 && !use_stdout)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to open output file: %s", strerror(errno));
|
M_ERROR(MODULE_NAME, "Unable to open output file: %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
(void)memset(buf,'\0',MAX_BUF);
|
(void)memset(buf, '\0', MAX_BUF);
|
||||||
char* ptr = buf;
|
char *ptr = buf;
|
||||||
// CPU
|
// CPU
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
for (int i = 0; i < opts->n_cpus; i++) {
|
for (int i = 0; i < opts->n_cpus; i++)
|
||||||
if(MAX_BUF - len -1 <= 0)
|
{
|
||||||
|
if (MAX_BUF - len - 1 <= 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
snprintf(ptr, MAX_BUF - len -1, "%.3f,", opts->cpus[i].percent);
|
snprintf(ptr, MAX_BUF - len - 1, "%.3f,", opts->cpus[i].percent);
|
||||||
len = strlen(buf);
|
len = strlen(buf);
|
||||||
ptr = buf+len;
|
ptr = buf + len;
|
||||||
}
|
}
|
||||||
buf[len - 1] = '\0';
|
buf[len - 1] = '\0';
|
||||||
|
|
||||||
// NET
|
// NET
|
||||||
len = 0;
|
len = 0;
|
||||||
ptr = net_buf;
|
ptr = net_buf;
|
||||||
for (int i = 0; i < opts->net.n_intf; i++) {
|
for (int i = 0; i < opts->net.n_intf; i++)
|
||||||
if(MAX_BUF - len -1 < strlen(JSON_NET_FMT))
|
{
|
||||||
|
if (MAX_BUF - len - 1 < strlen(JSON_NET_FMT))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
snprintf(ptr, MAX_BUF - len -1, JSON_NET_FMT,
|
snprintf(ptr, MAX_BUF - len - 1, JSON_NET_FMT,
|
||||||
opts->net.interfaces[i].name,
|
opts->net.interfaces[i].name,
|
||||||
opts->net.interfaces[i].rx,
|
opts->net.interfaces[i].rx,
|
||||||
opts->net.interfaces[i].tx,
|
opts->net.interfaces[i].tx,
|
||||||
opts->net.interfaces[i].rx_rate,
|
opts->net.interfaces[i].rx_rate,
|
||||||
opts->net.interfaces[i].tx_rate
|
opts->net.interfaces[i].tx_rate);
|
||||||
);
|
|
||||||
len = strlen(net_buf);
|
len = strlen(net_buf);
|
||||||
ptr = net_buf+len;
|
ptr = net_buf + len;
|
||||||
}
|
}
|
||||||
net_buf[len - 1] = '\0';
|
net_buf[len - 1] = '\0';
|
||||||
|
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
snprintf(out_buf, sizeof(out_buf), JSON_FMT,
|
snprintf(out_buf, sizeof(out_buf), JSON_FMT,
|
||||||
now.tv_sec,
|
now.tv_sec,
|
||||||
now.tv_usec,
|
now.tv_usec,
|
||||||
opts->bat_stat.read_voltage* opts->bat_stat.ratio,
|
opts->bat_stat.read_voltage * opts->bat_stat.ratio,
|
||||||
opts->bat_stat.percent,
|
opts->bat_stat.percent,
|
||||||
opts->bat_stat.max_voltage,
|
opts->bat_stat.max_voltage,
|
||||||
opts->bat_stat.min_voltage,
|
opts->bat_stat.min_voltage,
|
||||||
opts->temp.cpu,
|
opts->temp.cpu,
|
||||||
opts->temp.gpu,
|
opts->temp.gpu,
|
||||||
buf,
|
buf,
|
||||||
opts->mem.m_total,
|
opts->mem.m_total,
|
||||||
opts->mem.m_free,
|
opts->mem.m_free,
|
||||||
(opts->mem.m_total - opts->mem.m_free - opts->mem.m_buffer-opts->mem.m_cache),
|
(opts->mem.m_total - opts->mem.m_free - opts->mem.m_buffer - opts->mem.m_cache),
|
||||||
opts->mem.m_buffer+opts->mem.m_cache,
|
opts->mem.m_buffer + opts->mem.m_cache,
|
||||||
opts->mem.m_available,
|
opts->mem.m_available,
|
||||||
opts->mem.m_swap_total,
|
opts->mem.m_swap_total,
|
||||||
opts->mem.m_swap_free,
|
opts->mem.m_swap_free,
|
||||||
opts->disk.d_total,
|
opts->disk.d_total,
|
||||||
opts->disk.d_free,
|
opts->disk.d_free,
|
||||||
net_buf
|
net_buf);
|
||||||
);
|
out_buf[strlen(out_buf)] = '\n';
|
||||||
ret = guard_write(fd,out_buf,strlen(out_buf));
|
ret = 0;
|
||||||
if(ret <= 0)
|
if (use_stdout)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to write data to output file");
|
printf("%s", out_buf);
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
if(ret != (int)strlen(out_buf))
|
|
||||||
{
|
|
||||||
M_ERROR(MODULE_NAME, "Unable to write all battery info to output file");
|
|
||||||
ret = -1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// M_LOG(MODULE_NAME, "written %d bytes to file: %s", strlen(out_buf), opts->data_file_out);
|
ret = guard_write(fd, out_buf, strlen(out_buf));
|
||||||
ret = 0;
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
M_ERROR(MODULE_NAME, "Unable to write data to output file");
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
if (ret != (int)strlen(out_buf))
|
||||||
|
{
|
||||||
|
M_ERROR(MODULE_NAME, "Unable to write all battery info to output file");
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(void) close(fd);
|
if (fd > 0)
|
||||||
|
(void)close(fd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,75 +598,75 @@ static int ini_handle(void *user_data, const char *section, const char *name, co
|
|||||||
(void)section;
|
(void)section;
|
||||||
unsigned long period = 0;
|
unsigned long period = 0;
|
||||||
const char d[2] = ",";
|
const char d[2] = ",";
|
||||||
char* token;
|
char *token;
|
||||||
|
|
||||||
app_data_t* opts = (app_data_t*) user_data;
|
app_data_t *opts = (app_data_t *)user_data;
|
||||||
if(EQU(name, "battery_max_voltage"))
|
if (EQU(name, "battery_max_voltage"))
|
||||||
{
|
{
|
||||||
opts->bat_stat.max_voltage = atoi(value);
|
opts->bat_stat.max_voltage = atoi(value);
|
||||||
}
|
}
|
||||||
else if(EQU(name, "battery_min_voltage"))
|
else if (EQU(name, "battery_min_voltage"))
|
||||||
{
|
{
|
||||||
opts->bat_stat.min_voltage = atoi(value);
|
opts->bat_stat.min_voltage = atoi(value);
|
||||||
}
|
}
|
||||||
else if(EQU(name, "battery_cutoff_votalge"))
|
else if (EQU(name, "battery_cutoff_votalge"))
|
||||||
{
|
{
|
||||||
opts->bat_stat.cutoff_voltage = atoi(value);
|
opts->bat_stat.cutoff_voltage = atoi(value);
|
||||||
}
|
}
|
||||||
else if(EQU(name, "battery_divide_ratio"))
|
else if (EQU(name, "battery_divide_ratio"))
|
||||||
{
|
{
|
||||||
opts->bat_stat.ratio = atof(value);
|
opts->bat_stat.ratio = atof(value);
|
||||||
}
|
}
|
||||||
else if(EQU(name, "battery_input"))
|
else if (EQU(name, "battery_input"))
|
||||||
{
|
{
|
||||||
strncpy(opts->bat_stat.bat_in, value, MAX_BUF - 1);
|
strncpy(opts->bat_stat.bat_in, value, MAX_BUF - 1);
|
||||||
}
|
}
|
||||||
else if(EQU(name, "sample_period"))
|
else if (EQU(name, "sample_period"))
|
||||||
{
|
{
|
||||||
period = strtoul(value, NULL, 10)*1e6;
|
period = strtoul(value, NULL, 10) * 1e6;
|
||||||
opts->sample_period.it_interval.tv_nsec = period;
|
opts->sample_period.it_interval.tv_nsec = period;
|
||||||
opts->sample_period.it_value.tv_nsec = period;
|
opts->sample_period.it_value.tv_nsec = period;
|
||||||
}
|
}
|
||||||
else if(EQU(name, "cpu_core_number"))
|
else if (EQU(name, "cpu_core_number"))
|
||||||
{
|
{
|
||||||
opts->n_cpus = atoi(value) + 1;
|
opts->n_cpus = atoi(value) + 1;
|
||||||
}
|
}
|
||||||
else if(EQU(name, "power_off_count_down"))
|
else if (EQU(name, "power_off_count_down"))
|
||||||
{
|
{
|
||||||
opts->pwoff_cd = atoi(value);
|
opts->pwoff_cd = atoi(value);
|
||||||
}
|
}
|
||||||
else if(EQU(name, "power_off_percent"))
|
else if (EQU(name, "power_off_percent"))
|
||||||
{
|
{
|
||||||
opts->power_off_percent = (uint8_t)atoi(value);
|
opts->power_off_percent = (uint8_t)atoi(value);
|
||||||
}
|
}
|
||||||
else if(EQU(name, "data_file_out"))
|
else if (EQU(name, "data_file_out"))
|
||||||
{
|
{
|
||||||
(void)strncpy(opts->data_file_out, value, MAX_BUF-1);
|
(void)strncpy(opts->data_file_out, value, MAX_BUF - 1);
|
||||||
}
|
}
|
||||||
else if(EQU(name, "cpu_temperature_input"))
|
else if (EQU(name, "cpu_temperature_input"))
|
||||||
{
|
{
|
||||||
(void)strncpy(opts->temp.cpu_temp_file, value, MAX_BUF-1);
|
(void)strncpy(opts->temp.cpu_temp_file, value, MAX_BUF - 1);
|
||||||
}
|
}
|
||||||
else if(EQU(name, "gpu_temperature_input"))
|
else if (EQU(name, "gpu_temperature_input"))
|
||||||
{
|
{
|
||||||
(void)strncpy(opts->temp.gpu_temp_file, value, MAX_BUF-1);
|
(void)strncpy(opts->temp.gpu_temp_file, value, MAX_BUF - 1);
|
||||||
}
|
}
|
||||||
else if(EQU(name, "disk_mount_point"))
|
else if (EQU(name, "disk_mount_point"))
|
||||||
{
|
{
|
||||||
(void)strncpy(opts->disk.mount_path, value, MAX_BUF-1);
|
(void)strncpy(opts->disk.mount_path, value, MAX_BUF - 1);
|
||||||
}
|
}
|
||||||
else if(EQU(name, "network_interfaces"))
|
else if (EQU(name, "network_interfaces"))
|
||||||
{
|
{
|
||||||
// parsing the network interfaces
|
// parsing the network interfaces
|
||||||
token = strtok((char*)value,d);
|
token = strtok((char *)value, d);
|
||||||
opts->net.n_intf = 0;
|
opts->net.n_intf = 0;
|
||||||
while(token != NULL)
|
while (token != NULL)
|
||||||
{
|
{
|
||||||
(void) strncpy(opts->net.interfaces[opts->net.n_intf].name, token, sizeof(opts->net.interfaces[opts->net.n_intf].name) - 1);
|
(void)strncpy(opts->net.interfaces[opts->net.n_intf].name, token, sizeof(opts->net.interfaces[opts->net.n_intf].name) - 1);
|
||||||
opts->net.n_intf++;
|
opts->net.n_intf++;
|
||||||
if(opts->net.n_intf >= MAX_NETWORK_INF)
|
if (opts->net.n_intf >= MAX_NETWORK_INF)
|
||||||
break;
|
break;
|
||||||
token = strtok(NULL,d);
|
token = strtok(NULL, d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -618,11 +674,11 @@ static int ini_handle(void *user_data, const char *section, const char *name, co
|
|||||||
M_ERROR(MODULE_NAME, "Ignore unknown configuration %s = %s", name, value);
|
M_ERROR(MODULE_NAME, "Ignore unknown configuration %s = %s", name, value);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int load_config(app_data_t* opts)
|
static int load_config(app_data_t *opts)
|
||||||
{
|
{
|
||||||
// global
|
// global
|
||||||
(void)memset(opts->data_file_out, '\0', MAX_BUF);
|
(void)memset(opts->data_file_out, '\0', MAX_BUF);
|
||||||
@ -635,7 +691,7 @@ static int load_config(app_data_t* opts)
|
|||||||
opts->sample_period.it_value.tv_nsec = 3e+8;
|
opts->sample_period.it_value.tv_nsec = 3e+8;
|
||||||
opts->cpus = NULL;
|
opts->cpus = NULL;
|
||||||
opts->n_cpus = 2;
|
opts->n_cpus = 2;
|
||||||
|
|
||||||
//battery
|
//battery
|
||||||
(void)memset(opts->bat_stat.bat_in, '\0', MAX_BUF);
|
(void)memset(opts->bat_stat.bat_in, '\0', MAX_BUF);
|
||||||
opts->bat_stat.max_voltage = 4200;
|
opts->bat_stat.max_voltage = 4200;
|
||||||
@ -645,14 +701,13 @@ static int load_config(app_data_t* opts)
|
|||||||
opts->bat_stat.read_voltage = 0.0;
|
opts->bat_stat.read_voltage = 0.0;
|
||||||
opts->bat_stat.percent = 0.0;
|
opts->bat_stat.percent = 0.0;
|
||||||
opts->power_off_percent = 1;
|
opts->power_off_percent = 1;
|
||||||
|
|
||||||
|
|
||||||
(void)memset(&opts->mem, '\0', sizeof(opts->mem));
|
(void)memset(&opts->mem, '\0', sizeof(opts->mem));
|
||||||
(void)memset(&opts->temp, '\0', sizeof(opts->temp));
|
(void)memset(&opts->temp, '\0', sizeof(opts->temp));
|
||||||
(void)memset(&opts->net, '\0', sizeof(opts->net));
|
(void)memset(&opts->net, '\0', sizeof(opts->net));
|
||||||
(void)memset(&opts->disk, '\0', sizeof(opts->disk));
|
(void)memset(&opts->disk, '\0', sizeof(opts->disk));
|
||||||
opts->disk.mount_path[0] = '/';
|
opts->disk.mount_path[0] = '/';
|
||||||
|
|
||||||
M_LOG(MODULE_NAME, "Use configuration: %s", opts->conf_file);
|
M_LOG(MODULE_NAME, "Use configuration: %s", opts->conf_file);
|
||||||
if (ini_parse(opts->conf_file, ini_handle, opts) < 0)
|
if (ini_parse(opts->conf_file, ini_handle, opts) < 0)
|
||||||
{
|
{
|
||||||
@ -660,14 +715,14 @@ static int load_config(app_data_t* opts)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// check battery configuration
|
// check battery configuration
|
||||||
if((opts->bat_stat.max_voltage < opts->bat_stat.min_voltage) ||
|
if ((opts->bat_stat.max_voltage < opts->bat_stat.min_voltage) ||
|
||||||
(opts->bat_stat.max_voltage < opts->bat_stat.cutoff_voltage) ||
|
(opts->bat_stat.max_voltage < opts->bat_stat.cutoff_voltage) ||
|
||||||
(opts->bat_stat.min_voltage < opts->bat_stat.cutoff_voltage))
|
(opts->bat_stat.min_voltage < opts->bat_stat.cutoff_voltage))
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Battery configuration is invalid: max: %d, min: %d, cut off: %d",
|
M_ERROR(MODULE_NAME, "Battery configuration is invalid: max: %d, min: %d, cut off: %d",
|
||||||
opts->bat_stat.max_voltage,
|
opts->bat_stat.max_voltage,
|
||||||
opts->bat_stat.min_voltage,
|
opts->bat_stat.min_voltage,
|
||||||
opts->bat_stat.cutoff_voltage);
|
opts->bat_stat.cutoff_voltage);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -689,26 +744,26 @@ int main(int argc, char *const *argv)
|
|||||||
switch (ret)
|
switch (ret)
|
||||||
{
|
{
|
||||||
case 'f':
|
case 'f':
|
||||||
(void)strncpy(opts.conf_file, optarg, MAX_BUF-1);
|
(void)strncpy(opts.conf_file, optarg, MAX_BUF - 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
help(argv[0]);
|
help(argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(optind > argc)
|
if (optind > argc)
|
||||||
{
|
{
|
||||||
help(argv[0]);
|
help(argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(load_config(&opts) != 0)
|
if (load_config(&opts) != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"Unable to read config file\n");
|
fprintf(stderr, "Unable to read config file\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
M_LOG(MODULE_NAME, "Data Output: %s", opts.data_file_out);
|
M_LOG(MODULE_NAME, "Data Output: %s", opts.data_file_out);
|
||||||
M_LOG(MODULE_NAME, "Battery input: %s", opts.bat_stat.bat_in);
|
M_LOG(MODULE_NAME, "Battery input: %s", opts.bat_stat.bat_in);
|
||||||
M_LOG(MODULE_NAME, "Battery Max voltage: %d", opts.bat_stat.max_voltage);
|
M_LOG(MODULE_NAME, "Battery Max voltage: %d", opts.bat_stat.max_voltage);
|
||||||
@ -718,16 +773,16 @@ int main(int argc, char *const *argv)
|
|||||||
M_LOG(MODULE_NAME, "Sample period: %d", (int)(opts.sample_period.it_value.tv_nsec / 1e6));
|
M_LOG(MODULE_NAME, "Sample period: %d", (int)(opts.sample_period.it_value.tv_nsec / 1e6));
|
||||||
M_LOG(MODULE_NAME, "CPU cores: %d", opts.n_cpus);
|
M_LOG(MODULE_NAME, "CPU cores: %d", opts.n_cpus);
|
||||||
M_LOG(MODULE_NAME, "Power off count down: %d", opts.pwoff_cd);
|
M_LOG(MODULE_NAME, "Power off count down: %d", opts.pwoff_cd);
|
||||||
M_LOG(MODULE_NAME,"CPU temp. input: %s",opts.temp.cpu_temp_file);
|
M_LOG(MODULE_NAME, "CPU temp. input: %s", opts.temp.cpu_temp_file);
|
||||||
M_LOG(MODULE_NAME,"GPU temp. input: %s",opts.temp.gpu_temp_file);
|
M_LOG(MODULE_NAME, "GPU temp. input: %s", opts.temp.gpu_temp_file);
|
||||||
M_LOG(MODULE_NAME, "Poweroff percent: %d", opts.power_off_percent);
|
M_LOG(MODULE_NAME, "Poweroff percent: %d", opts.power_off_percent);
|
||||||
|
|
||||||
// init timerfd
|
// init timerfd
|
||||||
tfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
|
tfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
|
||||||
if (tfd == -1)
|
if (tfd == -1)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to create timerfd: %s", strerror(errno));
|
M_ERROR(MODULE_NAME, "Unable to create timerfd: %s", strerror(errno));
|
||||||
fprintf(stderr,"Unable to create timer fd: %s\n", strerror(errno));
|
fprintf(stderr, "Unable to create timer fd: %s\n", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (timerfd_settime(tfd, 0 /* no flags */, &opts.sample_period, NULL) == -1)
|
if (timerfd_settime(tfd, 0 /* no flags */, &opts.sample_period, NULL) == -1)
|
||||||
@ -737,8 +792,8 @@ int main(int argc, char *const *argv)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
//init CPU monitors
|
//init CPU monitors
|
||||||
opts.cpus = (sys_cpu_t*) malloc(opts.n_cpus*sizeof(sys_cpu_t));
|
opts.cpus = (sys_cpu_t *)malloc(opts.n_cpus * sizeof(sys_cpu_t));
|
||||||
for(int i=0; i < opts.n_cpus; i++)
|
for (int i = 0; i < opts.n_cpus; i++)
|
||||||
{
|
{
|
||||||
opts.cpus[i].last_sum = 0;
|
opts.cpus[i].last_sum = 0;
|
||||||
opts.cpus[i].last_idle = 0;
|
opts.cpus[i].last_idle = 0;
|
||||||
@ -746,23 +801,23 @@ int main(int argc, char *const *argv)
|
|||||||
}
|
}
|
||||||
// loop
|
// loop
|
||||||
count_down = opts.pwoff_cd;
|
count_down = opts.pwoff_cd;
|
||||||
while(running)
|
while (running)
|
||||||
{
|
{
|
||||||
if(opts.bat_stat.bat_in[0] != '\0')
|
if (opts.bat_stat.bat_in[0] != '\0')
|
||||||
{
|
{
|
||||||
// open the file
|
// open the file
|
||||||
if(read_voltage(&opts) == -1)
|
if (read_voltage(&opts) == -1)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to read system voltage");
|
M_ERROR(MODULE_NAME, "Unable to read system voltage");
|
||||||
}
|
}
|
||||||
volt = opts.bat_stat.read_voltage*opts.bat_stat.ratio;
|
volt = opts.bat_stat.read_voltage * opts.bat_stat.ratio;
|
||||||
if(volt < opts.bat_stat.cutoff_voltage)
|
if (volt < opts.bat_stat.cutoff_voltage)
|
||||||
{
|
{
|
||||||
M_LOG(MODULE_NAME, "Invalid voltage read: %.3f", volt);
|
M_LOG(MODULE_NAME, "Invalid voltage read: %.3f", volt);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(opts.bat_stat.percent <= (float)opts.power_off_percent)
|
if (opts.bat_stat.percent <= (float)opts.power_off_percent)
|
||||||
{
|
{
|
||||||
count_down--;
|
count_down--;
|
||||||
M_LOG(MODULE_NAME, "Out of battery. Will shutdown after %d count down", count_down);
|
M_LOG(MODULE_NAME, "Out of battery. Will shutdown after %d count down", count_down);
|
||||||
@ -773,46 +828,46 @@ int main(int argc, char *const *argv)
|
|||||||
count_down = opts.pwoff_cd;
|
count_down = opts.pwoff_cd;
|
||||||
}
|
}
|
||||||
// check if we should shutdown
|
// check if we should shutdown
|
||||||
if(count_down <= 0)
|
if (count_down <= 0)
|
||||||
{
|
{
|
||||||
M_LOG(MODULE_NAME, "Shutting down system");
|
M_LOG(MODULE_NAME, "Shutting down system");
|
||||||
ret = system("poweroff");
|
ret = system("poweroff");
|
||||||
(void) ret;
|
(void)ret;
|
||||||
// this should never happend
|
// this should never happend
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// read cpu info
|
// read cpu info
|
||||||
if(read_cpu_info(&opts) == -1)
|
if (read_cpu_info(&opts) == -1)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to read CPU infos");
|
M_ERROR(MODULE_NAME, "Unable to read CPU infos");
|
||||||
}
|
}
|
||||||
// read memory usage
|
// read memory usage
|
||||||
if(read_mem_info(&opts) == -1)
|
if (read_mem_info(&opts) == -1)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to read memory usage");
|
M_ERROR(MODULE_NAME, "Unable to read memory usage");
|
||||||
}
|
}
|
||||||
// read CPU temperature
|
// read CPU temperature
|
||||||
if(read_cpu_temp(&opts) == -1)
|
if (read_cpu_temp(&opts) == -1)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to read CPU temperature");
|
M_ERROR(MODULE_NAME, "Unable to read CPU temperature");
|
||||||
}
|
}
|
||||||
if(read_net_statistic(&opts) == -1)
|
if (read_net_statistic(&opts) == -1)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to query network statistic");
|
M_ERROR(MODULE_NAME, "Unable to query network statistic");
|
||||||
}
|
}
|
||||||
if(read_disk_usage(&opts) == -1)
|
if (read_disk_usage(&opts) == -1)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to query disk usage");
|
M_ERROR(MODULE_NAME, "Unable to query disk usage");
|
||||||
}
|
}
|
||||||
// log to file
|
// log to file
|
||||||
if(log_to_file(&opts) == -1)
|
if (log_to_file(&opts) == -1)
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to write sysinfo to output");
|
M_ERROR(MODULE_NAME, "Unable to write sysinfo to output");
|
||||||
}
|
}
|
||||||
// check timeout
|
// check timeout
|
||||||
if(read(tfd, &expirations_count, sizeof(expirations_count)) != (int)sizeof(expirations_count))
|
if (read(tfd, &expirations_count, sizeof(expirations_count)) != (int)sizeof(expirations_count))
|
||||||
{
|
{
|
||||||
M_ERROR(MODULE_NAME, "Unable to read timer: %s", strerror(errno));
|
M_ERROR(MODULE_NAME, "Unable to read timer: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
@ -821,10 +876,10 @@ int main(int argc, char *const *argv)
|
|||||||
M_ERROR(MODULE_NAME, "LOOP OVERFLOW COUNT: %lu", (long unsigned int)expirations_count);
|
M_ERROR(MODULE_NAME, "LOOP OVERFLOW COUNT: %lu", (long unsigned int)expirations_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(opts.cpus)
|
if (opts.cpus)
|
||||||
free(opts.cpus);
|
free(opts.cpus);
|
||||||
if(tfd > 0)
|
if (tfd > 0)
|
||||||
{
|
{
|
||||||
(void)close(tfd);
|
(void)close(tfd);
|
||||||
}
|
}
|
||||||
|
10
sysmond.conf
10
sysmond.conf
@ -23,11 +23,17 @@ disk_mount_point = /
|
|||||||
# the system will be shutdown after n count down
|
# the system will be shutdown after n count down
|
||||||
power_off_count_down = 10
|
power_off_count_down = 10
|
||||||
# the system will bet shutdown if the battery voltage percent is below this value
|
# the system will bet shutdown if the battery voltage percent is below this value
|
||||||
|
# after `power_off_count_down` time
|
||||||
power_off_percent = 3
|
power_off_percent = 3
|
||||||
|
|
||||||
cpu_temperature_input=/sys/devices/virtual/thermal/thermal_zone1/temp
|
cpu_temperature_input=/sys/devices/virtual/thermal/thermal_zone1/temp
|
||||||
|
|
||||||
gpu_temperature_input=/sys/devices/virtual/thermal/thermal_zone2/temp
|
gpu_temperature_input=/sys/devices/virtual/thermal/thermal_zone2/temp
|
||||||
|
|
||||||
# output system info to file
|
# output system info to file
|
||||||
data_file_out = /var/jarvis:fbf070ddea3ea90d07f456540b405d302554ec82
|
# The output file may be: stdout, a regular file or name pipe, or a unix domain socket
|
||||||
|
# To print JSON data records to stdout use
|
||||||
|
# data_file_out = stdout
|
||||||
|
# To send data via unix domain socket use
|
||||||
|
# data_file_out = sock:/path/to/socket/file
|
||||||
|
data_file_out = sock:/var/sysmond.log
|
Loading…
Reference in New Issue
Block a user