Removing the --rotate option, as it is unused. Use lwes-journaller-rotate instead.
[lwes-journaller.git] / src / opt.c
blob614ac4bcb4213b3ce0e24d96377acc4aa23097dc
1 /*======================================================================*
2 * Copyright (C) 2008 Light Weight Event System *
3 * All rights reserved. *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the Free Software *
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
18 * Boston, MA 02110-1301 USA. *
19 *======================================================================*/
20 #include "config.h"
22 #include "log.h"
23 #include "opt.h"
24 #include <string.h>
26 #if HAVE_LIBGEN_H
27 #include <libgen.h>
28 #endif
30 #include <popt.h>
31 #include <stdlib.h>
32 #include <unistd.h>
34 /* Base program name from argv[0]. */
35 char* arg_basename = 0;
37 /* Number of network reader processes/threads to run. */
38 int arg_nreaders = 1;
40 /* Set default queue type, types in preferred order. */
41 #if HAVE_MQUEUE_H
42 const char* arg_queue_type = ARG_MQ;
43 #elif HAVE_SYS_MSG_H
44 const char* arg_queue_type = ARG_MSG;
45 #else
46 #error No kernel message queue support on this platform.
47 #endif
49 /* Queue parameters. */
50 const char* arg_queue_name = "/lwes_journal";
51 int arg_queue_max_sz = 64*1024 - 1;
52 int arg_queue_max_cnt = 10000;
53 int arg_hurryup_at = 80 ;
54 int arg_hurrydown_at = 50 ;
55 int arg_join_group;
56 char* arg_sink_ram = NULL ;
57 char nam_sink_ram[500] ; /* holds real /sink/ram/all_events.log.gz
58 * filename */
60 #if HAVE_LIBZ
61 const char* arg_journ_type = ARG_GZ;
62 #else
63 const char* arg_journ_type = ARG_FILE;
64 #endif
65 int arg_rotate_mask = 30 ; /* ignore any duplicate Command::Rotate
66 * within 30 seconds */
67 char* arg_monitor_type = NULL ;
69 #if HAVE_PTHREAD_H
70 const char* arg_proc_type = ARG_THREAD;
71 #else
72 const char* arg_proc_type = ARG_PROCESS;
73 #endif
75 /* network transport parameters */
76 const char* arg_xport = "udp";
77 const char* arg_ip = "224.0.0.69";
78 int arg_port = 9191;
79 const char* arg_interface = "";
80 int arg_join_group = 1;
81 int arg_sockbuffer = 16*1024*1024;
82 int arg_ttl = 16 ;
83 int arg_nopong = 0 ;
85 /* Set the logging level, see log.h. */
86 int arg_log_level = LOG_MASK_ERROR
87 | LOG_MASK_WARNING
88 | LOG_MASK_INFO;
90 int arg_rt = 0;
92 /* site ID used to set various config items from config file. */
93 int arg_site = 1;
95 /* Queue report interval. */
96 /*TODO: int arg_interval = 60;*/
98 const char* arg_pid_file = "/var/run/lwes-journaller.pid";
100 /* Journals specified and number of journals specified. */
101 char** arg_journalls;
102 int arg_njournalls;
103 char* arg_disk_journals[10];
105 int arg_nodaemonize = 0;
107 /* Print version, then exit. */
108 int arg_version;
110 /* Print args to sub-programs, then exit. */
111 int arg_args;
113 void process_options(int argc, const char* argv[])
115 static const struct poptOption options[] = {
116 { "args", 0, POPT_ARG_NONE, &arg_args, 0, "Print command line arguments, then exit", 0 },
117 { "nodaemonize", 0, POPT_ARG_NONE, &arg_nodaemonize, 0, "Don't run in the background", 0 },
118 { "hurryup-at", 0, POPT_ARG_INT, &arg_hurryup_at, 0, "Hurry-up if queue use > this, dflt=80", "percentage" },
119 { "hurrydown-at", 0, POPT_ARG_INT, &arg_hurrydown_at, 0, "Quit hurry-up when queue use returns to < this, dflt=50", "percentage" },
120 { "log-level", 0, POPT_ARG_INT, &arg_log_level, 0, "Set the output logging level - OFF=(1), ERROR=(2), WARNING=(4), INFO=(8), PROGRESS=(16)", "mask" },
121 { "interface", 'I', POPT_ARG_STRING, &arg_interface, 0, "Network interface to listen on", "ip" },
122 /*TODO: { "report-interval", 's', POPT_ARG_INT, &arg_interval, 0, "Queue report interval", "seconds" },*/
123 { "address", 'm', POPT_ARG_STRING, &arg_ip, 0, "IP address", "ip" },
124 { "join-group", 'g', POPT_ARG_INT, &arg_join_group, 0, "Join multicast group", "0/1" },
125 { "journal-type", 'j', POPT_ARG_STRING, &arg_journ_type, 0, "Journal type", "{" ARG_GZ "," ARG_FILE "}" },
126 { "monitor-type", 'j', POPT_ARG_STRING, &arg_monitor_type, 0, "Monitor type", 0 },
127 { "log-level", 0, POPT_ARG_INT, &arg_log_level, 0, "Set the output logging level - OFF=(1), ERROR=(2), WARNING=(4), INFO=(8), PROGRESS=(16)", "mask" },
128 { "nopong", 0, POPT_ARG_NONE, &arg_nopong, 0, "Don not reply to System::Ping", 0 },
129 { "nreaders", 'r', POPT_ARG_INT, &arg_nreaders, 0, "Number of network reading threads, dflt=1, max=5", 0 },
130 { "pid-file", 'f', POPT_ARG_STRING, &arg_pid_file, 0, "PID file, dflt=NULL", "path" },
131 { "port", 'p', POPT_ARG_INT, &arg_port, 0, "Port number to listen on, dflt=9191", "short" },
132 { "thread-type", 't', POPT_ARG_STRING, &arg_proc_type, 0, "Threading model, '" ARG_THREAD "' or '" ARG_PROCESS "', dflt="
133 #if HAVE_PTHREAD_H
134 ARG_THREAD
135 #else
136 ARG_PROCESS
137 #endif
138 , 0 },
139 { "queue-max-cnt", 0, POPT_ARG_INT, &arg_queue_max_cnt, 0, "Max messages for queue, dflt=10000", "int" },
140 { "queue-max-sz", 0, POPT_ARG_INT, &arg_queue_max_sz, 0, "Max message size for queue, dflt=65535", "int" },
141 { "queue-name", 'Q', POPT_ARG_STRING, &arg_queue_name, 0, "Queue name, should start with '/', dflt='/lwes_journal'", "string" },
142 { "queue-type", 'q', POPT_ARG_STRING, &arg_queue_type, 0, "Queue type", "{" ARG_MSG "," ARG_MQ "}" },
143 { "rotate-mask", 'd', POPT_ARG_INT, &arg_rotate_mask, 0, "Rotate mask, dflt=30", "seconds" },
144 { "real-time", 'R', POPT_ARG_NONE, &arg_rt, 0, "Run threads with real-time priority", 0 },
145 { "sink-ram", 'z', POPT_ARG_STRING, &arg_sink_ram, 0, "/sink/ram/", "NULL" },
146 { "site", 'n', POPT_ARG_INT, &arg_site, 0, "Site id", "int" },
147 { "sockbuffer", 0, POPT_ARG_INT, &arg_sockbuffer, 0, "Receive socket buffer size", "bytes" },
148 { "ttl", 16, POPT_ARG_INT, &arg_ttl, 0, "Emitting TTL value", "hops" },
149 { "version", 'v', POPT_ARG_NONE, &arg_version, 0, "Display version, then exit", 0 },
150 { "xport-type", 'x', POPT_ARG_STRING, &arg_xport, 0, "Transport, dflt=udp", "{" ARG_UDP ", ...}" },
152 POPT_AUTOHELP
153 { NULL, 0, 0, NULL, 0, NULL, NULL }};
155 int bad_options = 0;
156 int rc;
158 #if HAVE_LIBGEN_H
159 arg_basename = basename((char*)argv[0]);
160 #else
161 arg_basename = (char*)argv[0];
162 #endif
164 poptContext optCon = poptGetContext(NULL, argc, argv, options, 0);
165 poptSetOtherOptionHelp(optCon, "");
167 while ( (rc = poptGetNextOpt(optCon)) != -1 )
169 if ( rc < 0 )
171 switch ( rc )
173 case POPT_ERROR_BADOPT:
174 /* You might waht to check options of other types here... */
176 default:
177 LOG_ER("%s: %s\n",
178 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
179 poptStrerror(rc));
180 ++bad_options;
185 arg_journalls = (char**) poptGetArgs(optCon);
186 if ( arg_journalls == NULL
187 || ! arg_journalls[0]
188 || ! strrchr(arg_journalls[0],'/') )
190 LOG_ER("%s requires output pathnames in form "
191 "'/path/to/archive/file.gz'\n", arg_basename);
192 ++bad_options;
195 if ( bad_options )
197 exit(EXIT_FAILURE);
200 /* Count the journals specified on the command line. */
201 if ( arg_journalls )
203 for ( arg_njournalls=0; arg_journalls[arg_njournalls]; ++arg_njournalls )
207 /* Use default journal spec if none provided on the command line. */
208 if ( 0 == arg_njournalls )
210 static const char* default_arg_journalls[] = { "/tmp/all_events.log.gz",
211 NULL };
212 arg_journalls = (char**) default_arg_journalls;
213 arg_njournalls = 1;
216 if ( arg_sink_ram != NULL )
218 strcpy(nam_sink_ram, arg_sink_ram) ;
219 if ( nam_sink_ram[strlen(nam_sink_ram)-1] != '/' )
221 strcat(nam_sink_ram, "/") ;
223 strcat(nam_sink_ram, strrchr(arg_journalls[0],'/') + 1) ;
225 arg_disk_journals[arg_njournalls] = NULL ;
226 while ( --arg_njournalls >= 0 )
228 /* copy original arg_journalls to arg_disk_journals */
229 arg_disk_journals[arg_njournalls] = arg_journalls[arg_njournalls] ;
232 arg_journalls[0] = nam_sink_ram ;
233 arg_journalls[1] = NULL ;
234 arg_njournalls = 1 ;
237 if ( arg_version )
239 printf("The packet journaller is a program for recording LWES\n"
240 "messages for later processing.\n"
241 "\n"
242 "It listens for UDP packets on an interface/IP address/port\n"
243 "combination and writes them to an optionally compressed\n"
244 "packet journal file.\n"
245 "\n"
246 "It adds a 22 bytes header with the packet size and sender\n"
247 "information. See the README file for additional details.\n"
248 "\n"
249 "The journaller looks at the \"message type\" in each received\n"
250 "packet and will rotate the logs if it matches\n"
251 "\"Command::Rotate\".\n"
252 "\n"
255 printf("Compile time features: \n"
257 " process model(s): "
258 #if HAVE_PTHREAD_H
259 "threads "
260 #endif
261 "exec "
262 ";\n"
264 " queue type(s): "
265 #if HAVE_MQUEUE_H
266 "mqueue "
267 #endif
268 #if HAVE_SYS_MSG_H
269 "msg "
270 #endif
271 ";\n"
273 " journal type(s): "
274 #if HAVE_LIBZ
275 "gz "
276 #endif
277 "file "
278 ";\n"
280 #if HAVE_SCHED_H
281 " scheduling type(s): FIFO "
282 ";\n"
283 #endif
285 "\n"
288 printf("Bug reports to %s\n\n", PACKAGE_BUGREPORT);
290 exit(EXIT_SUCCESS);
293 if ( arg_args )
295 char log_level_string[100];
297 log_get_level_string(log_level_string, sizeof(log_level_string));
299 log_msg(LOG_MASK_INFO, __FILE__, __LINE__,
300 "arguments:\n"
301 " arg_basename == \"%s\"\n"
302 " arg_hurryup_at == %d\n"
303 " arg_hurrydown_at == %d\n"
304 " arg_interface == \"%s\"\n"
305 " arg_ip == \"%s\"\n"
306 " arg_journ_type == \"%s\"\n"
307 " arg_monitor_type == \"%s\"\n"
308 " arg_pid_file == \"%s\"\n"
309 " arg_proc_type == \"%s\"\n"
310 " arg_queue_name == \"%s\"\n"
311 " arg_queue_type == \"%s\"\n"
312 " arg_xport == \"%s\"\n"
313 /*" arg_interval == %d\n"*/
314 " arg_join_group == %d\n"
315 " arg_log_level == %s\n"
316 " arg_njournalls == %d\n"
317 " %s" // -nopong generates own message
318 " arg_nreaders == %d\n"
319 " arg_port == %d\n"
320 " arg_queue_max_cnt == %d\n"
321 " arg_queue_max_sz == %d\n"
322 " arg_rt == %d\n"
323 " arg_sink_ram == %s\n"
324 " arg_site == %d\n"
325 " arg_ttl == %d\n",
326 arg_basename,
327 arg_hurryup_at,
328 arg_hurrydown_at,
329 arg_interface,
330 arg_ip,
331 arg_journ_type,
332 arg_pid_file,
333 arg_proc_type,
334 arg_queue_name,
335 arg_queue_type,
336 arg_monitor_type,
337 arg_xport,
338 /*TODO: arg_interval,*/
339 arg_join_group,
340 log_level_string,
341 arg_njournalls,
342 arg_nopong?" arg_nopong\n":"",
343 arg_nreaders,
344 arg_port,
345 arg_queue_max_cnt,
346 arg_queue_max_sz,
347 arg_rt,
348 arg_sink_ram,
349 arg_site,
350 arg_ttl);
352 for ( arg_njournalls=0; arg_journalls[arg_njournalls]; ++arg_njournalls )
354 log_msg(LOG_MASK_INFO, __FILE__, __LINE__,
355 "journall[%d] == %s\n",
356 arg_njournalls,
357 arg_journalls[arg_njournalls]);
359 exit(EXIT_SUCCESS);