1 /*======================================================================*
2 * Copyright (c) 2008, Yahoo! Inc. All rights reserved. *
3 * Copyright (c) 2010-2016, OpenX Inc. All rights reserved. *
5 * Licensed under the New BSD License (the "License"); you may not use *
6 * this file except in compliance with the License. Unless required *
7 * by applicable law or agreed to in writing, software distributed *
8 * under the License is distributed on an "AS IS" BASIS, WITHOUT *
9 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
10 * See the License for the specific language governing permissions and *
11 * limitations under the License. See accompanying LICENSE file. *
12 *======================================================================*/
28 #include <sys/types.h>
31 /* Base program name from argv[0]. */
32 char* arg_basename
= 0;
34 /* Set default queue type, types in preferred order. */
36 const char* arg_queue_type
= ARG_MQ
;
38 const char* arg_queue_type
= ARG_MSG
;
40 #error No kernel message queue support on this platform.
43 /* Queue parameters. */
44 const char* arg_queue_name
= "/lwes_journal";
45 int arg_queue_max_sz
= 64*1024 - 1;
46 int arg_queue_max_cnt
= 10000;
49 const char* arg_journ_type
= ARG_GZ
;
51 const char* arg_journ_type
= ARG_FILE
;
55 const char* arg_proc_type
= ARG_THREAD
;
57 const char* arg_proc_type
= ARG_PROCESS
;
60 /* network transport parameters */
61 const char* arg_xport
= "udp";
62 const char* arg_ip
= "224.0.0.69";
64 const char* arg_interface
= NULL
;
65 int arg_sockbuffer
= 16*1024*1024;
68 /* Set the logging level, see log.h. */
69 int arg_log_level
= LOG_MASK_ERROR
72 const char* arg_log_file
= NULL
;
76 /* site ID used to set various config items from config file. */
79 /* intended owner of journal files */
80 int arg_journal_uid
= 0;
81 const char* arg_journal_user
= NULL
;
83 /* Queue report interval. */
84 int arg_queue_test_interval
= 10000;
86 const char* arg_pid_file
= "/var/run/lwes-journaller.pid";
88 /* Journals specified and number of journals specified. */
91 char* arg_disk_journals
[10];
93 /* Journal rotate interval in seconds (will attempt to rotate on
94 * round intervals starting at beginning of day)
96 int arg_journal_rotate_interval
= 0;
97 int arg_wakup_interval_ms
= WAKEUP_MS
;
99 int arg_nodaemonize
= 0;
101 /* Print version, then exit. */
104 /* Print args to sub-programs, then exit. */
107 #ifdef HAVE_MONDEMAND
108 const char* arg_mondemand_host
= NULL
;
109 const char* arg_mondemand_ip
= NULL
;
110 int arg_mondemand_port
= 20402;
111 const char* arg_mondemand_program_id
= "lwes-journaller";
114 void process_options(int argc
, const char* argv
[])
116 static const struct poptOption options
[] = {
117 { "args", 0, POPT_ARG_NONE
, &arg_args
, 0, "Print command line arguments, then exit", 0 },
118 { "nodaemonize", 0, POPT_ARG_NONE
, &arg_nodaemonize
, 0, "Don't run in the background", 0 },
119 { "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" },
120 { "log-file", 0, POPT_ARG_STRING
, &arg_log_file
, 0, "Set the output log file", "file" },
121 { "interface", 'I', POPT_ARG_STRING
, &arg_interface
, 0, "Network interface to listen on", "ip" },
122 { "queue-test-interval", 'q', POPT_ARG_INT
, &arg_queue_test_interval
, 0, "Queue depth test interval for serial mode (dflt=10000)", "milliseconds" },
123 { "address", 'm', POPT_ARG_STRING
, &arg_ip
, 0, "IP address", "ip" },
124 { "journal-type", 'j', POPT_ARG_STRING
, &arg_journ_type
, 0, "Journal type", "{" ARG_GZ
"," ARG_FILE
"}" },
125 { "journal-rotate-interval", 'i', POPT_ARG_INT
, &arg_journal_rotate_interval
, 0, "Journal rotation interval in seconds (default off)", 0 },
126 { "pid-file", 'f', POPT_ARG_STRING
, &arg_pid_file
, 0, "PID file, dflt=NULL", "path" },
127 { "port", 'p', POPT_ARG_INT
, &arg_port
, 0, "Port number to listen on, dflt=9191", "short" },
128 { "thread-type", 't', POPT_ARG_STRING
, &arg_proc_type
, 0, "Threading model, '" ARG_THREAD
"' or '" ARG_PROCESS
"' or '" ARG_SERIAL
"', dflt="
135 { "queue-max-cnt", 0, POPT_ARG_INT
, &arg_queue_max_cnt
, 0, "Max messages for queue, dflt=10000", "int" },
136 { "queue-max-sz", 0, POPT_ARG_INT
, &arg_queue_max_sz
, 0, "Max message size for queue, dflt=65535", "int" },
137 { "queue-name", 'Q', POPT_ARG_STRING
, &arg_queue_name
, 0, "Queue name, should start with '/', dflt='/lwes_journal'", "string" },
138 { "queue-type", 'q', POPT_ARG_STRING
, &arg_queue_type
, 0, "Queue type", "{" ARG_MSG
"," ARG_MQ
"}" },
139 { "real-time", 'R', POPT_ARG_NONE
, &arg_rt
, 0, "Run threads with real-time priority", 0 },
140 { "site", 'n', POPT_ARG_INT
, &arg_site
, 0, "Site id", "int" },
141 { "sockbuffer", 0, POPT_ARG_INT
, &arg_sockbuffer
, 0, "Receive socket buffer size", "bytes" },
142 { "ttl", 0, POPT_ARG_INT
, &arg_ttl
, 0, "Emitting TTL value", "hops" },
143 { "wakeup", 'w', POPT_ARG_INT
, &arg_wakup_interval_ms
, 0, "How often to break checking for signals", "milliseconds" },
144 { "user", 0, POPT_ARG_STRING
, &arg_journal_user
, 0, "Owner of journal files", "user" },
145 { "version", 'v', POPT_ARG_NONE
, &arg_version
, 0, "Display version, then exit", 0 },
146 { "xport-type", 'x', POPT_ARG_STRING
, &arg_xport
, 0, "Transport, dflt=udp", "{" ARG_UDP
", ...}" },
147 #ifdef HAVE_MONDEMAND
148 { "mondemand-host", 0, POPT_ARG_STRING
, &arg_mondemand_host
, 0, "Mondemand monitoring host", "string" },
149 { "mondemand-ip", 0, POPT_ARG_STRING
, &arg_mondemand_ip
, 0, "Mondemand monitoring ip", "ip-address" },
150 { "mondemand-port", 0, POPT_ARG_INT
, &arg_mondemand_port
, 0, "Mondemand monitoring port dflt=20402", "port" },
151 { "mondemand-program-id", 0, POPT_ARG_STRING
, &arg_mondemand_program_id
, 0, "Mondemand program id (default is 'lwes-journaller')", "program-id" },
155 { NULL
, 0, 0, NULL
, 0, NULL
, NULL
}};
161 arg_basename
= basename((char*)argv
[0]);
163 arg_basename
= (char*)argv
[0];
166 poptContext optCon
= poptGetContext(NULL
, argc
, argv
, options
, 0);
167 poptSetOtherOptionHelp(optCon
, "");
169 while ( (rc
= poptGetNextOpt(optCon
)) != -1 )
175 case POPT_ERROR_BADOPT
:
176 /* You might waht to check options of other types here... */
180 poptBadOption(optCon
, POPT_BADOPTION_NOALIAS
),
187 arg_journalls
= (char**) poptGetArgs(optCon
);
189 /* Count the journals specified on the command line. */
192 for ( arg_njournalls
=0; arg_journalls
[arg_njournalls
]; ++arg_njournalls
)
196 /* Use default journal spec if none provided on the command line. */
197 if ( 0 == arg_njournalls
)
199 static const char* default_arg_journalls
[] = { "/tmp/all_events.log.gz",
201 arg_journalls
= (char**) default_arg_journalls
;
205 /* convert the journal file username to a uid */
206 if ( arg_journal_user
!= NULL
)
208 struct passwd
*pw_entry
= getpwnam(arg_journal_user
);
211 LOG_ER("%s was told to use a file owner (%s) that could not be found\n",
212 arg_basename
, arg_journal_user
);
217 arg_journal_uid
= pw_entry
->pw_uid
;
222 /* default to the effective id of the user */
223 arg_journal_uid
= geteuid();
228 printf("The packet journaller is a program for recording LWES\n"
229 "messages for later processing.\n"
231 "It listens for UDP packets on an interface/IP address/port\n"
232 "combination and writes them to an optionally compressed\n"
233 "packet journal file.\n"
235 "It adds a 22 bytes header with the packet size and sender\n"
236 "information. See the README file for additional details.\n"
238 "The journaller looks at the \"message type\" in each received\n"
239 "packet and will rotate the logs if it matches\n"
240 "\"Command::Rotate\".\n"
244 printf("Compile time features: \n"
246 " process model(s): "
270 " scheduling type(s): FIFO "
277 printf("Bug reports to %s\n\n", PACKAGE_BUGREPORT
);
284 char log_level_string
[100];
286 log_get_mask_string(log_level_string
, sizeof(log_level_string
));
288 log_msg(LOG_INFO
, __FILE__
, __LINE__
,
290 " arg_basename == \"%s\"\n"
291 " arg_interface == \"%s\"\n"
292 " arg_ip == \"%s\"\n"
293 " arg_journ_type == \"%s\"\n"
294 " arg_pid_file == \"%s\"\n"
295 " arg_proc_type == \"%s\"\n"
296 " arg_queue_name == \"%s\"\n"
297 " arg_queue_type == \"%s\"\n"
298 " arg_xport == \"%s\"\n"
299 /*" arg_interval == %d\n"*/
300 " arg_log_level == %s (%d)\n"
301 " arg_log_file == %s\n"
302 " arg_njournalls == %d\n"
304 " arg_queue_max_cnt == %d\n"
305 " arg_queue_max_sz == %d\n"
309 " arg_journal_user == %s\n"
310 " arg_journal_uid == %d\n",
320 /*TODO: arg_interval,*/
334 for ( arg_njournalls
=0; arg_journalls
[arg_njournalls
]; ++arg_njournalls
)
336 log_msg(LOG_INFO
, __FILE__
, __LINE__
,
337 "journall[%d] == %s\n",
339 arg_journalls
[arg_njournalls
]);
344 #ifdef HAVE_MONDEMAND
345 if ( arg_mondemand_host
== NULL
346 && arg_mondemand_ip
!= NULL
)
348 /* mondemand was requested, but no hostname was specified. Choose one. */
350 if ( gethostname(host
,sizeof(host
)-1) == 0 )
352 /* this strndup is an intentional one-time memory leak. */
353 arg_mondemand_host
= strndup(host
,sizeof(host
)-1);
357 LOG_WARN("Mondemand requires a hostname, but none was provided or"
358 " available. Disabling mondemand.");
359 arg_mondemand_ip
= NULL
;
364 if ( arg_journalls
== NULL
365 || ! arg_journalls
[0]
366 || ! strrchr(arg_journalls
[0],'/') )
368 LOG_ER("%s requires output pathnames in form "
369 "'/path/to/archive/file.gz'\n", arg_basename
);
373 if (arg_journal_rotate_interval
< 0)
375 LOG_ER("--journal-rotate-interval should be positive\n");