diff --git a/extensions/windows-event-log/ConsumeWindowsEventLog.cpp b/extensions/windows-event-log/ConsumeWindowsEventLog.cpp index 9c23fe65ae..b2a2259b19 100644 --- a/extensions/windows-event-log/ConsumeWindowsEventLog.cpp +++ b/extensions/windows-event-log/ConsumeWindowsEventLog.cpp @@ -100,9 +100,9 @@ void ConsumeWindowsEventLog::initialize() { } bool ConsumeWindowsEventLog::insertHeaderName(wel::METADATA_NAMES &header, const std::string &key, const std::string & value) { - wel::METADATA name = wel::WindowsEventLogMetadata::getMetadataFromString(key); + wel::Metadata name = wel::WindowsEventLogMetadata::getMetadataFromString(key); - if (name != wel::METADATA::UNKNOWN) { + if (name != wel::Metadata::UNKNOWN) { header.emplace_back(std::make_pair(name, value)); return true; } @@ -488,7 +488,7 @@ nonstd::expected ConsumeWindowsEventLog::createE std::string_view payload_name = event_message ? "Message" : "Error"; wel::WindowsEventLogHeader log_header(header_names_, header_delimiter_, payload_name.size()); - result.plaintext = log_header.getEventHeader([&walker](wel::METADATA metadata) { return walker.getMetadata(metadata); }); + result.plaintext = log_header.getEventHeader([&walker](wel::Metadata metadata) { return walker.getMetadata(metadata); }); result.plaintext += payload_name; result.plaintext += log_header.getDelimiterFor(payload_name.size()); result.plaintext += event_message.has_value() ? *event_message : event_message.error().message(); diff --git a/extensions/windows-event-log/tests/MetadataWalkerTests.cpp b/extensions/windows-event-log/tests/MetadataWalkerTests.cpp index 300b8009a6..2a261fa39b 100644 --- a/extensions/windows-event-log/tests/MetadataWalkerTests.cpp +++ b/extensions/windows-event-log/tests/MetadataWalkerTests.cpp @@ -27,7 +27,7 @@ #include "wel/XMLString.h" #include "pugixml.hpp" -using METADATA = org::apache::nifi::minifi::wel::METADATA; +using Metadata = org::apache::nifi::minifi::wel::Metadata; using MetadataWalker = org::apache::nifi::minifi::wel::MetadataWalker; using WindowsEventLogMetadata = org::apache::nifi::minifi::wel::WindowsEventLogMetadata; using WindowsEventLogMetadataImpl = org::apache::nifi::minifi::wel::WindowsEventLogMetadataImpl; @@ -74,7 +74,7 @@ const short event_type_index = 178; // NOLINT short comes from WINDOWS API class FakeWindowsEventLogMetadata : public WindowsEventLogMetadata { public: - [[nodiscard]] std::string getEventData(EVT_FORMAT_MESSAGE_FLAGS flags) const override { return "event_data_for_flag_" + std::to_string(flags); } + [[nodiscard]] nonstd::expected getEventData(EVT_FORMAT_MESSAGE_FLAGS flags) const noexcept override { return "event_data_for_flag_" + std::to_string(flags); } [[nodiscard]] std::string getEventTimestamp() const override { return "event_timestamp"; } short getEventTypeIndex() const override { return event_type_index; } // NOLINT short comes from WINDOWS API }; @@ -149,7 +149,7 @@ void extractMappingsTestHelper(const std::string &file_name, bool update_xml, bool resolve, const std::map& expected_identifiers, - const std::map& expected_metadata, + const std::map& expected_metadata, const std::map& expected_field_values) { std::string input_xml = readFile(file_name); REQUIRE(!input_xml.empty()); @@ -175,12 +175,12 @@ TEST_CASE("MetadataWalker extracts mappings correctly when there is a single Sid const std::map expected_identifiers{{"S-1-0-0", "S-1-0-0"}}; - using org::apache::nifi::minifi::wel::METADATA; - const std::map expected_metadata{ - {METADATA::SOURCE, "Microsoft-Windows-Security-Auditing"}, - {METADATA::TIME_CREATED, "event_timestamp"}, - {METADATA::EVENTID, "4672"}, - {METADATA::EVENT_RECORDID, "2575952"}}; + using org::apache::nifi::minifi::wel::Metadata; + const std::map expected_metadata{ + {Metadata::SOURCE, "Microsoft-Windows-Security-Auditing"}, + {Metadata::TIME_CREATED, "event_timestamp"}, + {Metadata::EVENTID, "4672"}, + {Metadata::EVENT_RECORDID, "2575952"}}; const std::map expected_field_values{}; @@ -198,18 +198,18 @@ TEST_CASE("MetadataWalker extracts mappings correctly when there is a single Sid const std::map expected_identifiers{{"S-1-0-0", "Nobody"}}; - using org::apache::nifi::minifi::wel::METADATA; - const std::map expected_metadata{ - {METADATA::LOG_NAME, "MetadataWalkerTests"}, - {METADATA::SOURCE, "Microsoft-Windows-Security-Auditing"}, - {METADATA::TIME_CREATED, "event_timestamp"}, - {METADATA::EVENTID, "4672"}, - {METADATA::OPCODE, "event_data_for_flag_4"}, - {METADATA::EVENT_RECORDID, "2575952"}, - {METADATA::EVENT_TYPE, "178"}, - {METADATA::TASK_CATEGORY, "event_data_for_flag_3"}, - {METADATA::LEVEL, "event_data_for_flag_2"}, - {METADATA::KEYWORDS, "event_data_for_flag_5"}}; + using org::apache::nifi::minifi::wel::Metadata; + const std::map expected_metadata{ + {Metadata::LOG_NAME, "MetadataWalkerTests"}, + {Metadata::SOURCE, "Microsoft-Windows-Security-Auditing"}, + {Metadata::TIME_CREATED, "event_timestamp"}, + {Metadata::EVENTID, "4672"}, + {Metadata::OPCODE, "event_data_for_flag_4"}, + {Metadata::EVENT_RECORDID, "2575952"}, + {Metadata::EVENT_TYPE, "178"}, + {Metadata::TASK_CATEGORY, "event_data_for_flag_3"}, + {Metadata::LEVEL, "event_data_for_flag_2"}, + {Metadata::KEYWORDS, "event_data_for_flag_5"}}; SECTION("update_xml is false => fields are collected into walker.getFieldValues()") { const std::map expected_field_values{ @@ -235,12 +235,12 @@ TEST_CASE("MetadataWalker extracts mappings correctly when there are multiple Si const std::map expected_identifiers{{"S-1-0-0", "S-1-0-0"}}; - using org::apache::nifi::minifi::wel::METADATA; - const std::map expected_metadata{ - {METADATA::SOURCE, "Microsoft-Windows-Security-Auditing"}, - {METADATA::TIME_CREATED, "event_timestamp"}, - {METADATA::EVENTID, "4672"}, - {METADATA::EVENT_RECORDID, "2575952"}}; + using org::apache::nifi::minifi::wel::Metadata; + const std::map expected_metadata{ + {Metadata::SOURCE, "Microsoft-Windows-Security-Auditing"}, + {Metadata::TIME_CREATED, "event_timestamp"}, + {Metadata::EVENTID, "4672"}, + {Metadata::EVENT_RECORDID, "2575952"}}; const std::map expected_field_values{}; @@ -264,18 +264,18 @@ TEST_CASE("MetadataWalker extracts mappings correctly when there are multiple Si {"S-1-0-0", "Nobody"}, {"S-1-1-0", "Everyone"}}; - using org::apache::nifi::minifi::wel::METADATA; - const std::map expected_metadata{ - {METADATA::LOG_NAME, "MetadataWalkerTests"}, - {METADATA::SOURCE, "Microsoft-Windows-Security-Auditing"}, - {METADATA::TIME_CREATED, "event_timestamp"}, - {METADATA::EVENTID, "4672"}, - {METADATA::OPCODE, "event_data_for_flag_4"}, - {METADATA::EVENT_RECORDID, "2575952"}, - {METADATA::EVENT_TYPE, "178"}, - {METADATA::TASK_CATEGORY, "event_data_for_flag_3"}, - {METADATA::LEVEL, "event_data_for_flag_2"}, - {METADATA::KEYWORDS, "event_data_for_flag_5"}}; + using org::apache::nifi::minifi::wel::Metadata; + const std::map expected_metadata{ + {Metadata::LOG_NAME, "MetadataWalkerTests"}, + {Metadata::SOURCE, "Microsoft-Windows-Security-Auditing"}, + {Metadata::TIME_CREATED, "event_timestamp"}, + {Metadata::EVENTID, "4672"}, + {Metadata::OPCODE, "event_data_for_flag_4"}, + {Metadata::EVENT_RECORDID, "2575952"}, + {Metadata::EVENT_TYPE, "178"}, + {Metadata::TASK_CATEGORY, "event_data_for_flag_3"}, + {Metadata::LEVEL, "event_data_for_flag_2"}, + {Metadata::KEYWORDS, "event_data_for_flag_5"}}; SECTION("update_xml is false => fields are collected into walker.getFieldValues()") { const std::map expected_field_values{ @@ -301,12 +301,12 @@ TEST_CASE("MetadataWalker extracts mappings correctly when the Sid is unknown an const std::map expected_identifiers{{"S-1-8-6-5-3-0-9", "S-1-8-6-5-3-0-9"}}; - using org::apache::nifi::minifi::wel::METADATA; - const std::map expected_metadata{ - {METADATA::SOURCE, "Microsoft-Windows-Security-Auditing"}, - {METADATA::TIME_CREATED, "event_timestamp"}, - {METADATA::EVENTID, "4672"}, - {METADATA::EVENT_RECORDID, "2575952"}}; + using org::apache::nifi::minifi::wel::Metadata; + const std::map expected_metadata{ + {Metadata::SOURCE, "Microsoft-Windows-Security-Auditing"}, + {Metadata::TIME_CREATED, "event_timestamp"}, + {Metadata::EVENTID, "4672"}, + {Metadata::EVENT_RECORDID, "2575952"}}; const std::map expected_field_values{}; @@ -324,18 +324,18 @@ TEST_CASE("MetadataWalker extracts mappings correctly when the Sid is unknown an const std::map expected_identifiers{{"S-1-8-6-5-3-0-9", "S-1-8-6-5-3-0-9"}}; - using org::apache::nifi::minifi::wel::METADATA; - const std::map expected_metadata{ - {METADATA::LOG_NAME, "MetadataWalkerTests"}, - {METADATA::SOURCE, "Microsoft-Windows-Security-Auditing"}, - {METADATA::TIME_CREATED, "event_timestamp"}, - {METADATA::EVENTID, "4672"}, - {METADATA::OPCODE, "event_data_for_flag_4"}, - {METADATA::EVENT_RECORDID, "2575952"}, - {METADATA::EVENT_TYPE, "178"}, - {METADATA::TASK_CATEGORY, "event_data_for_flag_3"}, - {METADATA::LEVEL, "event_data_for_flag_2"}, - {METADATA::KEYWORDS, "event_data_for_flag_5"}}; + using org::apache::nifi::minifi::wel::Metadata; + const std::map expected_metadata{ + {Metadata::LOG_NAME, "MetadataWalkerTests"}, + {Metadata::SOURCE, "Microsoft-Windows-Security-Auditing"}, + {Metadata::TIME_CREATED, "event_timestamp"}, + {Metadata::EVENTID, "4672"}, + {Metadata::OPCODE, "event_data_for_flag_4"}, + {Metadata::EVENT_RECORDID, "2575952"}, + {Metadata::EVENT_TYPE, "178"}, + {Metadata::TASK_CATEGORY, "event_data_for_flag_3"}, + {Metadata::LEVEL, "event_data_for_flag_2"}, + {Metadata::KEYWORDS, "event_data_for_flag_5"}}; SECTION("update_xml is false => fields are collected into walker.getFieldValues()") { const std::map expected_field_values{ diff --git a/extensions/windows-event-log/wel/MetadataWalker.cpp b/extensions/windows-event-log/wel/MetadataWalker.cpp index c8ba37e92c..114f390a31 100644 --- a/extensions/windows-event-log/wel/MetadataWalker.cpp +++ b/extensions/windows-event-log/wel/MetadataWalker.cpp @@ -16,12 +16,8 @@ * limitations under the License. */ -#include - #include #include -#include -#include #include #include #include @@ -90,10 +86,11 @@ bool MetadataWalker::for_each(pugi::xml_node &node) { if (it != formatFlagMap.end()) { std::function updateFunc = [&](const std::string &input) -> std::string { if (resolve_) { - auto resolved = windows_event_log_metadata_.getEventData(it->second); - if (!resolved.empty()) { - return resolved; + const auto resolved = windows_event_log_metadata_.getEventData(it->second); + if (resolved && !resolved->empty()) { + return *resolved; } + // TODO(szaszm): add error logging } return input; }; @@ -123,40 +120,25 @@ std::vector MetadataWalker::getIdentifiers(const std::string &text) return found_strings; } -std::string MetadataWalker::getMetadata(METADATA metadata) const { - switch (metadata) { - case LOG_NAME: - return log_name_; - case SOURCE: - return getString(metadata_, "Provider"); - case TIME_CREATED: - return windows_event_log_metadata_.getEventTimestamp(); - case EVENTID: - return getString(metadata_, "EventID"); - case EVENT_RECORDID: - return getString(metadata_, "EventRecordID"); - case OPCODE: - return getString(metadata_, "Opcode"); - case TASK_CATEGORY: - return getString(metadata_, "Task"); - case LEVEL: - return getString(metadata_, "Level"); - case KEYWORDS: - return getString(metadata_, "Keywords"); - case EVENT_TYPE: - return std::to_string(windows_event_log_metadata_.getEventTypeIndex()); - case COMPUTER: - return WindowsEventLogMetadata::getComputerName(); - } - return "N/A"; -} - -std::map MetadataWalker::getFieldValues() const { - return fields_values_; -} - -std::map MetadataWalker::getIdentifiers() const { - return replaced_identifiers_; +std::string MetadataWalker::getMetadata(Metadata metadata) const { + using enum Metadata; + switch (metadata) { + case LOG_NAME: return log_name_; + case SOURCE: return getString(metadata_, "Provider"); + case TIME_CREATED: return windows_event_log_metadata_.getEventTimestamp(); + case EVENTID: return getString(metadata_, "EventID"); + case EVENT_RECORDID: return getString(metadata_, "EventRecordID"); + case OPCODE: return getString(metadata_, "Opcode"); + case TASK_CATEGORY: return getString(metadata_, "Task"); + case LEVEL: return getString(metadata_, "Level"); + case KEYWORDS: return getString(metadata_, "Keywords"); + case EVENT_TYPE: return std::to_string(windows_event_log_metadata_.getEventTypeIndex()); + case COMPUTER: return WindowsEventLogMetadata::getComputerName(); + case USER: // TODO(szaszm): unhandled before refactoring + case UNKNOWN: // TODO(szaszm): unhandled before refactoring + ; + } + return "N/A"; } template diff --git a/extensions/windows-event-log/wel/MetadataWalker.h b/extensions/windows-event-log/wel/MetadataWalker.h index 869e254f1f..bbae637d2f 100644 --- a/extensions/windows-event-log/wel/MetadataWalker.h +++ b/extensions/windows-event-log/wel/MetadataWalker.h @@ -22,14 +22,12 @@ #include #include -#include #include #include -#include #include #include -#include #include +#include #include "core/Core.h" #include "core/Processor.h" @@ -37,7 +35,6 @@ #include "FlowFileRecord.h" #include "WindowsEventLog.h" -#include "concurrentqueue.h" #include "pugixml.hpp" #include "utils/RegexUtils.h" @@ -45,7 +42,6 @@ namespace org::apache::nifi::minifi::wel { /** * Defines a tree walker for the XML input - * */ class MetadataWalker : public pugi::xml_tree_walker { public: @@ -65,11 +61,9 @@ class MetadataWalker : public pugi::xml_tree_walker { */ bool for_each(pugi::xml_node &node) override; - [[nodiscard]] std::map getFieldValues() const; - - [[nodiscard]] std::map getIdentifiers() const; - - [[nodiscard]] std::string getMetadata(METADATA metadata) const; + [[nodiscard]] std::map getFieldValues() const { return fields_values_; } + [[nodiscard]] std::map getIdentifiers() const { return replaced_identifiers_; } + [[nodiscard]] std::string getMetadata(Metadata metadata) const; private: static std::vector getIdentifiers(const std::string &text); diff --git a/extensions/windows-event-log/wel/WindowsEventLog.cpp b/extensions/windows-event-log/wel/WindowsEventLog.cpp index 0140ee7077..3a9129db30 100644 --- a/extensions/windows-event-log/wel/WindowsEventLog.cpp +++ b/extensions/windows-event-log/wel/WindowsEventLog.cpp @@ -108,69 +108,57 @@ void WindowsEventLogMetadataImpl::renderMetadata() { } } -std::string WindowsEventLogMetadataImpl::getEventData(EVT_FORMAT_MESSAGE_FLAGS flags) const { - WCHAR stack_buffer[4096]; - DWORD num_chars_in_buffer = sizeof(stack_buffer) / sizeof(stack_buffer[0]); - using Deleter = utils::StackAwareDeleter; - std::unique_ptr buffer{stack_buffer, Deleter{stack_buffer}}; - DWORD num_chars_used = 0; - - std::string event_data; - - if (!metadata_ptr_ || !event_ptr_) { - return event_data; +nonstd::expected formatEvent(gsl::not_null metadata, gsl::not_null event, EVT_FORMAT_MESSAGE_FLAGS flags) noexcept try { + // first EvtFormatMessage call with no buffer to determine the required buffer size. + DWORD buffer_size_in_number_of_WCHARs = 0; + { + const bool size_check_result = EvtFormatMessage(metadata, event, 0, 0, nullptr, flags, 0, nullptr, &buffer_size_in_number_of_WCHARs); + if (size_check_result) { + // format succeeded with no buffer, this has to be an empty result + return std::string{}; + } + const auto last_error = GetLastError(); + if (last_error != ERROR_INSUFFICIENT_BUFFER) { + return nonstd::make_unexpected(utils::OsUtils::windowsErrorToErrorCode(last_error)); + } } - if (!EvtFormatMessage(metadata_ptr_, event_ptr_, 0, 0, nullptr, flags, num_chars_in_buffer, buffer.get(), &num_chars_used)) { - auto last_error = GetLastError(); - if (ERROR_INSUFFICIENT_BUFFER == last_error) { - num_chars_in_buffer = num_chars_used; + // second EvtFormatMessage call: format and convert/narrow to std::string + { + static_assert(std::is_same_v>, "assuming that a string of WCHAR is wstring"); + DWORD out_buffer_size = buffer_size_in_number_of_WCHARs; + std::wstring out_buffer; + out_buffer.resize(out_buffer_size); + const bool format_result = EvtFormatMessage(metadata, event, 0, 0, nullptr, flags, out_buffer.size(), out_buffer.data(), &out_buffer_size); + if (!format_result) { + const auto last_error = GetLastError(); + return nonstd::make_unexpected(utils::OsUtils::windowsErrorToErrorCode(last_error)); + } - buffer.reset((LPWSTR) malloc(num_chars_in_buffer * sizeof(WCHAR))); - if (!buffer) { - return event_data; - } + gsl_Assert(buffer_size_in_number_of_WCHARs == out_buffer_size && "message size shouldn't change between invocations of EvtFormatMessage"); - EvtFormatMessage(metadata_ptr_, event_ptr_, 0, 0, nullptr, flags, num_chars_in_buffer, buffer.get(), &num_chars_used); + // fixing up keyword lists based on the example at https://learn.microsoft.com/en-us/windows/win32/wes/formatting-event-messages + if (EvtFormatMessageKeyword == flags) { + out_buffer[num_chars_used - 1] = L'\0'; } - } - if (num_chars_used == 0) { - return event_data; + return utils::to_string(out_buffer); } +} catch (const std::bad_alloc&) { + return nonstd::make_unexpected(utils::OsUtils::windowsErrorToErrorCode(ERROR_OUTOFMEMORY)); +} - if (EvtFormatMessageKeyword == flags) { - buffer.get()[num_chars_used - 1] = L'\0'; +nonstd::expected WindowsEventLogMetadataImpl::getEventData(EVT_FORMAT_MESSAGE_FLAGS flags) const noexcept { + if (!metadata_ptr_ || !event_ptr_) { + // nothing to format, keep old behavior of returning an empty string + return std::string{}; } - return utils::to_string(std::wstring{buffer.get()}); + + return formatMessage(metadata_ptr_, event_ptr_, flags); } -nonstd::expected WindowsEventLogHandler::getEventMessage(EVT_HANDLE eventHandle) const { - std::string returnValue; - WCHAR stack_buffer[4096]; - DWORD num_chars_in_buffer = sizeof(stack_buffer) / sizeof(stack_buffer[0]); - using Deleter = utils::StackAwareDeleter; - std::unique_ptr buffer{stack_buffer, Deleter{stack_buffer}}; - DWORD num_chars_used = 0; - - bool evt_format_succeeded = EvtFormatMessage(metadata_provider_.get(), eventHandle, 0, 0, nullptr, EvtFormatMessageEvent, num_chars_in_buffer, buffer.get(), &num_chars_used); - if (evt_format_succeeded) - return utils::to_string(std::wstring{buffer.get()}); - - DWORD status = GetLastError(); - - if (status != ERROR_INSUFFICIENT_BUFFER) - return nonstd::make_unexpected(utils::OsUtils::windowsErrorToErrorCode(status)); - - num_chars_in_buffer = num_chars_used; - buffer.reset((LPWSTR) malloc(num_chars_in_buffer * sizeof(WCHAR))); - if (!buffer) - return nonstd::make_unexpected(utils::OsUtils::windowsErrorToErrorCode(ERROR_OUTOFMEMORY)); - if (EvtFormatMessage(metadata_provider_.get(), eventHandle, 0, 0, nullptr, - EvtFormatMessageEvent, num_chars_in_buffer, - buffer.get(), &num_chars_used)) - return utils::to_string(std::wstring{buffer.get()}); - return nonstd::make_unexpected(utils::OsUtils::windowsErrorToErrorCode(GetLastError())); +nonstd::expected WindowsEventLogHandler::getEventMessage(EVT_HANDLE eventHandle) const noexcept { + return formatMessage(metadata_provider_.get(), eventHandle, EvtFormatMessageEvent); } namespace { @@ -203,8 +191,4 @@ std::string WindowsEventLogHeader::createDefaultDelimiter(size_t length) const { } } -EVT_HANDLE WindowsEventLogHandler::getMetadata() const { - return metadata_provider_.get(); -} - } // namespace org::apache::nifi::minifi::wel diff --git a/extensions/windows-event-log/wel/WindowsEventLog.h b/extensions/windows-event-log/wel/WindowsEventLog.h index cef720a3bf..6e680bdb8b 100644 --- a/extensions/windows-event-log/wel/WindowsEventLog.h +++ b/extensions/windows-event-log/wel/WindowsEventLog.h @@ -31,7 +31,6 @@ #include #include "core/Core.h" -#include "concurrentqueue.h" #include "core/Processor.h" #include "core/ProcessSession.h" #include "utils/OsUtils.h" @@ -43,7 +42,8 @@ namespace org::apache::nifi::minifi::wel { -enum METADATA { +// enum names are part of the API +enum class Metadata { LOG_NAME, SOURCE, TIME_CREATED, @@ -59,22 +59,19 @@ enum METADATA { UNKNOWN }; +using METADATA_NAMES = std::vector>; -// this is a continuous enum, so we can rely on the array - -using METADATA_NAMES = std::vector>; +nonstd::expected formatEvent(gsl::not_null metadata, gsl::not_null event, EVT_FORMAT_MESSAGE_FLAGS flags) noexcept; class WindowsEventLogHandler { public: - WindowsEventLogHandler() : metadata_provider_(nullptr) { - } - - explicit WindowsEventLogHandler(EVT_HANDLE metadataProvider) : metadata_provider_(metadataProvider) { - } + WindowsEventLogHandler() = default; + explicit WindowsEventLogHandler(EVT_HANDLE metadataProvider) + : metadata_provider_(metadataProvider) + { } - nonstd::expected getEventMessage(EVT_HANDLE eventHandle) const; - - [[nodiscard]] EVT_HANDLE getMetadata() const; + [[nodiscard]] nonstd::expected getEventMessage(EVT_HANDLE eventHandle) const noexcept; + [[nodiscard]] EVT_HANDLE getMetadata() const noexcept { return metadata_provider_.get(); } private: unique_evt_handle metadata_provider_; @@ -83,76 +80,50 @@ class WindowsEventLogHandler { class WindowsEventLogMetadata { public: virtual ~WindowsEventLogMetadata() = default; - [[nodiscard]] virtual std::string getEventData(EVT_FORMAT_MESSAGE_FLAGS flags) const = 0; + [[nodiscard]] virtual nonstd::expected getEventData(EVT_FORMAT_MESSAGE_FLAGS flags) const noexcept = 0; [[nodiscard]] virtual std::string getEventTimestamp() const = 0; virtual short getEventTypeIndex() const = 0; // NOLINT short comes from WINDOWS API - static std::string getMetadataString(METADATA val) { - static std::map map = { - {LOG_NAME, "LOG_NAME"}, - {SOURCE, "SOURCE"}, - {TIME_CREATED, "TIME_CREATED"}, - {EVENTID, "EVENTID"}, - {OPCODE, "OPCODE"}, - {EVENT_RECORDID, "EVENT_RECORDID"}, - {EVENT_TYPE, "EVENT_TYPE"}, - {TASK_CATEGORY, "TASK_CATEGORY"}, - {LEVEL, "LEVEL"}, - {KEYWORDS, "KEYWORDS"}, - {USER, "USER"}, - {COMPUTER, "COMPUTER"} - }; - - return map[val]; - } - - static METADATA getMetadataFromString(const std::string& val) { - static std::map map = { - {"LOG_NAME", LOG_NAME}, - {"SOURCE", SOURCE}, - {"TIME_CREATED", TIME_CREATED}, - {"EVENTID", EVENTID}, - {"OPCODE", OPCODE}, - {"EVENT_RECORDID", EVENT_RECORDID}, - {"TASK_CATEGORY", TASK_CATEGORY}, - {"EVENT_TYPE", EVENT_TYPE}, - {"LEVEL", LEVEL}, - {"KEYWORDS", KEYWORDS}, - {"USER", USER}, - {"COMPUTER", COMPUTER} - }; - - auto enumVal = map.find(val); - if (enumVal != std::end(map)) { - return enumVal->second; - } else { - return METADATA::UNKNOWN; - } + static Metadata getMetadataFromString(std::string_view val) { + using enum Metadata; + if (val == "LOG_NAME") { return LOG_NAME; } + else if (val == "SOURCE") { return SOURCE; } + else if (val == "TIME_CREATED") { return TIME_CREATED; } + else if (val == "EVENTID") { return EVENTID; } + else if (val == "OPCODE") { return OPCODE; } + else if (val == "EVENT_RECORDID") { return EVENT_RECORDID; } + else if (val == "EVENT_TYPE") { return EVENT_TYPE; } + else if (val == "TASK_CATEGORY") { return TASK_CATEGORY; } + else if (val == "LEVEL") { return LEVEL; } + else if (val == "KEYWORDS") { return KEYWORDS; } + else if (val == "USER") { return USER; } + else if (val == "COMPUTER") { return COMPUTER; } + else { return UNKNOWN; } } static std::string getComputerName() { - static std::string computer_name; - if (computer_name.empty()) { - char buff[10248]; + static std::string computer_name = []() -> std::string { + char buff[256] = {0}; DWORD size = sizeof(buff); - if (GetComputerNameExA(ComputerNameDnsFullyQualified, buff, &size)) { - computer_name = buff; + if (GetComputerNameExA(ComputerNameDnsFullyQualified, buff, &size) || GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + buff[255] = '\0'; // It's not clear from the MSDN docs whether the terminating null byte is written + return buff; } else { - computer_name = "N/A"; + return "N/A"; } - } + }(); return computer_name; } }; class WindowsEventLogMetadataImpl : public WindowsEventLogMetadata { public: - WindowsEventLogMetadataImpl(EVT_HANDLE metadataProvider, EVT_HANDLE event_ptr) : metadata_ptr_(metadataProvider), event_ptr_(event_ptr) { + WindowsEventLogMetadataImpl(EVT_HANDLE metadataProvider, EVT_HANDLE event_ptr) + : metadata_ptr_(metadataProvider), event_ptr_(event_ptr) { renderMetadata(); } - [[nodiscard]] std::string getEventData(EVT_FORMAT_MESSAGE_FLAGS flags) const override; - + [[nodiscard]] nonstd::expected getEventData(EVT_FORMAT_MESSAGE_FLAGS flags) const noexcept override; [[nodiscard]] std::string getEventTimestamp() const override { return event_timestamp_str_; } short getEventTypeIndex() const override { return event_type_index_; } // NOLINT short comes from WINDOWS API @@ -186,17 +157,16 @@ class WindowsEventLogHeader { template std::string WindowsEventLogHeader::getEventHeader(const MetadataCollection& metadata_collection) const { std::stringstream eventHeader; - for (const auto& option : header_names_) { - auto name = option.second; + const auto& name = option.second; eventHeader << name; - if (custom_delimiter_) + if (custom_delimiter_) { eventHeader << *custom_delimiter_; - else + } else { eventHeader << createDefaultDelimiter(name.size()); - eventHeader << utils::string::trim(metadata_collection(option.first)) << std::endl; + } + eventHeader << utils::string::trim(metadata_collection(option.first)) << '\n'; } - return eventHeader.str(); } diff --git a/libminifi/include/utils/OsUtils.h b/libminifi/include/utils/OsUtils.h index d9f35be18e..7feedc2e91 100644 --- a/libminifi/include/utils/OsUtils.h +++ b/libminifi/include/utils/OsUtils.h @@ -43,7 +43,7 @@ int64_t getSystemTotalPhysicalMemory(); /// Returns the total paging file size in bytes int64_t getTotalPagingFileSize(); -std::error_code windowsErrorToErrorCode(unsigned long error_code); // NOLINT [runtime/int] +std::error_code windowsErrorToErrorCode(unsigned long error_code) noexcept; // NOLINT [runtime/int] #endif /// Returns the host architecture (e.g. x32, arm64) diff --git a/libminifi/src/utils/OsUtils.cpp b/libminifi/src/utils/OsUtils.cpp index f1ac8b67c9..6f60e984f3 100644 --- a/libminifi/src/utils/OsUtils.cpp +++ b/libminifi/src/utils/OsUtils.cpp @@ -296,7 +296,7 @@ int64_t OsUtils::getTotalPagingFileSize() { return total_paging_file_size; } -std::error_code OsUtils::windowsErrorToErrorCode(DWORD error_code) { +std::error_code OsUtils::windowsErrorToErrorCode(DWORD error_code) noexcept { return {gsl::narrow_cast(error_code), std::system_category()}; } #endif