-
Notifications
You must be signed in to change notification settings - Fork 100
Move filewatch lib here, refactor and add new features. #171
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
Move filewatch lib here, refactor and add new features. #171
Conversation
Rakefile
Outdated
end | ||
|
||
desc "Run full check with custom Logstash path" | ||
task :custom_ls_check, :ls_dir do |task, args| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure why this is required? what I usually do is
LOGSTASH_SOURCE=1 bundle exec ...
not sure we need/want to add yet another custom rake task?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I use this to run the specs against any downloaded LS as well as my LS dev repo.
I have this:
logstash-2.1.3
logstash-2.2.2
logstash-2.3.4
logstash-2.4.0
logstash-2.4.1
logstash-5.0.0
logstash-5.2.1
logstash-5.2.2
logstash-5.3.0
logstash-5.4.3
logstash-5.5.0
logstash-5.5.1
logstash-5.6.2
logstash-5.6.4
logstash-5.6.8-SNAPSHOT
logstash-6.0.0
logstash-6.1.0
logstash-6.1.1
logstash-6.1.2
logstash-6.2.1
logstash-6.2.2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, that looks super useful, my problem is that this is specific to your workflow and is not really documented or used anywhere else, or is it?
project.sourceCompatibility = 1.8 | ||
|
||
dependencies { | ||
compileOnly group: 'org.jruby', name: 'jruby-complete', version: "9.1.13.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need this double dependencies on jruby-complete
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unsure. If buildscript
defines repositories
and dependencies
- does this mean that we can remove the root repositories
and dependencies
at lines 41 and 48?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed buildscript - seems to work.
About rake/gradle: I see we have very different rake/gradle tasks from other "hybrid" java plugins. I am wondering if we want to or should try to be consistent with that? |
lib/filewatch/bootstrap.rb
Outdated
# all the required constants and files | ||
# defined in one place | ||
module FileWatch | ||
HOST_OS_WINDOWS = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/) != nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI in Logstash https://github.com/elastic/logstash/blob/5e49b5d9cbb0a66482555a2ae57c0e89379f3923/lib/bootstrap/environment.rb#L45-L47 this is how we test for the windows platform. Should we be consistent?
def windows?
::Gem.win_platform?
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for pointing this out. It is a leftover from filewatch being standalone.
Will refactor this to use logstash/environment.
lib/filewatch/bootstrap.rb
Outdated
|
||
if HOST_OS_WINDOWS | ||
require "winhelper" | ||
FILEWATCH_INODE_METHOD = :win_inode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: like we don in LS for the windows?
method instead of using a constant, maybe it would be cleaner to define methods likes win_inodes?
and nix_inodes?
lib/filewatch/bootstrap.rb
Outdated
FILEWATCH_INODE_METHOD = :nix_inode | ||
end | ||
|
||
if defined?(JRUBY_VERSION) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in which case would that be undefined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
lib/filewatch/bootstrap.rb
Outdated
require_relative "read_handlers/base" | ||
|
||
# TODO [guy] make this a config option, perhaps. | ||
CurrentSerializerClass = SincedbRecordSerializer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since we don't support alternate serializers, I suggest we drop the CurrentSerializerClass
and directly set the SincedbRecordSerializer
into SincedbCollection
constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking that we will need to serialize to a ES based Shared State store soon - effectively JSON.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, but I am not sure this "empty" decoupling brings any actual of future value? for now it's just an "empty" abstraction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can remove it.
lib/filewatch/buftok.rb
Outdated
@input.empty? | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logstash core exposes BufferedTokenizer
(logstash-core/lib/logstash/util/buftok.rb
) do we also need it here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will switch. 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an addition attr_reader :input
. I will have to reopen the class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me see... AFAICT, attr_reader :input
is only used for the FileWatch::WatchedFile.reset_buffer
method?
def reset_buffer
@buffer.input.clear
end
But this could be replaced with the BufferedTokenizer.flush
method. It will be slighly less efficient but this is not a code hotspot so it should not have any impact?
end | ||
|
||
def add_path(path) | ||
return if @watching.member?(path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will likely fail if paths are not normalized, is that a consideration here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let me rephrase that: this will not catch duplicate paths unless they are normalized, is that a consideration here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked at this again. The path is either a file or a glob, if the glob is functionally the same as one we have seen before but not the same string then it will be added but at discovery any already discovered files will not be added to the collection - so a small overhead.
I checked the filewatch repo. This has been so since Aug 30, 2011. I don't recall any issues with this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, that seems reasonable ...
lib/filewatch/helper.rb
Outdated
# end | ||
# | ||
# If your temp directory is not on the same filesystem as the file you're | ||
# trying to write, you can provide a different temporary directory. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we add a check for this? or we could create the tmp file in the same directory as the target file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know. Its copied verbatim from the rails code. We control the call to this method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, upon closer inspection the implementation is not sync'ed with the comments. there is no usage of a temp directory and this implementation does not match the rails link above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll remove the comment.
lib/filewatch/observing_base.rb
Outdated
@@ -0,0 +1,68 @@ | |||
# encoding: utf-8 | |||
require_relative 'bootstrap' unless defined?(FileWatch) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this required?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO because I wanted the file input to not need to know about bootstrap.rb. So the entry point is either ObservingTail or ObservingRead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but can't the require order be done in a way that we don't need this kind of conditional require? in my experience these become hard to maintain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can remove the unless
.
lib/filewatch/observing_tail.rb
Outdated
include LogStash::Util::Loggable | ||
include ObservingBase | ||
|
||
def build_specific_processor(settings) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as discussed, I think it would be useful to document somehow the interface for the ObservingXxx
classes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
lib/filewatch/observing_tail.rb
Outdated
# observer here is the file input | ||
dispatcher = TailHandlers::Dispatch.new(sincedb_collection, observer, @settings) | ||
watch.subscribe(dispatcher) | ||
sincedb_collection.write("subscribe complete - shutting down") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"subscribe complete - shutting down"
is inconsistent with the ObservingRead
class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will make the same.
lib/filewatch/read_handlers/base.rb
Outdated
end | ||
end end | ||
|
||
require_relative "dispatch" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
having a require
at the end of the file is a bit weird. would it be better do a require "base"
at the beginning of the dispatch.rb
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
lib/logstash/inputs/file.rb
Outdated
# If 'delete' is specified then the file will be deleted. | ||
# If 'log' is specified then the full path of the file is logged to the file specified | ||
# in the `file_completed_log_path` setting. | ||
config :file_completed_action, :validate => ["delete", "log"], :default => "delete" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- could there be just a "do nothing" option? no delete, no log?
- also, are both options mutually exclusive?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"do nothing" - I suppose so. This was a last minute change - people have asked for this since forever. I was going to generate a 'special' event tagged with EOF having the path and force people to handle it in their output section - IIRC Jordan suggested to not do the event thing and give people an action to take.
Doing nothing is problematic though, because if a user is reading 10000 files, say, the user does not know when the file is done with. The discover glob order is indeterminately OS specific. Do you think we should sort the watched file collection before the iteration? The order is then known and we can doc that. Then again with striped reading, files will be done with in an order that is determined by its size with the smaller files finishing before the larger files regardless of the glob order or the collection sorted order.
"do both" - yeah sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great to reorder files.
It would be even better to have an option to tell how sort is done : by file name, by last modified file (from the oldest to the newest).
I’d love the second option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fbaligand
Do you see yourself using striped reading?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@guyboertje
I just looked at "striped reading", if I understand well, it lets to read files in parallel, with a chunk read mechanism.
IMHO, it doesn't let to read files in a particular order. That feature is particularly useful when start_position=beginning, and at Logstash startup, there are already numerous files. It can be important that files are read using a specific order : from the oldest to the newest, or alphabetically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fbaligand
Sorry, my question was a general one, not related to discovered file collection order.
I am happy to add collection ordering, with a new settings file_sort_by
-> "date"|"path" and file_sort_direction
-> "asc"|"desc".
Q: do these ^ settings names and values make sense? Are they useful in tail
mode (or which defaults are better for existing users in tail mode, IMO path + asc)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds great !
- Maybe replace "date" value by "last_modified" would be more meaningful ?
- Currently (so in tail mode), even if start_position=end, file input continues to discover new files every 15 seconds (by default) and read them from beginning. During these 15s, several files could arrive, that's why I find it relevant to apply order in tail mode.
- IMO, I prefer default as date + asc, as it means that files are processed as they arrived in time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@guyboertje
I just looked at FileBeat options for that (https://www.elastic.co/guide/en/beats/filebeat/current/configuration-filebeat-options.html#scan-sort).
They name it scan.sort
and scan.order
.
I like the prefix scan_
, I find it meaningfull.
lib/logstash/inputs/file.rb
Outdated
# If no changes are detected in tracked files in the last N days their sincedb | ||
# tracking record will expire and not be persisted. | ||
# This option protects against the well known inode recycling problem. (add reference) | ||
config :sincedb_clean_after, :validate => :number, :default => 14 # days |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
idea: could the actual file cleanup/delete be triggered by the sincedb cleanup?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love this new option !
it could potentially fix issue #173
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One other feature to fix inode recycling problem would be to regularly remove entries in sincedb where inode file does not exist anymore. For example every discover_interval
seconds.
I would love such a feature !
lib/logstash/inputs/file.rb
Outdated
# See the option `max_open_files` for more info, but note in "read" mode, close_older is | ||
# not required as files are closed at EOF | ||
# The default set internally is very large (the maximum positive Ruby integer) | ||
config :read_iterations, :validate => :number, :default => (2**(0.size * 8 - 2) - 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont understand this option - maybe we should rephrase it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not reuse the FIXNUM_MAX
constant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Constant.
Is the description confusing or the setting name? both?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for me both I guess, but if we have a good description then maybe the setting name will make more sense to me 😆
lib/logstash/inputs/file.rb
Outdated
# Specify the size in bytes of each chunk read in each read iteration | ||
# See `read_iterations` to see why and when to change this from the default. | ||
# The default set internally is 32768 (32KB) | ||
config :file_chunk_size, :validate => :number, :default => 32768 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that 32768
is defined twice (also in bootstrap.rb
), should it be a contant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
lib/logstash/inputs/file.rb
Outdated
|
||
# Join by ',' to make it easy for folks to know their own sincedb | ||
# generated path (vs, say, inspecting the @path array) | ||
@sincedb_path = File.join(sincedb_dir, ".sincedb_" + Digest::MD5.hexdigest(@path.join(","))) | ||
@sincedb_path = sincedb_dir.join(".sincedb_" + Digest::MD5.hexdigest(@path.join(","))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I notice code duplication with the sincedb filename generation, we should DRY it up
lib/logstash/inputs/file.rb
Outdated
end | ||
|
||
if tail_mode? | ||
require "filewatch/observing_tail" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need dynamic class loading here? I usually try to avoid that unless there is a good reason to. sometime, depending on test coverage it will hide errors in ont or the other file.
Ok, just completed a first review pass. Have we considered creating a whole new plugin instead of updating the new one? |
lib/filewatch/bootstrap.rb
Outdated
require "jruby_file_watch" | ||
end | ||
|
||
if HOST_OS_WINDOWS && defined?(JRUBY_VERSION) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to self: JRuby is guaranteed.
lib/filewatch/buftok.rb
Outdated
# or allow you to specify any delimiter token you so choose, which will then | ||
# be used by String#split to tokenize the input data | ||
|
||
attr_reader :delimiter, :input |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also note (following our discussion on attr_reader :input
below) that this copy of BufferedTokenizer
also exposes delimiter
but AFAICT this is not required our code? I will comment on where I believe this was required but I think it is actually a bug?
lib/filewatch/watched_file.rb
Outdated
end | ||
|
||
def buffer_delimiter_byte_size | ||
@buffer.delimiter_byte_size |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAICT BufferedTokenizer
does not have a delimiter_byte_size
method. It looks like the original intent might have been @buffer.delimiter.bytesize
? hence the need to expose attr_reader :delimiter
?
In any case, can't this be replaced with:
def buffer_delimiter_byte_size
@settings.delimiter_byte_size
end
or
def buffer_delimiter_byte_size
@settings.delimiter.bytesize
end
so that attr_reader delimiter
is not required and we can reuse the Logstash BufferedTokenizer
?
CHANGES Rakefile task :custom_ls_check. Removed compileOnly group: 'org.jruby'. Removed change def windows?. Done define methods likes win_inodes? and nix_inodes? I decided to define two modules to mixin to the WatchedFile class depending on defined?(JRUBY_VERSION). Fixed CurrentSerializerClass = SincedbRecordSerializer. Removed CurrentSerializerClass, use SincedbRecordSerializer use logstash core BufferedTokenizer. See below also exposes delimiter. See below replaced with the BufferedTokenizer.flush method? I opted for this solution, removed buftok file but not the test - making sure the LS version of BufferedTokenizer still does what we need it to do return if @watching.member?(path). Answered inline, this code has been as such since Aug 30, 2011. I don't recall any issues with this trying to write, you can provide a different temporary directory. should we add a check for this? Replied inline, IMO no action needed require_relative 'bootstrap' unless defined?(FileWatch). Completely reorganised require order throughout document somehow the interfaces contracts. Added documentation in the ObservingBase class - however, in preparing the documentation it became clear to me that the Processor - Dispatch separation no longer made sense, so I merged Dispatch into Processor with the necessary adjustments. Renamed ReadHandlers and TailHandlers to ReadMode and TailMode and moved the Handler classes into a Handlers module namespace to better reflect their intention without needing to add sincedb_collection.write("subscribe complete - shutting down"). Unified both arguments to this call require_relative "dispatch" - require at the end of the file is a bit weird. Completely reorganised require order throughout WatchedFile buffer_delimiter_byte_size unused. Removed could there be just a "do nothing" option? no delete, no log? Answered inline. Do nothing is undesirable IMO also, are both options mutually exclusive? Refactored to do one, other or both with a third way option read_iterations - I dont understand this option. Renamed to I see that 32768 is defined twice (also in bootstrap.rb), should it be a contant? Refactored to make both constants - needed sincedb filename generation, we should DRY it up. Refactored to handle sincedb_path determinism in one pass. Added a test to verify that a legacy sincedb file was renamed do we need dynamic class loading here? Refactored to load both module trees but only use one ADDITIONS Added sorting of watched_file_collection as per Fabian's request. Added sort specs. |
spec/inputs/file_tail_spec.rb
Outdated
run_thread_proc.call | ||
sleep 0.25 | ||
sleep 0.2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
idem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 both
expect(subject.extract("hello\r\nworld\r\n")).to eq ["hello", "world"] | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@guyboertje did another review pass! good stuff. |
@guyboertje |
sleep 0.25 | ||
first_lsof = lsof_proc.call | ||
expect(first_lsof.scan(file_path).size).to eq(1) | ||
wait(1).for{lsof_proc.call.scan(file_path).size}.to eq(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -0,0 +1 @@ | |||
1.0.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok! I wonder how we manage jar versions in other plugins?! this seems like a reasonable strategy. the other strategy would be to no have any versions number on the jar since it is not published outside the plugin?
I left a few more comments but overall I am LGTM at this stage!
|
Ah also, for the jar versioning - we should open a separate thread/issue to define a consistent strategy for jar(s) versioning across plugins. |
For my part, I like the jar to have a version, more so if the Java code is where the main functionality lies. Mainly for my own peace of mind, in seeing which version is inside the gem (I had to yank dissect 1.1.3 because it had the jar from 1.1.1 in it.) I suppose, for all hybrid plugins, we need to make sure that no jars get committed and pushed to Github, i.e. a gem publish will always rebuild the latest jar and include it in the gem. |
About the GZIP ensure block. |
begin | ||
closeable.close | ||
rescue Exception # IOException can be thrown by any of the Java classes that implement the Closable interface. | ||
# ignore this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
I'd suggest adding a log.warn here with something like "ignoring close excetion blablaba" so that if something else breaks somewhere else, we can maybe see a relation with a close exception if it happened.
|
||
private | ||
|
||
def close_java_closeable(closeable) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or maybe close_and_ignore
or something like that? because this method does 2 things, it closes but also explicitly ignores exceptions.
begin | ||
closeable.close | ||
rescue Exception # IOException can be thrown by any of the Java classes that implement the Closable interface. | ||
# ignore this | ||
logger.warn("Ignoring an IOException when closing an instance of #{closeable.class.name}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: add the exception detail too?
end | ||
sincedb_collection.unset_watched_file(watched_file) | ||
end | ||
|
||
private | ||
|
||
def close_java_closeable(closeable) | ||
def close_and_ignore_ioexception(closeable) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
rescue Exception # IOException can be thrown by any of the Java classes that implement the Closable interface. | ||
logger.warn("Ignoring an IOException when closing an instance of #{closeable.class.name}") | ||
rescue Exception => e # IOException can be thrown by any of the Java classes that implement the Closable interface. | ||
logger.warn("Ignoring an IOException when closing an instance of #{closeable.class.name}", "exception" => e.class.name, "message" => e.message) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe our "normal" exception logging pattern is more like this no?
logger.warn("some problem happened", :exception => e, :backtrace => e.backtrace)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a little bit wary of passing an object as the value in a logging statement because it simply calls to_s
on the object.
I will change this case to :exception => e
We don't need the backtrace in this case because we know exactly where it is happening.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
while looking at the exception logging, throughout the plugin I think we should followup with a cleanup issue to have a more uniform way of logging using the following pattern:
|
LGTM² |
Great ! |
Now for the doc changes. |
I am going to merge this and deal with the doc changes in a new PR. |
NOTES for Reviewers:
There are a lot of code changes, mainly to split the monolithic procedures filewatch had before into separate classes.