morganstanley/binlog

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
image

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();

image
Seemingly, it still does not work. consume.blog still has 0 size.

I suspect your stdlib buffers writes to the ofstream. Try flushing it after consume:

        printf("consume called\r\n");
        binlog::consume(logfile);
        logfile.flush();

image
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;
}