Open jamesharr opened 8 years ago
I have a similar requirement to produce metrics on a per event source basis. I have raised this issue for discussion in the logstash discussion forum and didn't see this particular enhancement discussion.
Trying to Count and Graph Multiple Event Sources
The concise version is that I'm trying to do this:
filter {
if [message] {
metrics {
meter => [ "%{host}" ]
add_tag => "metric"
}
}
}
output {
# only emit events with the 'metric' tag
if "metric" in [tags] {
stdout {
codec => rubydebug
}
}
}
With this valid configuration, the metrics filter does a great job at counting each message based on the event source host and producing the metrics, just not in a usable fashion when it comes to graphing time series.
I end up with metric events that contain an undetermined number of source hosts, I have no way to reliably filter the 1000+ possible server names to produce the individual metric events. If each event source host had it's own metrics event with common metric fields, very similar to the use case of the OP, I could easily produce charts on events per second per source host to a specific logstash instance.
This is particularly useful for determining what server is flooding my Redis queues with a large volume of events. I am currently doing this with statsd output plugin, however, it's pretty unreliable sending increment (1 event) stats and having statsd aggregate them and store in InfluxDB. It works, but it makes a lot more sense to have logstash calculate the rates and to store them in an elasticsearch metrics cluster.
Another slight niggle is that when a host stops sending events, the rate_1m never reaches zero, even after one minute it still producing a value over 0 which indicates to me there is an error with the way that value is being calculated although this is probably a gripe for separate plugin issue.
+1 I need this feature to get a structure I can use 'term split' for graphs later (kibana/grafana)
BTW:
this is not exactly the same as #17. In #17 the data is still structured as
split_%{key} = { <values> }
here it is flat and the name/key is a value pared with key name.
name = %{key}
<values>
Is there any traction on this? I'm running into a similar problem where I can create the metrics for a slew of dynamic names based on a field, but I cannot send them anywhere (in particular statsd) since I cannot reference them.
Similar to @berglh's issue, I'd like to track a running list of dynamic metrics to pinpoint specific hosts/indices in our pipeline for issues.
I have the same problem; wouldn't mind just using an additional script or something that does the cloning and splitting, but at the moment I cannot use the generated metrics events in a usable fashion for e.g. Kibana.
I've built a patch to metrics.rb, that introduces a new boolean option emit_single_metrics. If set to false - the default - it behaves as before, but if set to true, events are generated in the proposed flat format with one metric per event.
@chbuescher That's awesome, I've built the patch into the latest version of logstash-filter-metrics and going to test it shortly, thanks.
You can work around this by using Telegraf https://github.com/influxdata/telegraf
Along with sending the output to Elasticsearch, also send the event to Telegraf, which in turn can handle it like a proper metric event, aggregate and send out to InfluxDB or some other of its outputs.
@elvarb What receiver on Telegraf do you use? I've been actually been using the statsd plugin; and that's fine but it's pretty un-refined way of collecting statistics (spamming UDP packets for each Logstash event).
Can you elaborate on how Telegraf can split the various metric instances in a given event from a standard logstash-filter-metrics event? Thanks :+1:
@berglh I used just the standard tcp input plugin in telegraf, or if I used the statsd plugin. Don't have access to the system I set this up on anymore.
It basically meant that I was doubling the data coming from the logstash machine, one flow went to elasticsearch and the other to telegraf. Another benefit I got from this is that I selected which fields were sent over to telegraf so there I could use influxdb's tag system. So for an event that included a sourceip field that became a tag set in Influxdb, then I could filter in on only events for a specific sourceip value.
The logstash output I used was just plain tcp, I did not use the metric filter.
Here's a work-around that I have used for this use-case:
Manipulate the metric events to put metric values in a list using the ruby
filter (while recording the metric names in the list), and then use the split
filter to generate individual events for each metric name in the list:
filter {
if "firewall" in [tags] {
metrics {
meter => [ "firewall.%{firewall_rule}" ]
add_tag => "metric"
rates => [ 1 ]
flush_interval => 60
clear_interval => 3600
}
}
if "metric" in [tags] {
ruby {
code => "
metrics = []
event.to_hash.each_key do |k|
if k.start_with? 'firewall.'
values = event.remove(k)
values['name'] = k
metrics << values
end
end
event.set('metrics', metrics)
"
}
split {
field => "metrics"
target => "metric"
remove_field => "metrics"
add_tag => "metric"
}
}
}
With this, we get roughly the following output events:
{
@timestamp => "2016-02-21T15:04:28.414Z"
metric => {
name => "firewall.rule1"
rate_1m => 0.29
count => 8
}
tags => [ "metric" ]
}
{
@timestamp => "2016-02-21T15:04:28.414Z"
metric => {
name => "firewall.rule2"
rate_1m => 1
count => 60
}
tags => [ "metric" ]
}
Will this feature be added ?
@viranch, did you face any performance issues with the work around.? We will be having around 50000+ events to split
@1tarak I've been using this fork and it's still installing OK in the most recent logstash versions (6.7.1 for me): https://github.com/berglh/logstash-filter-metrics
Assuming you are using logstash in the default path:
# Prepare Ruby Build Environmet
export GEM_HOME=/usr/share/logstash/vendor/bundle/jruby/2.3.0
export JRUBY_HOME=/usr/share/logstash/vendor/jruby/bin
export PATH=$(echo $PATH):/usr/share/logstash/vendor/jruby/bin:/usr/share/logstash/vendor/bundle/jruby/2.3.0/bin
/usr/share/logstash/bin/logstash-plugin remove logstash-filter-metrics
cd /usr/share/logstash/plugins
git clone https://github.com/berglh/logstash-filter-metrics.git
cd /usr/share/logstash/plugins/logstash-filter-metrics
gem build logstash-filter-metrics.gemspec
../../bin/logstash-plugin install *.gem
Then you can do stuff like this:
metrics {
meter => [ "%{[@metadata][pipeline]}" ]
rates => 1
emit_single_metrics => true
add_field => {
"[@metadata][metric]" => "true"
"[@metadata][ls-dev-mode]" => "${LS_DEV_MODE:true}"
"[metric][description]" => "logstash_processor_pipeline_throughput"
"[service]" => "logstash"
"[type]" => "metrics"
"index" => "uq-metrics-%{+YYYY.MM.dd}"
}
}
metrics {
meter => [ "service" ]
rates => 1
emit_single_metrics => true
add_field => {
"[@metadata][metric]" => "true"
"[@metadata][ls-dev-mode]" => "${LS_DEV_MODE:true}"
"[service]" => "logstash"
"[type]" => "metrics"
"[metric][description]" => "logstash_processor_total_throughput"
"index" => "uq-metrics-%{+YYYY.MM.dd}"
}
}
@viranch, did you face any performance issues with the work around.? We will be having around 50000+ events to split
With that version of the metrics plugin I'm indexing about 4,100,000
metrics a day to a single Elasticsearch node metrics instance.
@berglh, Thank you! i will install and try.
@1tarak As I'm using this in production, if it's not working in Logstash 7 let me know and I'll merge in the latest changes from the upstream plugin so it should build properly there as well as I'll need to do this anyway after the logstash-filter-dns
bug is fixed :)
I am still using LS 6.2.3 in our prod. So we are good for now. Thank you!
@berglh Can you please rebase so it bumps to version 4.0.6? I'm using Logstash 6.8.1 and would like to try your patch. Thanks!
@berglh I'm using your patch based on 4.0.5 on 6.8.1 and it's working fine, thanks!
Is this working with Logstash 7?
@voiprodrigo I was using 7.9.1 and it was working fine, I'm just building 7.16.1 right now, I don't think this should be a problem though.
Ok, I've rebased for logstash 7.16.1. The primary branch has updated to main to reflect the upstream repo, and the patch is applied on main and on the tag v4.0.7. Patch applied fine, I'm assuming this will work.
Edit: I can confirm the multi-metrics patch is working on 7.16.1.
Thanks for the quick update! I'm running without issue on 7.16.1 as well.
I'd like to use the metrics plugin to generate 1 even per metric name. Clone can be used to manually split apart an event generated by
metrics
, however it's not always possible to know the name of every metric ahead of time. With 1 event per metric name, a slightly different event format would be useful where the event name is stored in a field instead of in a field-name. See below for examples.Examples of dynamic metrics: Firewall rule, country, domain (webserver), URL, log event source server, etc.
Example logstash configuration:
Example output from metrics plugin
Example output usage: