diff options
| author | Dan Goodliffe <dan@randomdan.homeip.net> | 2026-04-10 20:22:35 +0100 |
|---|---|---|
| committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2026-04-10 20:22:35 +0100 |
| commit | 72bfa9dd305258789b0d2e80f8af13962e5aac42 (patch) | |
| tree | 4f4dd17921154452289107fae6b6358047f35bce | |
| parent | 1e551e618a63c869fde6a4b327566b38696a5f45 (diff) | |
| download | webstat-72bfa9dd305258789b0d2e80f8af13962e5aac42.tar.bz2 webstat-72bfa9dd305258789b0d2e80f8af13962e5aac42.tar.xz webstat-72bfa9dd305258789b0d2e80f8af13962e5aac42.zip | |
Return path of parked lines log file from parkQueuedLogLines
Or the last errno on failure.
| -rw-r--r-- | src/ingestor.cpp | 13 | ||||
| -rw-r--r-- | src/ingestor.hpp | 3 | ||||
| -rw-r--r-- | test/test-ingest.cpp | 34 |
3 files changed, 28 insertions, 22 deletions
diff --git a/src/ingestor.cpp b/src/ingestor.cpp index c5cb8d8..0659f1f 100644 --- a/src/ingestor.cpp +++ b/src/ingestor.cpp @@ -275,11 +275,11 @@ namespace WebStat { } } - void + std::expected<std::filesystem::path, int> Ingestor::parkQueuedLogLines() { if (queuedLines.empty()) { - return; + return std::unexpected(0); } const std::filesystem::path path { settings.fallbackDir / std::format("parked-{}.short", crc32(queuedLines.front()))}; @@ -290,16 +290,19 @@ namespace WebStat { } if (fflush(parked.get()) == 0) { queuedLines.clear(); - auto finalPath = auto {path}.replace_extension(".log"); + auto finalPath = std::filesystem::path {path}.replace_extension(".log"); + parked.reset(); if (rename(path.c_str(), finalPath.c_str()) == 0) { - return; + return finalPath; } } } + const int err = errno; log(LOG_ERR, "Failed to park %zu queued lines:", queuedLines.size()); for (const auto & line : queuedLines) { log(LOG_ERR, "\t%.*s", static_cast<int>(line.length()), line.data()); } + return std::unexpected(err); } void @@ -334,7 +337,7 @@ namespace WebStat { unsigned int count = 0; for (auto pathIter = std::filesystem::directory_iterator {settings.fallbackDir}; pathIter != std::filesystem::directory_iterator {}; ++pathIter) { - if (scn::scan<Crc32Value>(pathIter->path().filename().string(), "parked-{}.log")) { + if (scn::scan<std::string>(pathIter->path().filename().string(), "parked-{:[a-zA-Z0-9]}.log")) { jobIngestParkedLines(pathIter->path()); count += 1; } diff --git a/src/ingestor.hpp b/src/ingestor.hpp index fcddc92..b2e0fed 100644 --- a/src/ingestor.hpp +++ b/src/ingestor.hpp @@ -7,6 +7,7 @@ #include <connectionPool.h> #include <connection_fwd.h> #include <cstdio> +#include <expected> #include <flat_set> #include <future> #include <scn/scan.h> @@ -54,7 +55,7 @@ namespace WebStat { void ingestLog(std::FILE *); void tryIngestQueuedLogLines(); void ingestLogLines(DB::Connection *, const LineBatch & lines); - void parkQueuedLogLines(); + std::expected<std::filesystem::path, int> parkQueuedLogLines(); void runJobsAsNeeded(); unsigned int jobIngestParkedLines(); diff --git a/test/test-ingest.cpp b/test/test-ingest.cpp index 5fc8195..d399288 100644 --- a/test/test-ingest.cpp +++ b/test/test-ingest.cpp @@ -155,7 +155,6 @@ BOOST_DATA_TEST_CASE(CLFStringsBad, constexpr std::string_view LOGLINE1 = R"LOG(git.randomdan.homeip.net 98.82.40.168 1755561576768318 GET "/repo/gentoobrowse-api/commit/gentoobrowse-api/unittests/fixtures/756569aa764177340726dd3d40b41d89b11b20c7/app-crypt/pdfcrack/Manifest" "?h=gentoobrowse-api-0.9.1&id=a2ed3fd30333721accd4b697bfcb6cc4165c7714" HTTP/1.1 200 1884 107791 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Amazonbot/0.1; +https://developer.amazon.com/support/amazonbot) Chrome/119.0.6045.214 Safari/537.36" "test/plain")LOG"; -constexpr std::string_view LOGLINE1_PARKED = "parked-237093379.log"; constexpr std::string_view LOGLINE2 = R"LOG(www.randomdan.homeip.net 43.128.84.166 1755561575973204 GET "/app-dicts/myspell-et/Manifest" "" HTTP/1.1 200 312 10369 "https://google.com" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" "image/png")LOG"; @@ -298,11 +297,11 @@ BOOST_AUTO_TEST_CASE(ParkLogLine) { queuedLines.emplace_back(LOGLINE1); queuedLines.emplace_back(LOGLINE2); - parkQueuedLogLines(); - const auto path = settings.fallbackDir / LOGLINE1_PARKED; - BOOST_TEST_INFO(path); - BOOST_REQUIRE(std::filesystem::exists(path)); - BOOST_CHECK_EQUAL(std::filesystem::file_size(path), LOGLINE1.length() + LOGLINE2.length() + 4); + const auto path = parkQueuedLogLines(); + BOOST_REQUIRE(path); + BOOST_TEST_INFO(*path); + BOOST_REQUIRE(std::filesystem::exists(*path)); + BOOST_CHECK_EQUAL(std::filesystem::file_size(*path), LOGLINE1.length() + LOGLINE2.length() + 4); } BOOST_AUTO_TEST_CASE(ParkLogLineOnError, *boost::unit_test::depends_on("I/ParkLogLine")) @@ -318,11 +317,12 @@ BOOST_AUTO_TEST_CASE(IngestParked, *boost::unit_test::depends_on("I/ParkLogLine" { queuedLines.emplace_back(LOGLINE1); queuedLines.emplace_back(LOGLINE2); - parkQueuedLogLines(); + BOOST_REQUIRE(parkQueuedLogLines()); + BOOST_CHECK(!std::filesystem::is_empty(settings.fallbackDir)); BOOST_REQUIRE(queuedLines.empty()); jobIngestParkedLines(); BOOST_CHECK_EQUAL(queuedLines.size(), 2); - BOOST_CHECK(!std::filesystem::exists(settings.fallbackDir / LOGLINE1_PARKED)); + BOOST_CHECK(std::filesystem::is_empty(settings.fallbackDir)); } BOOST_AUTO_TEST_CASE(DefaultLaunchNoJobs) @@ -338,21 +338,22 @@ BOOST_AUTO_TEST_CASE(IngestParkedJob, const auto now = Job::LastRunTime::clock::now(); ingestParkedLines.lastRun = now - 1s; queuedLines.emplace_back(LOGLINE1); - parkQueuedLogLines(); + const auto path = parkQueuedLogLines(); + BOOST_REQUIRE(path); BOOST_REQUIRE(queuedLines.empty()); - BOOST_REQUIRE(std::filesystem::exists(settings.fallbackDir / LOGLINE1_PARKED)); + BOOST_REQUIRE(std::filesystem::exists(*path)); runJobsAsNeeded(); BOOST_REQUIRE(!ingestParkedLines.currentRun); BOOST_CHECK(queuedLines.empty()); - BOOST_CHECK(std::filesystem::exists(settings.fallbackDir / LOGLINE1_PARKED)); + BOOST_CHECK(std::filesystem::exists(*path)); BOOST_CHECK_EQUAL(ingestParkedLines.lastRun, now - 1s); ingestParkedLines.lastRun = now - settings.freqIngestParkedLines + 2s; runJobsAsNeeded(); BOOST_REQUIRE(!ingestParkedLines.currentRun); BOOST_CHECK(queuedLines.empty()); - BOOST_CHECK(std::filesystem::exists(settings.fallbackDir / LOGLINE1_PARKED)); + BOOST_CHECK(std::filesystem::exists(*path)); BOOST_CHECK_EQUAL(ingestParkedLines.lastRun, now - settings.freqIngestParkedLines + 2s); ingestParkedLines.lastRun = now - settings.freqIngestParkedLines - 1s; @@ -363,7 +364,7 @@ BOOST_AUTO_TEST_CASE(IngestParkedJob, BOOST_REQUIRE(!ingestParkedLines.currentRun); BOOST_CHECK_EQUAL(queuedLines.size(), 1); BOOST_CHECK_GE(ingestParkedLines.lastRun, now); - BOOST_CHECK(!std::filesystem::exists(settings.fallbackDir / LOGLINE1_PARKED)); + BOOST_CHECK(!std::filesystem::exists(*path)); } BOOST_AUTO_TEST_CASE(JobErrorRescheduler, *boost::unit_test::depends_on("I/IngestParkedJob")) @@ -371,14 +372,15 @@ BOOST_AUTO_TEST_CASE(JobErrorRescheduler, *boost::unit_test::depends_on("I/Inges const auto now = Job::LastRunTime::clock::now(); ingestParkedLines.lastRun = now - settings.freqIngestParkedLines - 1s; queuedLines.emplace_back(LOGLINE1); - parkQueuedLogLines(); - std::filesystem::permissions(settings.fallbackDir / LOGLINE1_PARKED, std::filesystem::perms::owner_write); + const auto path = parkQueuedLogLines(); + BOOST_REQUIRE(path); + std::filesystem::permissions(*path, std::filesystem::perms::owner_write); runJobsAsNeeded(); BOOST_REQUIRE(ingestParkedLines.currentRun); ingestParkedLines.currentRun->wait(); runJobsAsNeeded(); BOOST_REQUIRE(!ingestParkedLines.currentRun); - BOOST_CHECK(std::filesystem::exists(settings.fallbackDir / LOGLINE1_PARKED)); + BOOST_CHECK(std::filesystem::exists(*path)); BOOST_CHECK_GE(ingestParkedLines.lastRun, now - (settings.freqIngestParkedLines / 2) - 1s); BOOST_CHECK_LE(ingestParkedLines.lastRun, now - (settings.freqIngestParkedLines / 2) + 1s); } |
