mirror of https://gerrit.osmocom.org/osmo-sysmon
268 lines
6.2 KiB
C
268 lines
6.2 KiB
C
/* Simple Osmocom System Monitor (osysmon) */
|
|
|
|
/* (C) 2018 by Harald Welte <laforge@gnumonks.org>
|
|
* All Rights Reserved.
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
* MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <signal.h>
|
|
#include <getopt.h>
|
|
|
|
#include "config.h"
|
|
#include "osysmon.h"
|
|
#include "value_node.h"
|
|
|
|
#include <osmocom/core/msgb.h>
|
|
#include <osmocom/core/logging.h>
|
|
#include <osmocom/core/application.h>
|
|
#include <osmocom/core/timer.h>
|
|
|
|
static struct log_info log_info = {};
|
|
|
|
static int osysmon_go_parent(struct vty *vty)
|
|
{
|
|
switch (vty->node) {
|
|
case CTRL_CLIENT_NODE:
|
|
case CTRL_CLIENT_GETVAR_NODE:
|
|
return osysmon_ctrl_go_parent(vty);
|
|
}
|
|
return vty->node;
|
|
}
|
|
|
|
static int osysmon_is_config_node(struct vty *vty, int node)
|
|
{
|
|
switch (node) {
|
|
/* no non-config-nodes */
|
|
default:
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
static struct vty_app_info vty_info = {
|
|
.name = "osysmon",
|
|
.copyright =
|
|
"Copyright (C) 2008-2018 Harald Welte\r\n"
|
|
"License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>\r\n"
|
|
"This is free software: you are free to change and redistribute it.\r\n"
|
|
"There is NO WARRANTY, to the extent permitted by law.\r\n",
|
|
.version = PACKAGE_VERSION,
|
|
.go_parent_cb = osysmon_go_parent,
|
|
.is_config_node = osysmon_is_config_node,
|
|
};
|
|
|
|
struct osysmon_state *g_oss;
|
|
|
|
|
|
static void print_node(struct value_node *node, unsigned int indent)
|
|
{
|
|
unsigned int i;
|
|
|
|
if (node->value) {
|
|
for (i = 0; i < indent; i++)
|
|
fputc(' ', stdout);
|
|
printf("%s: %s\n", node->name, node->value);
|
|
} else {
|
|
struct value_node *vn;
|
|
for (i = 0; i < indent; i++)
|
|
fputc(' ', stdout);
|
|
printf("%s\n", node->name);
|
|
llist_for_each_entry(vn, &node->children, list)
|
|
print_node(vn, indent+2);
|
|
}
|
|
}
|
|
|
|
static void display_update(struct value_node *root)
|
|
{
|
|
print_node(root, 0);
|
|
}
|
|
|
|
static void signal_handler(int signal)
|
|
{
|
|
fprintf(stderr, "Signal %u received", signal);
|
|
|
|
switch(signal) {
|
|
case SIGUSR1:
|
|
talloc_report(g_oss, stderr);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void print_usage()
|
|
{
|
|
printf("Usage: osmo-sysmon\n");
|
|
}
|
|
|
|
static void print_help()
|
|
{
|
|
printf(" -h --help This text.\n");
|
|
printf(" -c --config-file filename The config file to use.\n");
|
|
printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM Enable debugging.\n");
|
|
printf(" -D --daemonize Fork the process into a background daemon.\n");
|
|
printf(" -s --disable-color Do not print ANSI colors in the log\n");
|
|
printf(" -T --timestamp Prefix every log line with a timestamp.\n");
|
|
printf(" -e --log-level number Set a global loglevel.\n");
|
|
printf(" -V --version Print the version of osmo-sysmon.\n");
|
|
}
|
|
|
|
static struct {
|
|
const char *config_file;
|
|
bool daemonize;
|
|
} cmdline_opts = {
|
|
.config_file = "osmo-sysmon.cfg",
|
|
.daemonize = false,
|
|
};
|
|
|
|
static void handle_options(int argc, char **argv)
|
|
{
|
|
while (1) {
|
|
int option_index = 0, c;
|
|
static struct option long_options[] = {
|
|
{"help", 0, 0, 'h'},
|
|
{"config-file", 1, 0, 'c'},
|
|
{"debug", 1, 0, 'd'},
|
|
{"daemonize", 0, 0, 'D'},
|
|
{"disable-color", 0, 0, 's'},
|
|
{"log-level", 1, 0, 'e'},
|
|
{"timestamp", 0, 0, 'T'},
|
|
{"version", 0, 0, 'V' },
|
|
{0, 0, 0, 0}
|
|
};
|
|
|
|
c = getopt_long(argc, argv, "hc:d:Dse:TV",
|
|
long_options, &option_index);
|
|
if (c == -1)
|
|
break;
|
|
|
|
switch (c) {
|
|
case 'h':
|
|
print_usage();
|
|
print_help();
|
|
exit(0);
|
|
case 'c':
|
|
cmdline_opts.config_file = optarg;
|
|
break;
|
|
case 'd':
|
|
log_parse_category_mask(osmo_stderr_target, optarg);
|
|
break;
|
|
case 'D':
|
|
cmdline_opts.daemonize = 1;
|
|
break;
|
|
case 's':
|
|
log_set_use_color(osmo_stderr_target, 0);
|
|
break;
|
|
case 'e':
|
|
log_set_log_level(osmo_stderr_target, atoi(optarg));
|
|
break;
|
|
case 'T':
|
|
log_set_print_timestamp(osmo_stderr_target, 1);
|
|
break;
|
|
case 'V':
|
|
print_version(1);
|
|
exit(0);
|
|
break;
|
|
default:
|
|
/* catch unknown options *as well as* missing arguments. */
|
|
fprintf(stderr, "Error in command line options. Exiting.\n");
|
|
exit(-1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static struct osmo_timer_list print_timer;
|
|
int ping_init;
|
|
|
|
static void print_nodes(__attribute__((unused)) void *data)
|
|
{
|
|
struct value_node *root = value_node_add(NULL, "root", NULL);
|
|
osysmon_openvpn_poll(root);
|
|
osysmon_sysinfo_poll(root);
|
|
osysmon_ctrl_poll(root);
|
|
osysmon_rtnl_poll(root);
|
|
|
|
if (ping_init == 0)
|
|
osysmon_ping_poll(root);
|
|
|
|
osysmon_file_poll(root);
|
|
osysmon_shellcmd_poll(root);
|
|
|
|
display_update(root);
|
|
value_node_del(root);
|
|
|
|
osmo_timer_schedule(&print_timer, 1, 0);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int rc;
|
|
|
|
osmo_init_logging2(NULL, &log_info);
|
|
|
|
g_oss = talloc_zero(NULL, struct osysmon_state);
|
|
INIT_LLIST_HEAD(&g_oss->shellcmds);
|
|
INIT_LLIST_HEAD(&g_oss->ctrl_clients);
|
|
INIT_LLIST_HEAD(&g_oss->openvpn_clients);
|
|
INIT_LLIST_HEAD(&g_oss->netdevs);
|
|
INIT_LLIST_HEAD(&g_oss->files);
|
|
|
|
vty_init(&vty_info);
|
|
handle_options(argc, argv);
|
|
osysmon_sysinfo_init();
|
|
osysmon_shellcmd_init();
|
|
osysmon_ctrl_init();
|
|
osysmon_openvpn_init();
|
|
osysmon_rtnl_init();
|
|
ping_init = osysmon_ping_init();
|
|
osysmon_file_init();
|
|
|
|
signal(SIGUSR1, &signal_handler);
|
|
signal(SIGUSR2, &signal_handler);
|
|
osmo_init_ignore_signals();
|
|
|
|
rc = vty_read_config_file(cmdline_opts.config_file, NULL);
|
|
if (rc < 0) {
|
|
fprintf(stderr, "Failed to parse the config file %s\n",
|
|
cmdline_opts.config_file);
|
|
exit(2);
|
|
}
|
|
|
|
if (cmdline_opts.daemonize) {
|
|
rc = osmo_daemonize();
|
|
if (rc < 0) {
|
|
perror("Error during daemonize");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
osmo_timer_setup(&print_timer, print_nodes, NULL);
|
|
osmo_timer_schedule(&print_timer, 0, 0);
|
|
|
|
while (1)
|
|
osmo_select_main(0);
|
|
|
|
exit(0);
|
|
}
|