diff --git a/include/ircd/m/events.h b/include/ircd/m/events.h index b435f02b1..38fc30740 100644 --- a/include/ircd/m/events.h +++ b/include/ircd/m/events.h @@ -37,6 +37,9 @@ namespace ircd::m::events bool for_each(const range &, const closure_bool &); bool for_each(const range &, const event_filter &, const closure_bool &); + + // util + void dump__file(const string_view &filename); } /// Range to start (inclusive) and stop (exclusive). If start is greater than diff --git a/modules/console.cc b/modules/console.cc index 7a2d1322e..4496d6b0f 100644 --- a/modules/console.cc +++ b/modules/console.cc @@ -6176,75 +6176,7 @@ console_cmd__events__dump(opt &out, const string_view &line) param.at(0) }; - const fs::fd file - { - filename, std::ios::out | std::ios::app - }; - - const unique_buffer buf - { - size_t(events_dump_buffer_size) - }; - - char *pos{data(buf)}; - size_t foff{0}, ecount{0}, acount{0}, errcount{0}; - m::events::for_each(m::event::idx{0}, [&] - (const m::event::idx &seq, const m::event &event) - { - const auto remain - { - size_t(data(buf) + size(buf) - pos) - }; - - assert(remain >= m::event::MAX_SIZE && remain <= size(buf)); - const mutable_buffer mb{pos, remain}; - pos += json::print(mb, event); - ++ecount; - - if(pos + m::event::MAX_SIZE > data(buf) + size(buf)) - { - const const_buffer cb{data(buf), pos}; - foff += size(fs::append(file, cb)); - pos = data(buf); - ++acount; - - const double pct - { - (seq / double(m::vm::sequence::retired)) * 100.0 - }; - - log::info - { - "dump[%s] %lf$%c @ seq %zu of %zu; %zu events; %zu bytes; %zu writes; %zu errors", - filename, - pct, - '%', //TODO: fix gram - seq, - m::vm::sequence::retired, - ecount, - foff, - acount, - errcount - }; - } - - return true; - }); - - if(pos > data(buf)) - { - const const_buffer cb{data(buf), pos}; - foff += size(fs::append(file, cb)); - ++acount; - } - - out << "Dumped " << ecount << " events" - << " using " << foff << " bytes" - << " in " << acount << " writes" - << " to " << filename - << " with " << errcount << " errors" - << std::endl; - + m::events::dump__file(filename); return true; } diff --git a/modules/m_events.cc b/modules/m_events.cc index 5a9823e9b..64e39bea2 100644 --- a/modules/m_events.cc +++ b/modules/m_events.cc @@ -8,12 +8,101 @@ // copyright notice and this permission notice is present in all copies. The // full license for this software is available in the LICENSE file. +namespace ircd::m::events +{ + extern conf::item dump_buffer_size; +} + ircd::mapi::header IRCD_MODULE { "Matrix events library" }; +decltype(ircd::m::events::dump_buffer_size) +ircd::m::events::dump_buffer_size +{ + { "name", "ircd.m.events.dump.buffer_size" }, + { "default", int64_t(4_MiB) }, +}; + +void +IRCD_MODULE_EXPORT +ircd::m::events::dump__file(const string_view &filename) +{ + const fs::fd file + { + filename, std::ios::out | std::ios::app + }; + + const unique_buffer buf + { + size_t(dump_buffer_size) + }; + + char *pos{data(buf)}; + size_t foff{0}, ecount{0}, acount{0}, errcount{0}; + for_each(m::event::idx{0}, [&] + (const event::idx &seq, const m::event &event) + { + const auto remain + { + size_t(data(buf) + size(buf) - pos) + }; + + assert(remain >= event::MAX_SIZE && remain <= size(buf)); + const mutable_buffer mb{pos, remain}; + pos += copy(mb, event.source); + ++ecount; + + if(pos + event::MAX_SIZE > data(buf) + size(buf)) + { + const const_buffer cb{data(buf), pos}; + foff += size(fs::append(file, cb)); + pos = data(buf); + ++acount; + + const double pct + { + (seq / double(m::vm::sequence::retired)) * 100.0 + }; + + log::info + { + "dump[%s] %0.2lf$%c @ seq %zu of %zu; %zu events; %zu bytes; %zu writes; %zu errors", + filename, + pct, + '%', //TODO: fix gram + seq, + m::vm::sequence::retired, + ecount, + foff, + acount, + errcount + }; + } + + return true; + }); + + if(pos > data(buf)) + { + const const_buffer cb{data(buf), pos}; + foff += size(fs::append(file, cb)); + ++acount; + } + + log::notice + { + log, "dump[%s] complete events:%zu using %s in writes:%zu errors:%zu", + filename, + ecount, + pretty(iec(foff)), + acount, + errcount, + }; +} + bool IRCD_MODULE_EXPORT ircd::m::events::for_each(const range &range,