Skip to content

Provide supported path for Input and Output plugins to not have codecs #14828

Open
@yaauie

Description

@yaauie

While the base classes for Input and Output plugins include a to-be-inherited codec declaration, not all plugins use the resulting @codec that is instantiated for the plugin. On these plugins, it is still possible to specify codec => xyz in a pipeline configuration, but how that specification is handled is entirely up to the plugin (in most cases it is simply silently ignored). See :no_codec!: for a non-exhaustive list of affected plugins.

While it would be tempting for these plugins to mark the codec that they inherit as obsolete to rely on Logstash's plugin DSL rejecting an explicit codec, plugins defined in this way cannot be instantiated; obsolete causes the @codec ivar to not get set (even if the config also provides a default value), and the Logstash internals that convert the LIR into a CompiledPipeline will throw NoMethodError's trying to set up a nil codec after the input/output has been Plugin#initialize-d and before it has been Plugin#register-ed.

  1. Logstash internals should be tolerant of a nil (unset) codec during and after pipeline initialization
  2. Plugins should be able to define in-code that they do not have a codec in a way that makes them continue to work on older Logstashes where the above issue exists. One possible solution would be a support adapter that makes use of obsolete, but hooks into Plugin#register to ensure that the @codec ivar is set when run on Logstashes where it is required.
    module LogStash::PluginMixins::NoCodecSupport
    
      def self.included(base_class)
        fail(ArgumentError, "`#{base}` must inherit LogStash::Plugin") unless base < LogStash::Plugin
    
        base.instance_exec do
          config :codec, obsolete: 'this plugin does not use a user-configurable codec'
        end
      end
    
      if true # TODO: conditionally on LS not being broken for nil-`@codec`
    
        NOOP_CODEC = Class.new(LogStash::Codecs::Base) do
          config_name 'noop'
          # TODO: should error if used to decode/encode/multi_encode/encode_sync
        end
    
        def initialize(*a)
          super
    
          @codec = NOOP_CODEC.new("id" => "#{id}/NOOP_CODEC")
        end
      end
    end

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions