1#include "logging.hh"2#include <nix/util/logging.hh>3#include <nix/util/position.hh>45using namespace nix;67rust::Box<ErrorInfoBuilder> copy_error_info(const ErrorInfo &ei) {8 auto s = ei.msg.str();9 rust::Slice<const unsigned char> str(10 reinterpret_cast<const unsigned char *>(s.data()), s.size());11 auto b = new_error_info(ei.level, str);12 if (!ei.traces.empty()) {13 for (auto iter = ei.traces.rbegin(); iter != ei.traces.rend(); ++iter) {14 auto msg = iter->hint.str();1516 rust::Slice<const unsigned char> msgv(17 reinterpret_cast<const unsigned char *>(msg.data()), msg.size());1819 std::ostringstream oss;20 if (iter->pos) {21 iter->pos->print(oss, true);22 }23 std::string pos = oss.str();2425 rust::Slice<const unsigned char> posv(26 reinterpret_cast<const unsigned char *>(pos.data()), pos.size());2728 b->push_stack_frame(msgv, posv);29 }30 }31 return b;32}3334struct TracingLogger : Logger {35 TracingLogger() {}3637 bool isVerbose() override { return true; }38 void log(Verbosity lvl, std::string_view s) override {39 rust::Slice<const unsigned char> str(40 reinterpret_cast<const unsigned char *>(s.data()), s.size());41 emit_log(lvl, str);42 }43 void logEI(const ErrorInfo &ei) override {44 auto b = copy_error_info(ei);45 b->emit_error_info();46 }4748 void startActivity(ActivityId act, Verbosity lvl, ActivityType type,49 const std::string &s, const Fields &fields,50 ActivityId parent) override {51 auto b = new_start_activity(act, lvl, type);52 for (auto &f : fields) {53 if (f.type == Logger::Field::tInt) {54 b->add_int_field(f.i);55 } else if (f.type == Logger::Field::tString) {56 auto s = &f.s;57 rust::Slice<const unsigned char> str(58 reinterpret_cast<const unsigned char *>(s->data()), s->size());59 b->add_string_field(str);60 } else {61 unreachable();62 }63 }64 b->emit(parent, s);65 };6667 void stopActivity(ActivityId act) override { emit_stop(act); };6869 void result(ActivityId act, ResultType type, const Fields &fields) override {70 auto b = new_start_activity(act, 0, type);71 for (auto &f : fields) {72 if (f.type == Logger::Field::tInt) {73 b->add_int_field(f.i);74 } else if (f.type == Logger::Field::tString) {75 auto s = &f.s;76 rust::Slice<const unsigned char> str(77 reinterpret_cast<const unsigned char *>(s->data()), s->size());78 b->add_string_field(str);79 } else {80 unreachable();81 }82 }83 b->emit_result(type);84 };8586 void writeToStdout(std::string_view s) override {87 emit_warn("writeToStdout() called, but unsupported");88 }89 void warn(const std::string &msg) override { emit_warn(msg); }9091 virtual std::optional<char> ask(std::string_view s) {92 emit_warn("ask() called, but unsupported");93 return {};94 }95};9697extern "C" {98void apply_tracing_logger() {99 logger = std::make_unique<TracingLogger>();100 // verbosity = lvlVomit;101}102rust::Box<ErrorInfoBuilder>103extract_error_info(const nix_c_context *read_context) {104 return copy_error_info(read_context->info.value());105}106}