blob: 82df61f35a8e476962b70b83c532e2fa326e107c [file] [log] [blame]
Harald Welte1a36f332018-06-04 17:36:33 +02001/* Simple Osmocom System Monitor (osysmon) */
2
3/* (C) 2018 by Harald Welte <laforge@gnumonks.org>
4 * All Rights Reserved.
5 *
6 * SPDX-License-Identifier: GPL-2.0+
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 * MA 02110-1301, USA.
22 */
23
24#include <unistd.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <signal.h>
Pau Espin Pedrolae253992018-12-12 19:37:02 +010029#include <getopt.h>
Harald Welte1a36f332018-06-04 17:36:33 +020030
Harald Welte54ca6f42018-06-04 21:52:30 +020031#include "config.h"
Harald Welte1a36f332018-06-04 17:36:33 +020032#include "osysmon.h"
33#include "value_node.h"
34
35#include <osmocom/core/msgb.h>
36#include <osmocom/core/logging.h>
37#include <osmocom/core/application.h>
38
39static struct log_info log_info = {};
40
41static int osysmon_go_parent(struct vty *vty)
42{
43 switch (vty->node) {
44 case CTRL_CLIENT_NODE:
45 case CTRL_CLIENT_GETVAR_NODE:
46 return osysmon_ctrl_go_parent(vty);
47 }
48 return vty->node;
49}
50
51static int osysmon_is_config_node(struct vty *vty, int node)
52{
53 switch (node) {
54 /* no non-config-nodes */
55 default:
56 return 1;
57 }
58}
59
60
61static struct vty_app_info vty_info = {
62 .name = "osysmon",
63 .copyright =
64 "Copyright (C) 2008-2018 Harald Welte\r\n"
65 "License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>\r\n"
66 "This is free software: you are free to change and redistribute it.\r\n"
67 "There is NO WARRANTY, to the extent permitted by law.\r\n",
Harald Welte54ca6f42018-06-04 21:52:30 +020068 .version = PACKAGE_VERSION,
Harald Welte1a36f332018-06-04 17:36:33 +020069 .go_parent_cb = osysmon_go_parent,
70 .is_config_node = osysmon_is_config_node,
71};
72
Harald Welte1a36f332018-06-04 17:36:33 +020073struct osysmon_state *g_oss;
74
75
Harald Welte3dada482018-06-04 18:22:03 +020076static void print_node(struct value_node *node, unsigned int indent)
Harald Welte1a36f332018-06-04 17:36:33 +020077{
Harald Welte3dada482018-06-04 18:22:03 +020078 unsigned int i;
79
Harald Welte1a36f332018-06-04 17:36:33 +020080 if (node->value) {
Harald Welte3dada482018-06-04 18:22:03 +020081 for (i = 0; i < indent; i++)
82 fputc(' ', stdout);
Harald Welte1a36f332018-06-04 17:36:33 +020083 printf("%s: %s\n", node->name, node->value);
84 } else {
85 struct value_node *vn;
Harald Welte3dada482018-06-04 18:22:03 +020086 for (i = 0; i < indent; i++)
87 fputc(' ', stdout);
88 printf("%s\n", node->name);
Harald Welte1a36f332018-06-04 17:36:33 +020089 llist_for_each_entry(vn, &node->children, list)
Harald Welte3dada482018-06-04 18:22:03 +020090 print_node(vn, indent+2);
Harald Welte1a36f332018-06-04 17:36:33 +020091 }
92}
93
94static void display_update(struct value_node *root)
95{
Harald Welte3dada482018-06-04 18:22:03 +020096 print_node(root, 0);
Harald Welte1a36f332018-06-04 17:36:33 +020097}
98
99static void signal_handler(int signal)
100{
101 fprintf(stderr, "Signal %u received", signal);
102
103 switch(signal) {
104 case SIGUSR1:
105 talloc_report(g_oss, stderr);
106 break;
107 default:
108 break;
109 }
110}
111
Pau Espin Pedrolae253992018-12-12 19:37:02 +0100112static void print_usage()
113{
114 printf("Usage: osmo-sysmon\n");
115}
116
117static void print_help()
118{
119 printf(" -h --help This text.\n");
120 printf(" -c --config-file filename The config file to use.\n");
121 printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM Enable debugging.\n");
122 printf(" -D --daemonize Fork the process into a background daemon.\n");
123 printf(" -s --disable-color Do not print ANSI colors in the log\n");
124 printf(" -T --timestamp Prefix every log line with a timestamp.\n");
125 printf(" -e --log-level number Set a global loglevel.\n");
126 printf(" -V --version Print the version of OsmoHLR.\n");
127}
128
129static struct {
130 const char *config_file;
131 bool daemonize;
132} cmdline_opts = {
133 .config_file = "osmo-sysmon.cfg",
134 .daemonize = false,
135};
136
137static void handle_options(int argc, char **argv)
138{
139 while (1) {
140 int option_index = 0, c;
141 static struct option long_options[] = {
142 {"help", 0, 0, 'h'},
143 {"config-file", 1, 0, 'c'},
144 {"debug", 1, 0, 'd'},
145 {"daemonize", 0, 0, 'D'},
146 {"disable-color", 0, 0, 's'},
147 {"log-level", 1, 0, 'e'},
148 {"timestamp", 0, 0, 'T'},
149 {"version", 0, 0, 'V' },
150 {0, 0, 0, 0}
151 };
152
153 c = getopt_long(argc, argv, "hc:d:Dse:TV",
154 long_options, &option_index);
155 if (c == -1)
156 break;
157
158 switch (c) {
159 case 'h':
160 print_usage();
161 print_help();
162 exit(0);
163 case 'c':
164 cmdline_opts.config_file = optarg;
165 break;
166 case 'd':
167 log_parse_category_mask(osmo_stderr_target, optarg);
168 break;
169 case 'D':
170 cmdline_opts.daemonize = 1;
171 break;
172 case 's':
173 log_set_use_color(osmo_stderr_target, 0);
174 break;
175 case 'e':
176 log_set_log_level(osmo_stderr_target, atoi(optarg));
177 break;
178 case 'T':
179 log_set_print_timestamp(osmo_stderr_target, 1);
180 break;
181 case 'V':
182 print_version(1);
183 exit(0);
184 break;
185 default:
186 /* catch unknown options *as well as* missing arguments. */
187 fprintf(stderr, "Error in command line options. Exiting.\n");
188 exit(-1);
189 break;
190 }
191 }
192}
193
Harald Welte1a36f332018-06-04 17:36:33 +0200194int main(int argc, char **argv)
195{
196 int rc;
197
198 osmo_init_logging2(NULL, &log_info);
199
200 g_oss = talloc_zero(NULL, struct osysmon_state);
201 INIT_LLIST_HEAD(&g_oss->ctrl_clients);
Harald Welte9e7fe002018-06-04 20:09:26 +0200202 INIT_LLIST_HEAD(&g_oss->netdevs);
Harald Welte81e20232018-06-04 21:25:56 +0200203 INIT_LLIST_HEAD(&g_oss->files);
Harald Welte1a36f332018-06-04 17:36:33 +0200204
205 vty_init(&vty_info);
Pau Espin Pedrolae253992018-12-12 19:37:02 +0100206 handle_options(argc, argv);
Harald Welte32f7a992018-06-04 18:07:33 +0200207 osysmon_sysinfo_init();
Harald Welte1a36f332018-06-04 17:36:33 +0200208 osysmon_ctrl_init();
Harald Welte9e7fe002018-06-04 20:09:26 +0200209 osysmon_rtnl_init();
Harald Welte81e20232018-06-04 21:25:56 +0200210 osysmon_file_init();
Harald Welte1a36f332018-06-04 17:36:33 +0200211
Pau Espin Pedrolae253992018-12-12 19:37:02 +0100212 rc = vty_read_config_file(cmdline_opts.config_file, NULL);
Harald Welte1a36f332018-06-04 17:36:33 +0200213 if (rc < 0) {
Pau Espin Pedrolae253992018-12-12 19:37:02 +0100214 fprintf(stderr, "Failed to parse the config file %s\n",
215 cmdline_opts.config_file);
Harald Welte1a36f332018-06-04 17:36:33 +0200216 exit(2);
217 }
218
219 signal(SIGUSR1, &signal_handler);
220 signal(SIGUSR2, &signal_handler);
221 osmo_init_ignore_signals();
222
Pau Espin Pedrolae253992018-12-12 19:37:02 +0100223 if (cmdline_opts.daemonize) {
224 rc = osmo_daemonize();
225 if (rc < 0) {
226 perror("Error during daemonize");
227 exit(1);
228 }
229 }
230
Harald Welte1a36f332018-06-04 17:36:33 +0200231 while (1) {
Maxf41973e2019-01-25 18:40:11 +0100232 struct value_node *root = value_node_add(NULL, "root", NULL);
Harald Welte32f7a992018-06-04 18:07:33 +0200233 osysmon_sysinfo_poll(root);
Harald Welte1a36f332018-06-04 17:36:33 +0200234 osysmon_ctrl_poll(root);
Harald Welte9e7fe002018-06-04 20:09:26 +0200235 osysmon_rtnl_poll(root);
Harald Welte81e20232018-06-04 21:25:56 +0200236 osysmon_file_poll(root);
Harald Welte32f7a992018-06-04 18:07:33 +0200237
Harald Welte1a36f332018-06-04 17:36:33 +0200238 display_update(root);
239 value_node_del(root);
240 sleep(1);
241 }
242
243 exit(0);
244}