Skip to content

Commit 22c0d03

Browse files
committed
log from named pipe
1 parent ad8f7d1 commit 22c0d03

2 files changed

Lines changed: 107 additions & 17 deletions

File tree

doc/releaseNotes.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,6 @@ This file describes the main feature changes for each InfoLogger released versio
100100

101101
## v2.1.1 - 28/06/2021
102102
- minor cosmetics for auto-mute feature.
103+
104+
## next version
105+
- Added option for o2-infologger-log to collect logs from a named pipe (multiple clients possible). Pipe can be created and listened to continuously. e.g. `o2-infologger-log -f /tmp/log-pipe -c -l `.

src/log.cxx

Lines changed: 104 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <sys/types.h>
2525
#include <dirent.h>
2626
#include <sys/stat.h>
27+
#include <fcntl.h>
28+
#include <errno.h>
2729

2830
using namespace AliceO2::InfoLogger;
2931

@@ -34,8 +36,12 @@ void print_usage()
3436
printf("Options: \n");
3537
printf(" -s [severity] Possible values: Info (default), Error, Fatal, Warning, Debug.\n");
3638
printf(" -o[key]=[value] Set a message field. Valid keys: context (Facility, Role, System, Detector, Partition, Run) and message options (Severity, Level, ErrorCode, SourceFile, SourceLine).\n");
37-
printf(" -x If set, reads data coming on stdin line by line.\n");
39+
printf(" -x If set, read data coming on stdin line by line.\n");
3840
printf(" and transmit them as messages (1 line = 1 message).\n");
41+
printf(" -f [file] Same as -x, but from a file.\n");
42+
printf(" -c When -f selected, create a FIFO (mkfifo) to read from.\n");
43+
printf(" -l When -f selected, loop over file continuously.\n");
44+
printf(" -v Verbose mode (file operations, etc).\n");
3945
printf(" -h This help.\n");
4046
}
4147

@@ -145,7 +151,12 @@ pid_t findPipeProcess()
145151
int main(int argc, char** argv)
146152
{
147153

148-
int optFromStdin = 0; // 1 if logging from stdin, 0 when taking input from command line
154+
int optFromFile = 0; // 1 if logging from a file (stdin or pipe), 0 when taking input from command line
155+
int inputFd = -1; // file descriptor used for input, if any
156+
std::string inputPath = ""; // path to file to read from, if any
157+
bool createFifo = 0; // if set, create a FIFO
158+
bool loopInput = 0; // if set, loop on file (useful for fifo mode)
159+
bool verbose = 0; // if set, prints messages about file operations
149160

150161
InfoLogger::InfoLoggerMessageOption msgOptions = InfoLogger::undefinedMessageOption;
151162
msgOptions.severity = InfoLogger::Severity::Info;
@@ -157,7 +168,7 @@ int main(int argc, char** argv)
157168
char option;
158169

159170
// read options
160-
while ((option = getopt(argc, argv, "s:xo:h")) != -1) {
171+
while ((option = getopt(argc, argv, "s:xo:hf:clv")) != -1) {
161172
switch (option) {
162173

163174
case 's': {
@@ -171,7 +182,8 @@ int main(int argc, char** argv)
171182
} break;
172183

173184
case 'x': {
174-
optFromStdin = 1;
185+
optFromFile = 1;
186+
inputFd = fileno(stdin);
175187
// try to find process sending messages to stdin
176188
pid_t pid = findPipeProcess();
177189
if (pid != 0) {
@@ -193,6 +205,23 @@ int main(int argc, char** argv)
193205
break;
194206
*/
195207

208+
case 'c': {
209+
createFifo = 1;
210+
} break;
211+
212+
case 'l': {
213+
loopInput = 1;
214+
} break;
215+
216+
case 'v': {
217+
verbose = 1;
218+
} break;
219+
220+
case 'f': {
221+
inputPath = optarg;
222+
optFromFile = 1;
223+
} break;
224+
196225
case 'h':
197226
print_usage();
198227
return 0;
@@ -221,25 +250,83 @@ int main(int argc, char** argv)
221250

222251
// todo: catch exceptions
223252

224-
// also read from stdin if option set */
225-
if (optFromStdin) {
226-
LineBuffer lb; // buffer for input lines
227-
std::string msg;
228-
int eof;
253+
// also read from file if option set */
254+
if (optFromFile) {
255+
256+
if (createFifo) {
257+
bool isOk = 0;
258+
int err = 0;
259+
if (mkfifo(inputPath.c_str(), 0666)) {
260+
err = errno;
261+
if (err == EEXIST) {
262+
// is the existing file a fifo ?
263+
struct stat statbuf;
264+
if (stat(inputPath.c_str(), &statbuf) == 0) {
265+
if (S_ISFIFO(statbuf.st_mode)) {
266+
// the FIFO already exists
267+
isOk = 1;
268+
}
269+
}
270+
}
271+
} else {
272+
if (verbose) printf("FIFO %s created\n", inputPath.c_str());
273+
isOk = 1;
274+
}
275+
if (!isOk) {
276+
printf("Failed to create FIFO %s : %s\n", inputPath.c_str(), strerror(err));
277+
return -1;
278+
}
279+
}
229280

230-
// read lines from stdin until EOF, and send them as log messages
231281
for (;;) {
232-
eof = lb.appendFromFileDescriptor(fileno(stdin), -1);
282+
283+
if (inputFd < 0) {
284+
inputFd = open(inputPath.c_str(), O_RDONLY);
285+
if (inputFd < 0) {
286+
printf("Failed to open %s : %s\n", inputPath.c_str(), strerror(errno));
287+
return -1;
288+
}
289+
if (verbose) printf("Input file opened = %d\n",inputFd);
290+
}
291+
292+
LineBuffer lb; // buffer for input lines
293+
std::string msg;
294+
int eof;
295+
296+
// read lines from stdin until EOF, and send them as log messages
233297
for (;;) {
234-
if (lb.getNextLine(msg)) {
235-
// no line left
298+
eof = lb.appendFromFileDescriptor(inputFd, -1);
299+
for (;;) {
300+
if (lb.getNextLine(msg)) {
301+
// no line left
302+
break;
303+
}
304+
//infoLogger_msg_xt(UNDEFINED_STRING,UNDEFINED_INT,UNDEFINED_INT,facility,severity,level,msg);
305+
theLog->log(msgOptions, msgContext, "%s", msg.c_str());
306+
}
307+
if (eof)
236308
break;
237-
}
238-
//infoLogger_msg_xt(UNDEFINED_STRING,UNDEFINED_INT,UNDEFINED_INT,facility,severity,level,msg);
239-
theLog->log(msgOptions, msgContext, "%s", msg.c_str());
240309
}
241-
if (eof)
310+
311+
if (inputFd>0) {
312+
if (verbose) printf("Input file closed\n");
313+
close(inputFd);
314+
inputFd = -1;
315+
}
316+
317+
if (!loopInput) {
242318
break;
319+
}
320+
}
321+
322+
}
323+
324+
// remove fifo after use
325+
if (createFifo) {
326+
if (unlink(inputPath.c_str())) {
327+
printf("Failed to remove %s\n", inputPath.c_str());
328+
} else {
329+
if (verbose) printf("FIFO %s removed\n", inputPath.c_str());
243330
}
244331
}
245332

0 commit comments

Comments
 (0)