update logging to use logger channel

This commit is contained in:
Aaron Po
2026-05-15 01:13:53 -04:00
parent a4968eb043
commit e6a20324e4
35 changed files with 561 additions and 404 deletions

View File

@@ -14,7 +14,7 @@
#include <string>
#include <thread>
#include "biergarten_data_generator.h"
#include "biergarten_pipeline_orchestrator.h"
#include "concurrency/bounded_channel.h"
#include "data_generation/llama_generator.h"
#include "data_generation/mock_generator.h"
@@ -27,9 +27,9 @@
#include "services/enrichment/enrichment_service.h"
#include "services/enrichment/mock_enrichment.h"
#include "services/enrichment/wikipedia_service.h"
#include "services/logging/channel_logger.h"
#include "services/logging/log_consumer.h"
#include "services/logging/log_dispatcher.h"
#include "services/logging/log_entry.h"
#include "services/logging/log_producer.h"
#include "services/logging/logger.h"
#include "services/prompting/prompt_directory.h"
#include "web_client/http_web_client.h"
@@ -37,28 +37,36 @@
namespace di = boost::di;
static constexpr size_t kLogMaxCount = 512;
int main(const int argc, char** argv) {
auto log_channel = std::make_shared<BoundedChannel<LogEntry>>(kLogMaxCount);
ChannelLogger channel_logger(*log_channel);
LogConsumer log_worker(*log_channel);
std::thread log_thread([&log_worker] { log_worker.Run(); });
int main(const int argc, char** argv) {
// Configure global spdlog formatting: timestamp, level, and message.
// Use Unicode box-drawing characters to frame logs for improved readability.
// The LogDispatcher includes phase and thread info inside the message.
spdlog::set_pattern(R"(┌────────────────────────────────────────────────────────
%^%l%$ | %Y-%m-%d %H:%M:%S:%e
%v
)");
BoundedChannel<LogEntry> log_channel(kLogMaxCount);
auto log_dispatcher = std::make_unique<LogDispatcher>(log_channel);
std::thread log_thread([&log_dispatcher] { log_dispatcher->Run(); });
std::shared_ptr<ILogger> log_producer =
std::make_shared<LogProducer>(log_channel);
try {
Timer timer;
spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] %v");
#ifndef BIERGARTEN_MOCK_ONLY
const LlamaBackendState llama_backend_state;
#endif
#ifdef DEBUG
spdlog::set_level(spdlog::level::debug);
#endif
log_producer->Log(LogLevel::Info, PipelinePhase::Startup,
"=== Starting Biergarten Pipeline ===");
const std::optional<ApplicationOptions> parsed_options =
ParseArguments(argc, argv);
ParseArguments(argc, argv, log_producer);
if (!parsed_options.has_value()) {
log_channel->Close();
log_channel.Close();
log_thread.join();
return 0;
}
@@ -76,12 +84,13 @@ int main(const int argc, char** argv) {
if (!options.generator.use_mocked) {
try {
prompt_directory =
std::make_unique<PromptDirectory>(options.pipeline.prompt_dir);
std::make_unique<PromptDirectory>(options.pipeline.prompt_dir,
log_producer);
} catch (const std::exception& dir_error) {
channel_logger.Log(
log_producer->Log(
LogLevel::Error, PipelinePhase::Startup,
std::string("Invalid --prompt-dir: ") + dir_error.what());
log_channel->Close();
log_channel.Close();
log_thread.join();
return 1;
}
@@ -91,34 +100,32 @@ int main(const int argc, char** argv) {
// Dependency injection
// -----------------------------------------------------------------------
const auto injector = di::make_injector(
di::bind<ILogger>().to(log_producer),
di::bind<ApplicationOptions>().to(options),
di::bind<std::string>().to(model_path),
di::bind<WebClient>().to<HttpWebClient>(),
di::bind<IExportService>().to<SqliteExportService>(),
di::bind<IPromptFormatter>().to<Gemma4JinjaPromptFormatter>(),
di::bind<ILogger>().to(
[log_channel](const auto&) -> std::unique_ptr<ILogger> {
return std::make_unique<ChannelLogger>(*log_channel);
}),
di::bind<IEnrichmentService>().to(
[options](const auto& inj) -> std::unique_ptr<IEnrichmentService> {
[options, &log_producer](const auto& inj)
-> std::unique_ptr<IEnrichmentService> {
if (options.generator.use_mocked) {
return std::make_unique<MockEnrichmentService>();
}
return std::make_unique<WikipediaEnrichmentService>(
inj.template create<std::unique_ptr<WebClient>>());
inj.template create<std::unique_ptr<WebClient>>(),
log_producer);
}),
di::bind<DataGenerator>().to(
[&options, &model_path, &sampling, &prompt_directory,
&channel_logger](
const auto& inj) -> std::unique_ptr<DataGenerator> {
&log_producer](const auto& inj) -> std::unique_ptr<DataGenerator> {
if (options.generator.use_mocked) {
channel_logger.Log(
log_producer->Log(
LogLevel::Info, PipelinePhase::Startup,
"Using MockGenerator (no model path provided)");
return std::make_unique<MockGenerator>();
}
channel_logger.Log(
log_producer->Log(
LogLevel::Info, PipelinePhase::Startup,
"Using LlamaGenerator: " + model_path +
" (temperature=" + std::to_string(sampling.temperature) +
@@ -127,7 +134,7 @@ int main(const int argc, char** argv) {
", n_ctx=" + std::to_string(sampling.n_ctx) +
", seed=" + std::to_string(sampling.seed) + ")");
return std::make_unique<LlamaGenerator>(
options, model_path,
options, model_path, log_producer,
inj.template create<std::unique_ptr<IPromptFormatter>>(),
std::move(prompt_directory));
}));
@@ -139,25 +146,30 @@ int main(const int argc, char** argv) {
injector.create<std::unique_ptr<BiergartenPipelineOrchestrator>>();
if (!orchestrator->Run()) {
channel_logger.Log(LogLevel::Error, PipelinePhase::Teardown,
"Pipeline execution failed");
log_channel->Close();
log_producer->Log(LogLevel::Error, PipelinePhase::Teardown,
"Pipeline execution failed");
log_channel.Close();
log_thread.join();
return 1;
}
channel_logger.Log(LogLevel::Info, PipelinePhase::Teardown,
"Pipeline executed successfully in " +
std::to_string(timer.Elapsed()) + " ms");
log_producer->Log(LogLevel::Info, PipelinePhase::Teardown,
"Pipeline executed successfully in " +
std::to_string(timer.Elapsed()) + " ms");
log_channel->Close();
log_channel.Close();
log_thread.join();
return 0;
} catch (const std::exception& exception) {
// Channel may be in an unknown state; fall back to spdlog directly.
spdlog::critical("Unhandled fatal error in main: {}", exception.what());
log_channel->Close();
// Attempt to use the logging infrastructure; if channel/dispatcher are
// compromised this is a best-effort fallback.
if (log_producer) {
log_producer->Log(LogLevel::Error, PipelinePhase::Teardown,
std::string("Unhandled fatal error in main: ") +
exception.what());
}
log_channel.Close();
log_thread.join();
return 1;
}