Skip to content

Commit 7ac235b

Browse files
committed
feat: add syslog filterchecks
Signed-off-by: Roberto Scolaro <[email protected]>
1 parent 594e6fe commit 7ac235b

File tree

4 files changed

+275
-0
lines changed

4 files changed

+275
-0
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#include "sinsp_filtercheck_syslog.h"
2+
#include <libsinsp/sinsp.h>
3+
#include <libsinsp/sinsp_int.h>
4+
5+
using namespace std;
6+
7+
#define RETURN_EXTRACT_VAR(x) \
8+
do { \
9+
*len = sizeof((x)); \
10+
return (uint8_t*)&(x); \
11+
} while(0)
12+
13+
#define RETURN_EXTRACT_STRING(x) \
14+
do { \
15+
*len = (x).size(); \
16+
return (uint8_t*)(x).c_str(); \
17+
} while(0)
18+
19+
#define RETURN_EXTRACT_CSTR(x) \
20+
do { \
21+
if((x)) { \
22+
*len = strlen((char*)((x))); \
23+
} \
24+
return (uint8_t*)((x)); \
25+
} while(0)
26+
27+
static const filtercheck_field_info sinsp_filter_check_syslog_fields[] = {
28+
{PT_CHARBUF, EPF_NONE, PF_NA, "syslog.facility.str", "Facility", "facility as a string."},
29+
{PT_UINT32,
30+
EPF_NONE,
31+
PF_DEC,
32+
"syslog.facility",
33+
"Numeric Facility",
34+
"facility as a number (0-23)."},
35+
{PT_CHARBUF,
36+
EPF_NONE,
37+
PF_NA,
38+
"syslog.severity.str",
39+
"Severity",
40+
"severity as a string. Can have one of these values: emerg, alert, crit, err, warn, "
41+
"notice, info, debug"},
42+
{PT_UINT32,
43+
EPF_NONE,
44+
PF_DEC,
45+
"syslog.severity",
46+
"Numeric Severity",
47+
"severity as a number (0-7)."},
48+
{PT_CHARBUF, EPF_NONE, PF_NA, "syslog.message", "Message", "message sent to syslog."},
49+
};
50+
51+
sinsp_filter_check_syslog::sinsp_filter_check_syslog(std::shared_ptr<sinsp_syslog_decoder> syslog_decoder) {
52+
static const filter_check_info s_field_infos = {
53+
"syslog",
54+
"",
55+
"Content of Syslog messages.",
56+
sizeof(sinsp_filter_check_syslog_fields) / sizeof(sinsp_filter_check_syslog_fields[0]),
57+
sinsp_filter_check_syslog_fields,
58+
filter_check_info::FL_NONE,
59+
};
60+
m_info = &s_field_infos;
61+
m_syslog_decoder = syslog_decoder;
62+
}
63+
64+
std::unique_ptr<sinsp_filter_check> sinsp_filter_check_syslog::allocate_new() {
65+
return std::make_unique<sinsp_filter_check_syslog>(m_syslog_decoder);
66+
}
67+
68+
uint8_t* sinsp_filter_check_syslog::extract_single(sinsp_evt* evt,
69+
uint32_t* len,
70+
bool sanitize_strings) {
71+
*len = 0;
72+
if(!m_syslog_decoder->is_data_valid()) {
73+
return NULL;
74+
}
75+
76+
switch(m_field_id) {
77+
case TYPE_FACILITY:
78+
m_storageu32 = m_syslog_decoder->get_facility();
79+
RETURN_EXTRACT_VAR(m_storageu32);
80+
case TYPE_FACILITY_STR:
81+
mstrstorage = m_syslog_decoder->get_facility_str();
82+
RETURN_EXTRACT_STRING(mstrstorage);
83+
case TYPE_SEVERITY:
84+
m_storageu32 = m_syslog_decoder->get_severity();
85+
RETURN_EXTRACT_VAR(m_storageu32);
86+
case TYPE_SEVERITY_STR:
87+
mstrstorage = m_syslog_decoder->get_severity_str();
88+
RETURN_EXTRACT_STRING(mstrstorage);
89+
case TYPE_MESSAGE:
90+
mstrstorage = m_syslog_decoder->get_msg();
91+
RETURN_EXTRACT_STRING(mstrstorage);
92+
default:
93+
ASSERT(false);
94+
return NULL;
95+
}
96+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#pragma once
2+
3+
#include <libsinsp/sinsp_filtercheck.h>
4+
#include "../utils/sinsp_syslog.h"
5+
6+
class sinsp_filter_check_syslog : public sinsp_filter_check {
7+
public:
8+
enum check_type {
9+
TYPE_FACILITY_STR = 0,
10+
TYPE_FACILITY,
11+
TYPE_SEVERITY_STR,
12+
TYPE_SEVERITY,
13+
TYPE_MESSAGE,
14+
};
15+
16+
sinsp_filter_check_syslog(std::shared_ptr<sinsp_syslog_decoder> syslog_decoder);
17+
virtual ~sinsp_filter_check_syslog() = default;
18+
19+
std::unique_ptr<sinsp_filter_check> allocate_new() override;
20+
21+
protected:
22+
uint8_t* extract_single(sinsp_evt*, uint32_t* len, bool sanitize_strings = true) override;
23+
24+
private:
25+
uint32_t m_storageu32;
26+
std::string mstrstorage;
27+
std::shared_ptr<sinsp_syslog_decoder> m_syslog_decoder;
28+
};
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#include "sinsp_syslog.h"
2+
#include <libsinsp/utils.h>
3+
4+
#define PRI_BUF_SIZE 16
5+
6+
static const std::string s_syslog_severity_strings[] =
7+
{"emerg", "alert", "crit", "err", "warn", "notice", "info", "debug"};
8+
9+
static const std::string s_syslog_facility_strings[] = {
10+
"kern", "user", "mail", "daemon", "auth", "syslog", "lpr", "news",
11+
"uucp", "clock", "authpriv", "ftp", "ntp", "logaudit", "logalert", "cron",
12+
"local0", "local1", "local2", "local3", "local4", "local5", "local6", "local7"};
13+
14+
void sinsp_syslog_decoder::parse_data(const char* data, uint32_t len) {
15+
char pri[PRI_BUF_SIZE];
16+
const char* tc = data + 1;
17+
const char* te = data + len;
18+
uint32_t j = 0;
19+
20+
while(tc < te && *tc != '>' && *tc != '\0' && j < PRI_BUF_SIZE - 1) {
21+
pri[j++] = *tc;
22+
tc++;
23+
}
24+
25+
pri[j] = 0;
26+
27+
decode_message(data, len, pri, j);
28+
}
29+
30+
std::string sinsp_syslog_decoder::get_severity_str() const {
31+
if(!is_data_valid() ||
32+
m_severity >= sizeof(s_syslog_severity_strings) / sizeof(s_syslog_severity_strings[0])) {
33+
return "<NA>";
34+
} else {
35+
return s_syslog_severity_strings[m_severity];
36+
}
37+
}
38+
39+
std::string sinsp_syslog_decoder::get_facility_str() const {
40+
if(!is_data_valid() ||
41+
m_facility >= sizeof(s_syslog_facility_strings) / sizeof(s_syslog_facility_strings[0])) {
42+
return "<NA>";
43+
} else {
44+
return s_syslog_facility_strings[m_facility];
45+
}
46+
}
47+
48+
void sinsp_syslog_decoder::decode_message(const char* data,
49+
uint32_t len,
50+
char* pristr,
51+
uint32_t pristrlen) {
52+
if(len < pristrlen + 2 || pristrlen == 0) {
53+
m_priority = s_invalid_priority;
54+
return;
55+
}
56+
57+
bool res = sinsp_numparser::tryparsed32_fast(pristr, pristrlen, &m_priority);
58+
59+
if(!res) {
60+
m_priority = s_invalid_priority;
61+
return;
62+
}
63+
64+
m_severity = m_priority & 0x07;
65+
m_facility = m_priority >> 3;
66+
67+
m_msg.assign(data + pristrlen + 2, len - pristrlen - 2);
68+
}
69+
70+
std::string sinsp_syslog_decoder::get_info_line() const {
71+
if(!is_data_valid()) {
72+
return "<NA>";
73+
}
74+
75+
return "syslog sev=" + get_severity_str() + " msg=" + m_msg;
76+
}
77+
78+
void sinsp_syslog_decoder::parse(sinsp_evt* evt) {
79+
if(!evt || !evt->get_fd_info()) {
80+
return;
81+
}
82+
83+
// Check if this is a syslog fd
84+
if(!evt->get_fd_info()->is_syslog()) {
85+
return;
86+
}
87+
88+
// Extract the data buffer based on event type
89+
uint16_t etype = evt->get_type();
90+
const sinsp_evt_param* parinfo = nullptr;
91+
92+
// Determine which parameter contains the data based on event type
93+
if(etype == PPME_SOCKET_SENDMMSG_X) {
94+
parinfo = evt->get_param(2);
95+
} else if(etype == PPME_SYSCALL_READV_X || etype == PPME_SYSCALL_PREADV_X ||
96+
etype == PPME_SOCKET_RECVMSG_X) {
97+
parinfo = evt->get_param(2);
98+
} else if(etype == PPME_SOCKET_RECVMMSG_X) {
99+
parinfo = evt->get_param(3);
100+
} else {
101+
parinfo = evt->get_param(1);
102+
}
103+
104+
if(parinfo) {
105+
const char* data = parinfo->m_val;
106+
uint32_t datalen = parinfo->m_len;
107+
parse_data(data, datalen);
108+
}
109+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#pragma once
2+
3+
#include <libsinsp/sinsp.h>
4+
#include <libsinsp/sinsp_exception.h>
5+
6+
#include <stdint.h>
7+
#include <string>
8+
#include <memory>
9+
10+
class sinsp_syslog_decoder {
11+
public:
12+
void parse_data(const char* data, uint32_t len);
13+
14+
std::string get_info_line() const;
15+
std::string get_severity_str() const;
16+
std::string get_facility_str() const;
17+
18+
inline void reset() { m_priority = s_invalid_priority; }
19+
20+
bool is_data_valid() const { return m_priority != s_invalid_priority; }
21+
22+
inline int32_t get_priority() const { return m_priority; }
23+
24+
inline uint32_t get_facility() const { return m_facility; }
25+
26+
inline uint32_t get_severity() const { return m_severity; }
27+
28+
inline const std::string& get_msg() const { return m_msg; }
29+
30+
void parse(sinsp_evt* evt);
31+
32+
private:
33+
void decode_message(const char* data, uint32_t len, char* pristr, uint32_t pristrlen);
34+
35+
int32_t m_priority{s_invalid_priority};
36+
uint32_t m_facility{0};
37+
uint32_t m_severity{0};
38+
std::string m_msg;
39+
std::string m_infostr;
40+
41+
static constexpr const int32_t s_invalid_priority = -1;
42+
};

0 commit comments

Comments
 (0)