Trying to pass binary files through Logstash

Viewed 590

Some process is producing into my Kafka binary files (from Java it comes as bytearray).

I'm trying to consume from Kafka with Logstash and upload the file into s3.

My pipeline:

input {
  kafka {
    bootstrap_servers => "my-broker:9092"
    topic => "my-topic"
    partition_assignment_strategy => "org.apache.kafka.clients.consumer.StickyAssignor"
    value_deserializer_class => "org.apache.kafka.common.serialization.ByteArrayDeserializer"
  }
}
filter {
  mutate {
    remove_field => ["@timestamp", "host"]
  }
}
output {
  s3 {
    region => "eu-west-1"
    bucket => "my_bucket"
    time_file => 1
    prefix => "files/"
    rotation_strategy => "time"
  }
}

As you can see I used a different deserializer class. However, it seems that Logstash uses by default a coded that converts the bytes array to string. My goal is to upload the file to s3 as it is. Is there any codec known that doesn't do anything to the input data and upload it as it is to?

Right now the files are uploaded to s3, but I can't read them or open them. The binary content was corrupted by Logstash somehow. For example - I tried sending a gzip that contains multiple files inside and I can't open it afterwards in s3.

The warning that I get on Logstash:

0-06-02T10:49:29,149][WARN ][logstash.codecs.plain    ][my_pipeline] Received an event that has a different character encoding than you configured. {:text=>"7z\\xBC\\xAF'\\u001C\\u0000\\u0002\\xA6j<........more binary data", :expected_charset=>"UTF-8"}
2 Answers

I'm not sure that Logstash is the best fit for passing binary data and I in the end implemented a Java consumer but the following solution worked for me with Logstash:

  1. The data was sent to Kafka can be serialized to binary data. For example, I used filebeat to send the binary data so if Kafka`s output module there is a parameter that is called "value_serializer" and it should be set to "org.apache.kafka.common.serialization.ByteArraySerializer"
  2. In your Logstash settings (kafka input) define the value_deserializer_class to "org.apache.kafka.common.serialization.ByteArrayDeserializer" just as I did in the post
  3. Your output in logstash can be any resource that can get binary data.

Be aware, that the output will get a binary data and you will need to deserialize it.

I don't think you really understand what logstash is for.

As it's name log-stash it is for streaming ascii type of files using EOL delimiter to deffer between different log events.

I did managed to find community developed kafkaBeat for reading data from Kafka Topics, there are 2 options:

  • kafkabeat - Reads data from Kafka topics.
  • kafkabeat2 - Reads data (json or plain) from Kafka topics.

I didn't test those my own, but using the S3 output option with those might do the trick. If the S3 option is not yet supported you can develop it yourself and push it to the open-source so everyone can enjoy it :-)

Related