Skip to content

Commit

Permalink
Merge pull request #1780 from sempervictus/feature/reader_multi-line_…
Browse files Browse the repository at this point in the history
…indented

Implement multi-line collection for indented logs
  • Loading branch information
ddpbsd authored Nov 2, 2019
2 parents a973a7e + 067c71d commit f55bac0
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/config/localfile-config.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ int Read_Localfile(XML_NODE node, void *d1, __attribute__((unused)) void *d2)
} else if (strcmp(logf[pl].logformat, "command") == 0) {
} else if (strcmp(logf[pl].logformat, "full_command") == 0) {
} else if (strcmp(logf[pl].logformat, "audit") == 0) {
} else if (strcmp(logf[pl].logformat, "multi-line_indented") == 0) {
} else if (strncmp(logf[pl].logformat, "multi-line", 10) == 0) {
int x = 0;
logf[pl].logformat += 10;
Expand Down
5 changes: 3 additions & 2 deletions src/logcollector/logcollector.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ void LogCollectorStart()
logff[i].read = read_multiline;
} else if (strcmp("audit", logff[i].logformat) == 0) {
logff[i].read = read_audit;
} else if (strcmp("multi-line_indented", logff[i].logformat) == 0) {
logff[i].read = read_multiline_indented;
} else {
logff[i].read = read_syslog;
}
Expand Down Expand Up @@ -395,7 +397,7 @@ void LogCollectorStart()
#ifndef WIN32

/* To help detect a file rollover, temporarily open the file a second time.
* Previously the fstat would work on "cached" file data, but this should
* Previously the fstat would work on "cached" file data, but this should
* ensure it's fresh when hardlinks are used (like alerts.log).
*/
FILE *tf;
Expand Down Expand Up @@ -713,4 +715,3 @@ void win_format_event_string(char *string)
}

#endif /* WIN32 */

4 changes: 3 additions & 1 deletion src/logcollector/logcollector.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ void *read_postgresql_log(int pos, int *rc, int drop_it);
/* read multi line logs */
void *read_multiline(int pos, int *rc, int drop_it);

/* read indented multi line logs */
void *read_multiline_indented(int pos, int *rc, int drop_it);

/* Read DJB multilog format */
/* Initializes multilog */
int init_djbmultilog(int pos);
Expand Down Expand Up @@ -80,4 +83,3 @@ extern int open_file_attempts;
extern logreader *logff;

#endif /* __LOGREADER_H */

120 changes: 120 additions & 0 deletions src/logcollector/read_multiline_indented.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/* Copyright (C) 2019, Semper Victus LLC
* Copyright (C) 2009 Trend Micro Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public
* License (version 2) as published by the FSF - Free Software
* Foundation.
*/

/* Read indentend multi line logs */

#include "shared.h"
#include "logcollector.h"


/* Read multi line indented log files */
void *read_multiline_indented(int pos, int *rc, int drop_it) {
size_t str_len = 0;
char *p;
char str[OS_MAXSTR + 1];
char buffer[OS_MAXSTR + 1];
/* Zero buffer and str */
buffer[0] = '\0';
buffer[OS_MAXSTR] = '\0';
str[OS_MAXSTR] = '\0';
*rc = 0;

/* Get new entry */
while (fgets(str, OS_MAXSTR - OS_LOG_HEADER, logff[pos].fp) != NULL) {

/* Get buffer size */
str_len = strlen(str);

/* Check str_len size. Very useless, but just to make sure.. */
if (str_len >= sizeof(buffer) - 2) {
str_len = sizeof(buffer) - 10;
}

/* Get the last occurrence of \n */
if ((p = strrchr(str, '\n')) != NULL) {
*p = '\0';
}

#ifdef WIN32
if ((p = strrchr(str, '\r')) != NULL) {
*p = '\0';
}
#endif
/* Look for empty string */
if ((str_len <= 1) || (str[0] == '\r')) {
/* Send existing data if any in buffer */
if (buffer[0] != '\0') {
if (drop_it == 0 && SendMSG(logr_queue, buffer, logff[pos].file, LOCALFILE_MQ) < 0) {
merror(QUEUE_SEND, ARGV0);
if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) {
ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH);
}
}
buffer[0] = '\0';
}
continue;
}

/* Look for lines starting with indents */
if ((str_len > 2) && (buffer[0] != '\0') &&
((str[0] == ' ') || (str[0] == '\t'))) {
/* Size of the buffer */
size_t buffer_len = strlen(buffer);

p = str + 1;

/* Remove extra spaces and tabs */
while (*p == ' ' || *p == '\t') {
p++;
}

/* Add additional message to the saved buffer */
if (sizeof(buffer) - buffer_len > str_len + 256) {
/* Here we make sure that the size of the buffer
* minus what was used (strlen) is greater than
* the length of the received message.
*/
buffer[buffer_len] = ' ';
buffer[buffer_len + 1] = '\0';
strncat(buffer, str, str_len + 3);
}
/* Look for lines not starting with indents */
} else if ((str[0] != ' ') || (str[0] != '\t')) {
/* Flush previous messages */
if (buffer[0] != '\0') {
if (drop_it == 0 && SendMSG(logr_queue, buffer, logff[pos].file, LOCALFILE_MQ) < 0) {
merror(QUEUE_SEND, ARGV0);
if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) {
ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH);
}
}
buffer[0] = '\0';
}
strncpy(buffer, str, str_len + 2);
continue;
/* Error handling for buffer[0] being '\0' when indents are present */
} else {
// messages or retries
}

}

/* Send whatever is stored */
if (buffer[0] != '\0') {
if (drop_it == 0 && SendMSG(logr_queue, buffer, logff[pos].file, LOCALFILE_MQ) < 0) {
merror(QUEUE_SEND, ARGV0);
if ((logr_queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) {
ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH);
}
}
}

return (NULL);
}

0 comments on commit f55bac0

Please sign in to comment.