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

Detect log rotation and release renamed files #106

Closed
wants to merge 5 commits into from

Conversation

kenhys
Copy link
Collaborator

@kenhys kenhys commented Nov 26, 2020

In the previous vesions, there was no way to detect log rotation
event when log file was rotated.

It causes that rotated log file was grabbed by DaemonLogger.
This was unexpected behavior.

This commit fixes by reopening log file correctly.

NOTE: This PR depends on inotify so only linux was supported.

@kenhys
Copy link
Collaborator Author

kenhys commented Nov 26, 2020

A bit more work is needed to fix fluent/fluentd#2426 (comment) completely.

@kenhys kenhys force-pushed the reopen-by-rotate branch 2 times, most recently from 49dd8e4 to cded489 Compare November 26, 2020 08:32
serverengine.gemspec Outdated Show resolved Hide resolved
@repeatedly
Copy link
Contributor

serverengine has own log rotation mechanizm and it doesn't have this problem, right?
If this problem happens with only external log rotation tool, how about rb-inofity is optional?

@kenhys
Copy link
Collaborator Author

kenhys commented Nov 30, 2020

I've changed dependency to optional.

@kenhys kenhys marked this pull request as ready for review December 4, 2020 00:47
@repeatedly
Copy link
Contributor

Looks good to me with optional approach :)

@kenhys kenhys force-pushed the reopen-by-rotate branch from 557e2fd to a2e10fe Compare May 19, 2021 02:40
In the previous vesions, there was no way to detect log rotation
event when log file was rotated by external tool (logrotate)

It causes that rotated log file was grabbed by DaemonLogger.
This was unexpected behavior.

This commit fixes by reopening log file correctly.

NOTE: This PR depends on inotify so only linux was supported.
Usually Fluentd built-in rotation works so this feature is
optional.

Signed-off-by: Kentaro Hayashi <[email protected]>
@kenhys kenhys force-pushed the reopen-by-rotate branch from a2e10fe to 41563ff Compare May 19, 2021 02:43
@kenhys
Copy link
Collaborator Author

kenhys commented May 19, 2021

I've rebased PR to follow recent master.

@ashie ashie force-pushed the reopen-by-rotate branch 3 times, most recently from 3bac90c to e925dbf Compare May 21, 2021 02:40
@ashie ashie force-pushed the reopen-by-rotate branch from e925dbf to 73f1c94 Compare May 21, 2021 02:41
@ashie
Copy link
Collaborator

ashie commented May 21, 2021

I've added CI for with and w/o rb-notify.
All checks are passed.

@ashie
Copy link
Collaborator

ashie commented May 24, 2021

I've added CI for with and w/o rb-notify.
All checks are passed.

No, still rb-inotify isn't recognized:

Pending:
  ServerEngine::DaemonLogger reopen log when path is renamed
    # not supported except Linux with inotify
    # ./spec/daemon_logger_spec.rb:182
  ServerEngine::DaemonLogger reopen log when path is renamed by external process
    # not supported except Linux with inotify
    # ./spec/daemon_logger_spec.rb:192
  ServerEngine::DaemonLogger reopen logger when file is renamed
    # not supported except Linux with inotify
    # ./spec/daemon_logger_spec.rb:205
  ServerEngine::MultiThreadServer raises SystemExit when all workers exit with specified code by unrecoverable_exit_codes
    # unrecoverable_exit_codes supported only for multi process workers
    # ./spec/multi_process_server_spec.rb:63

@ashie
Copy link
Collaborator

ashie commented May 24, 2021

Hmm, when I test it on my local environment, sometimes a test stalls.

It seems that it reproduced also on GitHub Actions:
https://github.com/treasure-data/serverengine/pull/106/checks?check_run_id=2652587049

@kenhys Could you take look this?

@kenhys
Copy link
Collaborator Author

kenhys commented May 24, 2021

In my local environment, IO logger test case seems to stall.
(Not identified the reason yet)

% bundle exec rspec -f documentation 2>&1 | tee ../take12.log

ServerEngine::BlockingFlag
  set and reset
  set! and reset! return whether it toggled the state
  wait_for_set timeout
  wait_for_reset timeout
  wait

ServerEngine::DaemonLogger
  reopen
  reset path
  default level is debug
  level set by int
  level set by string
  unknown level
  rotation
  IO logger

@kenhys
Copy link
Collaborator Author

kenhys commented May 24, 2021

It may be caused by log.reopen!.

it 'IO logger' do
    io = StringIO.new
    io.should_receive(:write)
    io.should_not_receive(:reopen)

    log = DaemonLogger.new(io)
    log.debug "stdout logging test"
    log.reopen! # <= STALLED HERE
  end

@kenhys
Copy link
Collaborator Author

kenhys commented May 24, 2021

I've misunderstand rspec workflow.

executing do block, call after (if exists), then show it ... label.
So, 'inter-process locking on rotation' test case is stalling. (next test case for 'IO logger')

@kenhys
Copy link
Collaborator Author

kenhys commented May 24, 2021

@kenhys
Copy link
Collaborator Author

kenhys commented May 25, 2021

As far as I know, only 'inter-process locking on rotation' test case stalls. (frequency 2-3 stalls/10times)

@kenhys
Copy link
Collaborator Author

kenhys commented May 25, 2021

As far as I know, only 'inter-process locking on rotation' test case stalls. (frequency 2-3 stalls/10times)

It tend to stall when process(pid2) writes the limit (~30 bytes = log_rotate_age * log_rotate_size), proces(pid2) stucks.

@kenhys
Copy link
Collaborator Author

kenhys commented May 25, 2021

To clarify the issue:

  • master (not stall)
  • PR with rb-inotify (sometimes stalls with 'inter-process locking on rotation' test case)
  • PR without rb-inotify (not stall)
bundle install --with inotify
bundle exec rspec -f documentation -e inter

@kenhys
Copy link
Collaborator Author

kenhys commented Jun 2, 2021

It tend to:

pass:

  • @inotify.watch event is fired for process A and Process B (each process close @logdev and reopen it)

stall:

  • @inotify.watch event is fired for process A only

@kenhys
Copy link
Collaborator Author

kenhys commented Jun 2, 2021

It tend to:

pass:

* `@inotify.watch` event is fired for process A and Process B (each process close @logdev and reopen it)

stall:

* `@inotify.watch` event is fired for process A only

some extent true, but not applied to all cases...

@kenhys
Copy link
Collaborator Author

kenhys commented Jun 2, 2021

I'll check the current implementation, again.

@ashie
Copy link
Collaborator

ashie commented Aug 6, 2021

I've added a work around, but I'm not sure it's correct fix.
Further verification is needed.

@ashie
Copy link
Collaborator

ashie commented Jun 9, 2022

I open another pull request to resolve this issue: #127

@ashie ashie closed this in #127 Jun 13, 2022
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