getchar() or getline will be blocked in binlog
Closed this issue · 12 comments
Hey,
When there is getchar/std::getline(std::cin) function in my main() program, binlog will not work.
Does these two functions will hang up binlog event?
#include <binlog/binlog.hpp>
#include
#include
int main(int argc, char* argv[])
{
BINLOG_INFO("Hello {}!", "World");
std::ofstream logfile("hello.blog", std::ofstream::out | std::ofstream::binary);
binlog::consume(logfile);
string inputs;
std::getline(std::cin, inputs);
getchar();
}
there's no any logs in hello.blog.
hi, call binlog::consume(logfile);
at the end of your program. detailed doc here: http://binlog.org/UserGuide.html#consume-logs
std::ofstream logfile("hello.blog", std::ofstream::out | std::ofstream::binary);
int main()
{
BINLOG_INFO("Hello {}!", "World");
AppAdmin::ConsoleAdmin::Instance().Init(&io, std::bind(&AppAdmin::AdminCommand, &AppAdmin::ConsoleAdmin::Instance(), std::placeholders::_1));
AppAdmin::SignalHandler signalHandler(io);
std::thread t([&signalHandler]()
{
signalHandler.HandleInput();
});
t.join();
getchar()
binlog::consume(logfile);
void SignalHandler::HandleInput()
{
binlog::Session session;
const std::size_t queueCapacityBytes = 1 << 20;
binlog::SessionWriter writer(session, queueCapacityBytes);
std::string buf;
while (std::getline(std::cin, buf))
{
ConsoleAdmin::Instance().Command(buf);
if (buf == "q")
{
return;
}
session.consume(logfile);
}
}
In this case, hello.blog has no any logs until the main program quit when I input "q".
But I don't wanna quit program to print log, How can I do that?
In win32 platform, if I directly close the console application by click 'X', then it does not work, no any logs in .blog
Thank you in advance.
Please provide a MRE: https://stackoverflow.com/help/minimal-reproducible-example
If you are in doubt, add printf
calls next to the session.consume
calls, to make sure consume is called when needed.
In the code above, both binlog::consume
and session.consume
are used. This is allowed, but probably not what you want. Remove this part:
binlog::Session session;
const std::size_t queueCapacityBytes = 1 << 20;
binlog::SessionWriter writer(session, queueCapacityBytes);
And keep using binlog::consume
until you figure it out.
`#include <binlog/binlog.hpp>
#include
#include
#include
int main()
{
std::ofstream logfile("consume.blog", std::ofstream::out | std::ofstream::binary);
std::string input;
while (std::getline(std::cin, input))
{
if (input == "q")
break;
binlog::consume(logfile);
}
//]
if (!logfile)
{
std::cerr << "Failed to write consume.blog\n";
return 1;
}
std::cout << "Binary log written to consume.blog\n";
binlog::consume(logfile);
return 0;
}`
Above are my MRE. I have to type 'q' to quit program, then consume.blog will be logged. If I close application by click 'X', then no any logs.
There are no log statements in this example. What output did you expect?
I suspect your stdlib buffers writes to the ofstream. Try flushing it after consume:
printf("consume called\r\n");
binlog::consume(logfile);
logfile.flush();
I suspect your stdlib buffers writes to the ofstream. Try flushing it after consume:
printf("consume called\r\n"); binlog::consume(logfile); logfile.flush();
Seemingly, it still does not work. consume.blog still has 0 size.
Hi, do you have any suggestion to get it around? This issue now blocks me.
I really want to use binlog in my project。
Thank you
Hi, I tested your code on Linux, it works as intended. I don't have direct access to windows machines, but similar tests run in CI on windows, and work as intended. Here's a slightly modified example that prints the number of consumed bytes and flushes the file:
#include <binlog/binlog.hpp>
#include <fstream>
#include <iostream>
int main()
{
std::ofstream logfile("consume.blog", std::ofstream::out | std::ofstream::binary);
BINLOG_INFO("Hello {}!", "World");
std::string input;
while (std::getline(std::cin, input))
{
if (input == "q")
break;
binlog::Session::ConsumeResult cr = binlog::consume(logfile);
logfile.flush();
std::cout << "Consumed " << cr.bytesConsumed << " bytes" << std::endl;
}
if (!logfile)
{
std::cerr << "Failed to write consume.blog\n";
return 1;
}
std::cout << "Binary log written to consume.blog\n";
binlog::consume(logfile);
return 0;
}