Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Log console output during replay to file #985 #76

Merged
merged 2 commits into from
Oct 1, 2018

Conversation

cogutvalera
Copy link
Member

PR for "Log console output during replay to file #985 bitshares/bitshares-core#985"

@abitmore
Copy link
Member

Can you please briefly explain why change like this? There is no comment in your code.

@cogutvalera
Copy link
Member Author

I can add comments right into code if required.
After debugging and researching code I've found the reason of this issue.

  1. During replay we can see logs in console but not in file because of next reason: fc::file_appender::impl::out (ofstream) is opened after rotate_files.
  2. So this means that ofstream will be opened after replay is completed and finished. Thus after replay we can see the same logs in console and file.
  3. Now after my changes ofstream is opened before replay happens. So this solution makes possible to see logs not only in console during replay but also we can see the same logs in file according to configuration in config.ini or logging.ini.

if(!my->cfg.rotate)
my->out.open( my->cfg.filename, std::ios_base::out | std::ios_base::app);
{
fc::scoped_lock<boost::mutex> lock( my->slock );

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is a constructor, I do not see the need for a lock here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have different threads, that's why I've added lock here, IMHO slock mutex is supposed to be used for log files within different threads, maybe I'm wrong.

Thanks !

@@ -141,9 +160,11 @@ namespace fc {
{
fc::create_directories(my->cfg.filename.parent_path());

if(!my->cfg.rotate)
Copy link

@jmjatlanta jmjatlanta Sep 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't walked all of the code, but if rotate == true, will removing this cause open() to be called twice (once here, and once in rotate_files()) ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if rotate check was removed, and twice won't be open because there is a check in open_log_filename method

Copy link
Member

@abitmore abitmore left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need better abstraction / modularization.

@@ -57,21 +69,30 @@ namespace fc {
}
}

void open_log_filename()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function name is confusing. I'd recommend rename it to open_log_file() or something else that can describe the logic better.

In addition, the check for file name inside the function made it even harder to understand, I think it would be better to move out the check, e.g. have an open() simply opens a file or perhaps close then reopen, and only call it when necessary (aka with a check).

In short, try to simplify the code.

fc::time_point _now;
fc::time_point_sec _start_time;
string _timestamp_string;
fc::path _old_log_filename, _log_filename, _link_filename;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For member variables, please declare only one variable per line.

line << std::setw( 21 ) << (m.get_context().get_thread_name().substr(0,9) + string(":") + m.get_context().get_task_name()).c_str() << " ";
line << std::setw( 21 ) <<
(m.get_context().get_thread_name().substr(0,9) + string(":") + m.get_context().get_task_name()).c_str()
<< " ";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code style here looks a bit ugly. I'd prefer

line << "something"
     << "something else"
     << "the end";       

@@ -141,9 +160,7 @@ namespace fc {
{
fc::create_directories(my->cfg.filename.parent_path());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not move the whole logic into constructor of impl class for simplicity? All operation is done on my anyway.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought the same earlier, I agree it would be better ! Thanks !

@cogutvalera
Copy link
Member Author

pushed new commit "more improvements"

Thanks !

@pmconrad
Copy link

So this means that ofstream will be opened after replay is completed and finished.

Why is this so?
file_appender::impl calls rotate_files asynchronously from the constructor. Either there's something wrong with the call, or the async excution happens only after replay. In the latter case, the obvious (and much simpler) fix would be to make the initial rotate_files call synchronous.

if( cfg.rotate )
{
FC_ASSERT( cfg.rotation_interval >= seconds( 1 ) );
FC_ASSERT( cfg.rotation_limit >= cfg.rotation_interval );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these assertions should be put before creating log file, even before setup_log_filenames.

}
catch( ... )
{
std::cerr << "error opening log file: " << cfg.filename.preferred_string() << "\n";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the appender usable after caught an exception here? What will happen when trying to write?

_old_log_filename = _log_filename;

open_log_file();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic seems a bit strange.

  • Is there a chance that the file got closed but not reopened?
  • Is there a chance that the file be opened again when not closed?

@abitmore
Copy link
Member

the obvious (and much simpler) fix would be to make the initial rotate_files call synchronous.

Probably because rotate_files() also removes old files that could take some time, thus not good to call on initialization. However, even it's the case, we can skip the removal on first call.

By the way, I guess the rotate_files(1) call is defensive? Looks like it will never be called.

@cogutvalera
Copy link
Member Author

(just for the info) I've pushed 2 new commits:

  1. reverted all changes made before to current master branch
  2. Log console output during replay to file #985 (2nd simpler solution)

Copy link

@pmconrad pmconrad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we decide to merge the second version, you should rebase -i to get rid of the first version. But not yet.

@@ -137,18 +134,7 @@ namespace fc {
file_appender::file_appender( const variant& args ) :
my( new impl( args.as<config>( FC_MAX_LOG_OBJECT_DEPTH ) ) )
{
try
{
fc::create_directories(my->cfg.filename.parent_path());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this must be moved to impl::impl(), not simply removed.

{
fc::create_directories(my->cfg.filename.parent_path());

if(!my->cfg.rotate)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...and this shouldn't be removed.

@cogutvalera
Copy link
Member Author

I've cleaned up my previous changes with 1st solution and forced new push commit

@abitmore
Copy link
Member

@cogutvalera: Peter said "not yet". He mean you should NOT rebase by now. Then you did it regardless :-/

@cogutvalera
Copy link
Member Author

If we decide to merge the second version, you should rebase -i to get rid of the first version. But not yet.

IMHO the 2nd solution is simpler and it works as required, then why to rebase "not yet" ?


try
{
fc::create_directories(cfg.filename.parent_path());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create_directories should happen before rotate_files.

@pmconrad
Copy link

The idea was to preserve the original version in case my ideas didn't work. I'm ok with the rebase if it does work as intended.

@pmconrad
Copy link

Thanks! @abitmore @jmjatlanta please re-review.

@jmjatlanta
Copy link

jmjatlanta commented Sep 25, 2018

There may be an edge case here that we may want to fix, but the chances of it happening are very remote. Scenario: Destructor called, then rotate_files gets the lock.

I am okay with that being there, as the file_appender is typically only destroyed at program exit, and the problem has probably been there from before this issue was opened.

@cogutvalera
Copy link
Member Author

@pmconrad @jmjatlanta Thanks guys !

@pmconrad pmconrad merged commit 8e1b47a into bitshares:master Oct 1, 2018
@cogutvalera
Copy link
Member Author

Thanks !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants