Open reinhard-brandstaedter opened 8 years ago
Oh I just found this in the output code:
# Extract tags from a hash of fields.
# Returns a tuple containing a hash of tags (as configured by send_as_tags)
# and a hash of fields that exclude the tags. If fields contains a key
# "tags" with an array, they will be moved to the tags hash (and each will be
# given a value of true)
#
# Example:
# # Given send_as_tags: ["bar"]
# original_fields = {"foo" => 1, "bar" => 2, "tags" => ["tag"]}
# tags, fields = extract_tags(original_fields)
# # tags: {"bar" => 2, "tag" => "true"} and fields: {"foo" => 1}
def extract_tags(fields)
remainder = fields.dup
tags = if remainder.has_key?("tags") && remainder["tags"].respond_to?(:inject)
remainder.delete("tags").inject({}) { |tags, tag| tags[tag] = "true"; tags }
else
{}
end
@send_as_tags.each { |key| (tags[key] = remainder.delete(key)) if remainder.has_key?(key) }
tags.delete_if { |key,value| value.nil? || value == "" }
remainder.delete_if { |key,value| value.nil? || value == "" }
[tags, remainder]
end
Seems this behaviour is on purpose. I've changed it in my local installation to:
remainder.delete("tags").inject({}) { |tags, tag| tags[tag] = fields[tag]; tags }
which allows me now to use the tags in the original message.tags and populate them with the values of the message.field[tag] value. It would make sense to remove the field that is also listed in the tags from the message.fields and add a condition there. This would allow users to use dynamic created tags in logstash (tags that names are not known) and populate it with values in influxdb.
If I'd know some ruby I'd like to add something like this:
if fields["tagname"].exists() && tags["tagname"].exists() {
tags["tagname"].value = fields["tagname"].value
fields.delete["tagname"]
}
Would that be a useful change?
Voila... a bit of Ruby code:
# Extract tags from a hash of fields.
# Returns a tuple containing a hash of tags (as configured by send_as_tags)
# and a hash of fields that exclude the tags. If fields contains a key
# "tags" with an array, they will be moved to the tags hash (and each will be
# given a value of true)
#
# Example:
# # Given send_as_tags: ["bar"]
# original_fields = {"foo" => 1, "bar" => 2, "tags" => ["tag"]}
# tags, fields = extract_tags(original_fields)
# # tags: {"bar" => 2, "tag" => "true"} and fields: {"foo" => 1}
def extract_tags(fields)
remainder = fields.dup
tags = if remainder.has_key?("tags") && remainder["tags"].respond_to?(:inject)
remainder.delete("tags").inject({}) { |tags, tag| tags[tag] = if remainder.has_key?(tag) then fields[tag] else "true" end; tags }
else
{}
end
@send_as_tags.each { |key| (tags[key] = remainder.delete(key)) if remainder.has_key?(key) }
tags.delete_if { |key,value| value.nil? || value == "" }
remainder.delete_if { |key,value| value.nil? || value == "" }
remainder.delete_if { |key,value| tags.has_key?(key) }
[tags, remainder]
end
Tnx! you should make a pull request :)
no permission and new to github, seems I can't create a pull request as it tells me I have no permission to send a pull request...
I'm wonder if it will be merged one day
Logstash version 2.3, influxdb 0.13 on Ubuntu 64bit linux I'm trying to write dynamic tag keys with values using "use_event_fields_for_data_points"
When I output to a file from logstash I get this, which looks ok:
However in influxdb I'm seeing tag key values of "true" only for my tags. On the wire I see these push requests which clearly show that the tags are written with "true" and additionally fields with the actual string value.
In influxdb I'm seeing:
So it seems tags (in logstash) and fields with the same name conflict in the output to influxdb and cause confusion.
The logstash config: