Skip to content

Commit

Permalink
Merge pull request #48 from sysflow-telemetry/lib_fixes
Browse files Browse the repository at this point in the history
feature(libs): added better exception handling and driver detection capabilities
  • Loading branch information
araujof authored Sep 1, 2022
2 parents 93bf882 + 14dfe4d commit d606a76
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 75 deletions.
5 changes: 3 additions & 2 deletions src/collector/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,9 @@ int main(int argc, char **argv) {
delete g_driver;
delete g_config;
return ret;
} catch (sinsp_exception &ex) {
SF_ERROR(logger, "Runtime exception caught in main loop: " << ex.what());
} catch (sfexception::SysFlowException &ex) {
SF_ERROR(logger, "Runtime exception caught in main loop: "
<< ex.what() << " Error Code: " << ex.getErrorCode());
return 1;
}
}
2 changes: 1 addition & 1 deletion src/libs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ CFLAGS = -std=c++11 -Wall -I.. -I$(SFLOCALINCPREFIX)/ -I$(FSLOCALINCPREFIX)/ \
-I$(FALCOLOCALINCPREFIX)/userspace/libsinsp/ -I$(FALCOLOCALINCPREFIX)/userspace/libscap/ \
-I$(AVRLOCALINCPREFIX)/ -I/usr/local/include/ -I/usr/include/

OBJS = .sysflowlibs.o .sysflowlibs.o .MurmurHash3.o .utils.o .containercontext.o .processcontext.o .processeventprocessor.o .controlflowprocessor.o .dataflowprocessor.o .networkflowprocessor.o .fileflowprocessor.o .fileeventprocessor.o .sysflowcontext.o .sysflowprocessor.o .sysflowwriter.o .sffilewriter.o .sfsockwriter.o .sfmultiwriter.o .sfcallbackwriter.o .filecontext.o .k8scontext.o .k8seventprocessor.o .modutils.o
OBJS = .sysflowlibs.o .sysflowlibs.o .MurmurHash3.o .utils.o .containercontext.o .processcontext.o .processeventprocessor.o .controlflowprocessor.o .dataflowprocessor.o .networkflowprocessor.o .fileflowprocessor.o .fileeventprocessor.o .sysflowcontext.o .sysflowprocessor.o .sysflowwriter.o .sffilewriter.o .sfsockwriter.o .sfmultiwriter.o .sfcallbackwriter.o .filecontext.o .k8scontext.o .k8seventprocessor.o .modutils.o .sysflowexception.o

$(info MUSL is $(MUSL))
ifeq ($(MUSL), 1)
Expand Down
4 changes: 3 additions & 1 deletion src/libs/sfconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,10 @@ struct SysFlowConfig {
std::string k8sAPIURL;
// Path to K8s API Certificate (experimental).
std::string k8sAPICert;
// Run added module checks for better error checking.
bool moduleChecks;
// Consumer mode - no reads/writes/sends/recvs/closes are collected for TCP
// and file sessions
// and file sessions (not fully implemented)
bool enableConsumerMode;
// This is the dimension that a single buffer in our drivers will have. (BPF,
// kmod, modern BPF) Please note:
Expand Down
4 changes: 4 additions & 0 deletions src/libs/sysflowcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ SysFlowContext::SysFlowContext(SysFlowConfig *config)
m_statsInterval(30), m_nodeIP(), m_k8sEnabled(false),
m_probeType(NO_PROBE) {

m_config = config;
m_offline = !config->scapInputPath.empty();
if (!m_offline) {
detectProbeType();
Expand Down Expand Up @@ -187,6 +188,9 @@ string SysFlowContext::getExporterID() {
string SysFlowContext::getNodeIP() { return m_nodeIP; }

void SysFlowContext::checkModule() {
if (!m_config->moduleChecks) {
return;
}
switch (m_probeType) {
case KMOD: {
modutils::checkForFalcoKernMod();
Expand Down
55 changes: 53 additions & 2 deletions src/libs/sysflowexception.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,59 @@
**/

#include "sysflowexception.h"
#include "scap.h"

sfexception::SysFlowException::SysFlowException(std::string message) {
sfexception::SysFlowException::SysFlowException(std::string message)
: std::runtime_error(message) {
setErrorCode(message);
}
void sfexception::SysFlowException::setErrorCode(std::string message) {}

void sfexception::SysFlowException::setErrorCode(std::string message) {
m_code = LibsError;
std::size_t found = message.find("Driver supports API version");
if (found != std::string::npos) {
m_code = DriverLibsMismatch;
return;
}

found = message.find("missing api_version section");
if (found != std::string::npos) {
m_code = DriverLibsMismatch;
return;
}

found = message.find("Make sure you have root credentials and that the falco "
"module is loaded.");
if (found != std::string::npos) {
m_code = ProbeAccessDenied;
return;
}
}

sfexception::SysFlowError sfexception::getErrorCodeFromScap(int32_t ec) {
SysFlowError err = LibsError;
switch (ec) {
case SCAP_SUCCESS:
case SCAP_FAILURE:
case SCAP_TIMEOUT:
case SCAP_EOF:
break;
case SCAP_ILLEGAL_INPUT:
case SCAP_INPUT_TOO_SMALL:
case SCAP_UNEXPECTED_BLOCK:
err = EventParsingError;
break;
case SCAP_NOTFOUND:
err = ProcResourceNotFound;
break;
case SCAP_VERSION_MISMATCH:
err = DriverLibsMismatch;
break;
case SCAP_NOT_SUPPORTED:
err = OperationNotSupported;
break;
default:
break;
}
return err;
}
18 changes: 13 additions & 5 deletions src/libs/sysflowexception.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,35 @@
#include <string>

namespace sfexception {

enum SysFlowError {
LibsError,
ProbeAccessDenied,
ProbeNotExist,
ErrorReadingFileSystem,
NameTooLong,
ProbeCheckError,
ProbeNotLoaded
ProbeNotLoaded,
DriverLibsMismatch,
EventParsingError,
ProcResourceNotFound,
OperationNotSupported
};

class SysFlowException : public std::runtime_error {
private:
SysFlowError m_code;
void setErrorCode(std::string message);

public:
SysFlowException(std::string message);
SysFlowException(std::string message, SysFlowError code)
: std::runtime_error(message), m_code(code) {}
SysFlowError getErrorCode() { return m_code; }

private:
SysFlowError m_code;
void setErrorCode(std::string message);
};

SysFlowError getErrorCodeFromScap(int32_t ec);

} // namespace sfexception

#endif
26 changes: 23 additions & 3 deletions src/libs/sysflowlibs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,21 @@
**/

#include "sysflowlibs.hpp"
#include "scap_open_exception.h"
#include "sinsp_exception.h"
#include "sysflowcontext.h"
#include "sysflowprocessor.h"

using sysflowlibscpp::SysFlowDriver;

SysFlowDriver::SysFlowDriver(SysFlowConfig *conf) {
m_cxt = new context::SysFlowContext(conf);
m_processor = new sysflowprocessor::SysFlowProcessor(m_cxt, nullptr);
try {
m_cxt = new context::SysFlowContext(conf);
m_processor = new sysflowprocessor::SysFlowProcessor(m_cxt, nullptr);
} catch (const sinsp_exception &ex) {
SF_ERROR(logger, "Runtime exception on module load: " << ex.what());
throw sfexception::SysFlowException(ex.what());
}
}

SysFlowDriver::~SysFlowDriver() { delete m_processor; }
Expand All @@ -44,6 +51,7 @@ SysFlowConfig *sysflowlibscpp::InitializeSysFlowConfig() {
conf->callback = nullptr;
conf->debugMode = false;
conf->enableConsumerMode = false;
conf->moduleChecks = true;
conf->singleBufferDimension = 0;
return conf;
}
Expand All @@ -55,4 +63,16 @@ void DeleteSysFlowConfig(SysFlowConfig **conf) {

void SysFlowDriver::exit() { m_processor->exit(); }

int SysFlowDriver::run() { return m_processor->run(); }
int SysFlowDriver::run() {
try {
return m_processor->run();
} catch (const sinsp_exception &ex) {
SF_ERROR(logger, "Runtime exception caught in main loop: " << ex.what());
throw sfexception::SysFlowException(ex.what());
} catch (const avro::Exception &aex) {
SF_ERROR(logger,
"Runtime avro exception caught in main loop: " << aex.what());
throw sfexception::SysFlowException(aex.what());
}
return 0;
}
1 change: 1 addition & 0 deletions src/libs/sysflowlibs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#ifndef __SYSFLOW_LIBS_C_PLUS_PLUS_API__
#define __SYSFLOW_LIBS_C_PLUS_PLUS_API__
#include "sfconfig.h"
#include "sysflowexception.h"
#include <string>
namespace writer {
class SysFlowWriter;
Expand Down
126 changes: 65 additions & 61 deletions src/libs/sysflowprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,80 +152,84 @@ int SysFlowProcessor::run() {
int32_t res = 0;
sinsp_evt *ev = nullptr;

try {
m_writer->initialize();

while (true) {
res = m_cxt->getInspector()->next(&ev);
if (res == SCAP_TIMEOUT) {
if (m_exit) {
break;
}
checkForExpiredRecords();
m_processCxt->checkForDeletion();
checkAndRotateFile();
continue;
} else if (res == SCAP_EOF) {
break;
} else if (res != SCAP_SUCCESS) {
SF_ERROR(m_logger, "Scap processor failed with res = "
<< res << " and error: "
<< m_cxt->getInspector()->getlasterr());
throw sinsp_exception(m_cxt->getInspector()->getlasterr().c_str());
}
m_writer->initialize();

m_cxt->timeStamp = ev->get_ts();
while (true) {
res = m_cxt->getInspector()->next(&ev);
if (res == SCAP_TIMEOUT) {
if (m_exit) {
break;
}

checkForExpiredRecords();
m_processCxt->checkForDeletion();
checkAndRotateFile();
continue;
} else if (res == SCAP_EOF) {
break;
} else if (res != SCAP_SUCCESS) {
SF_ERROR(m_logger, "SCAP processor failed with res = "
<< res << " and error: "
<< m_cxt->getInspector()->getlasterr());
throw sinsp_exception(m_cxt->getInspector()->getlasterr().c_str());
}

if (m_cxt->isFilterContainers() && !utils::isInContainer(ev)) {
continue;
}
m_cxt->timeStamp = ev->get_ts();

switch (ev->get_type()) {
SF_EXECVE_ENTER()
SF_EXECVE_EXIT(ev)
SF_CLONE_EXIT(ev)
SF_PROCEXIT_E_X(ev)
SF_OPEN_EXIT(ev)
SF_ACCEPT_EXIT(ev)
SF_CONNECT_EXIT(ev)
SF_SEND_EXIT(ev)
SF_RECV_EXIT(ev)
SF_CLOSE_EXIT(ev)
SF_SETNS_EXIT(ev)
SF_MKDIR_EXIT(ev)
SF_RMDIR_EXIT(ev)
SF_LINK_EXIT(ev)
SF_UNLINK_EXIT(ev)
SF_SYMLINK_EXIT(ev)
SF_RENAME_EXIT(ev)
SF_SETUID_ENTER(ev)
SF_SETUID_EXIT(ev)
SF_SHUTDOWN_EXIT(ev)
SF_MMAP_EXIT(ev)
case PPME_K8S_E: {
if (m_cxt->isK8sEnabled()) {
m_k8sPrcr->handleK8sEvent(ev);
}
break;
}
if (m_exit) {
break;
}

checkForExpiredRecords();
m_processCxt->checkForDeletion();
checkAndRotateFile();

if (m_cxt->isFilterContainers() && !utils::isInContainer(ev)) {
continue;
}

if (m_cxt->getInspector()->m_k8s_client != nullptr &&
m_cxt->getInspector()->m_k8s_client->get_capture_events().size() > 0) {
SF_INFO(m_logger,
"Events Count: " << m_cxt->getInspector()
->m_k8s_client->get_capture_events()
.size());
}

switch (ev->get_type()) {
SF_EXECVE_ENTER()
SF_EXECVE_EXIT(ev)
SF_CLONE_EXIT(ev)
SF_PROCEXIT_E_X(ev)
SF_OPEN_EXIT(ev)
SF_ACCEPT_EXIT(ev)
SF_CONNECT_EXIT(ev)
SF_SEND_EXIT(ev)
SF_RECV_EXIT(ev)
SF_CLOSE_EXIT(ev)
SF_SETNS_EXIT(ev)
SF_MKDIR_EXIT(ev)
SF_RMDIR_EXIT(ev)
SF_LINK_EXIT(ev)
SF_UNLINK_EXIT(ev)
SF_SYMLINK_EXIT(ev)
SF_RENAME_EXIT(ev)
SF_SETUID_ENTER(ev)
SF_SETUID_EXIT(ev)
SF_SHUTDOWN_EXIT(ev)
SF_MMAP_EXIT(ev)
case PPME_K8S_E: {
if (m_cxt->isK8sEnabled()) {
m_k8sPrcr->handleK8sEvent(ev);
}
break;
}
}
SF_INFO(m_logger, "Exiting scap loop... shutting down");
printStats();
} catch (sinsp_exception &e) {
SF_ERROR(m_logger, "Sysdig exception " << e.what());
return 1;
} catch (avro::Exception &ex) {
SF_ERROR(m_logger, "Avro Exception! Error: " << ex.what());
return 1;
}

SF_INFO(m_logger, "Exiting scap loop... shutting down");
printStats();

return 0;
}

Expand Down

0 comments on commit d606a76

Please sign in to comment.