logstash-lib 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +24 -0
- data/.tailor +8 -0
- data/.travis.yml +12 -0
- data/CHANGELOG +1185 -0
- data/CONTRIBUTING.md +61 -0
- data/CONTRIBUTORS +79 -0
- data/LICENSE +14 -0
- data/Makefile +460 -0
- data/README.md +120 -0
- data/STYLE.md +96 -0
- data/bin/logstash +37 -0
- data/bin/logstash-test +4 -0
- data/bin/logstash-web +4 -0
- data/bin/logstash.lib.sh +78 -0
- data/bot/check_pull_changelog.rb +89 -0
- data/docs/configuration.md +260 -0
- data/docs/docgen.rb +242 -0
- data/docs/extending/example-add-a-new-filter.md +121 -0
- data/docs/extending/index.md +91 -0
- data/docs/flags.md +43 -0
- data/docs/generate_index.rb +28 -0
- data/docs/index.html.erb +56 -0
- data/docs/learn.md +46 -0
- data/docs/life-of-an-event.md +109 -0
- data/docs/logging-tool-comparisons.md +60 -0
- data/docs/plugin-doc.html.erb +91 -0
- data/docs/plugin-milestones.md +41 -0
- data/docs/plugin-synopsis.html.erb +24 -0
- data/docs/release-engineering.md +46 -0
- data/docs/release-test-results.md +14 -0
- data/docs/repositories.md +35 -0
- data/docs/tutorials/10-minute-walkthrough/apache-elasticsearch.conf +35 -0
- data/docs/tutorials/10-minute-walkthrough/apache-parse.conf +33 -0
- data/docs/tutorials/10-minute-walkthrough/apache_log.1 +1 -0
- data/docs/tutorials/10-minute-walkthrough/apache_log.2.bz2 +0 -0
- data/docs/tutorials/10-minute-walkthrough/hello-search.conf +25 -0
- data/docs/tutorials/10-minute-walkthrough/hello.conf +16 -0
- data/docs/tutorials/10-minute-walkthrough/index.md +124 -0
- data/docs/tutorials/10-minute-walkthrough/step-5-output.txt +17 -0
- data/docs/tutorials/getting-started-centralized-overview-diagram.png +0 -0
- data/docs/tutorials/getting-started-centralized-overview-diagram.xml +1 -0
- data/docs/tutorials/getting-started-centralized.md +217 -0
- data/docs/tutorials/getting-started-simple.md +200 -0
- data/docs/tutorials/just-enough-rabbitmq-for-logstash.md +201 -0
- data/docs/tutorials/media/frontend-response-codes.png +0 -0
- data/docs/tutorials/metrics-from-logs.md +84 -0
- data/docs/tutorials/zeromq.md +118 -0
- data/extract_services.rb +29 -0
- data/gembag.rb +64 -0
- data/lib/logstash-event.rb +2 -0
- data/lib/logstash.rb +4 -0
- data/lib/logstash/JRUBY-6970-openssl.rb +22 -0
- data/lib/logstash/JRUBY-6970.rb +102 -0
- data/lib/logstash/agent.rb +305 -0
- data/lib/logstash/certs/cacert.pem +3895 -0
- data/lib/logstash/codecs/base.rb +49 -0
- data/lib/logstash/codecs/compress_spooler.rb +50 -0
- data/lib/logstash/codecs/dots.rb +18 -0
- data/lib/logstash/codecs/edn.rb +28 -0
- data/lib/logstash/codecs/edn_lines.rb +36 -0
- data/lib/logstash/codecs/fluent.rb +55 -0
- data/lib/logstash/codecs/graphite.rb +114 -0
- data/lib/logstash/codecs/json.rb +41 -0
- data/lib/logstash/codecs/json_lines.rb +52 -0
- data/lib/logstash/codecs/json_spooler.rb +22 -0
- data/lib/logstash/codecs/line.rb +58 -0
- data/lib/logstash/codecs/msgpack.rb +43 -0
- data/lib/logstash/codecs/multiline.rb +189 -0
- data/lib/logstash/codecs/netflow.rb +342 -0
- data/lib/logstash/codecs/netflow/util.rb +212 -0
- data/lib/logstash/codecs/noop.rb +19 -0
- data/lib/logstash/codecs/oldlogstashjson.rb +56 -0
- data/lib/logstash/codecs/plain.rb +48 -0
- data/lib/logstash/codecs/rubydebug.rb +22 -0
- data/lib/logstash/codecs/spool.rb +38 -0
- data/lib/logstash/config/Makefile +4 -0
- data/lib/logstash/config/config_ast.rb +380 -0
- data/lib/logstash/config/file.rb +39 -0
- data/lib/logstash/config/grammar.rb +3504 -0
- data/lib/logstash/config/grammar.treetop +241 -0
- data/lib/logstash/config/mixin.rb +464 -0
- data/lib/logstash/config/registry.rb +13 -0
- data/lib/logstash/config/test.conf +18 -0
- data/lib/logstash/errors.rb +10 -0
- data/lib/logstash/event.rb +262 -0
- data/lib/logstash/filters/advisor.rb +178 -0
- data/lib/logstash/filters/alter.rb +173 -0
- data/lib/logstash/filters/anonymize.rb +93 -0
- data/lib/logstash/filters/base.rb +190 -0
- data/lib/logstash/filters/checksum.rb +50 -0
- data/lib/logstash/filters/cidr.rb +76 -0
- data/lib/logstash/filters/cipher.rb +145 -0
- data/lib/logstash/filters/clone.rb +35 -0
- data/lib/logstash/filters/collate.rb +114 -0
- data/lib/logstash/filters/csv.rb +94 -0
- data/lib/logstash/filters/date.rb +244 -0
- data/lib/logstash/filters/dns.rb +201 -0
- data/lib/logstash/filters/drop.rb +32 -0
- data/lib/logstash/filters/elapsed.rb +256 -0
- data/lib/logstash/filters/elasticsearch.rb +73 -0
- data/lib/logstash/filters/environment.rb +27 -0
- data/lib/logstash/filters/extractnumbers.rb +84 -0
- data/lib/logstash/filters/gelfify.rb +52 -0
- data/lib/logstash/filters/geoip.rb +145 -0
- data/lib/logstash/filters/grep.rb +153 -0
- data/lib/logstash/filters/grok.rb +425 -0
- data/lib/logstash/filters/grokdiscovery.rb +75 -0
- data/lib/logstash/filters/i18n.rb +51 -0
- data/lib/logstash/filters/json.rb +90 -0
- data/lib/logstash/filters/json_encode.rb +52 -0
- data/lib/logstash/filters/kv.rb +232 -0
- data/lib/logstash/filters/metaevent.rb +68 -0
- data/lib/logstash/filters/metrics.rb +237 -0
- data/lib/logstash/filters/multiline.rb +241 -0
- data/lib/logstash/filters/mutate.rb +399 -0
- data/lib/logstash/filters/noop.rb +21 -0
- data/lib/logstash/filters/prune.rb +149 -0
- data/lib/logstash/filters/punct.rb +32 -0
- data/lib/logstash/filters/railsparallelrequest.rb +86 -0
- data/lib/logstash/filters/range.rb +142 -0
- data/lib/logstash/filters/ruby.rb +42 -0
- data/lib/logstash/filters/sleep.rb +111 -0
- data/lib/logstash/filters/split.rb +64 -0
- data/lib/logstash/filters/sumnumbers.rb +73 -0
- data/lib/logstash/filters/syslog_pri.rb +107 -0
- data/lib/logstash/filters/translate.rb +121 -0
- data/lib/logstash/filters/unique.rb +29 -0
- data/lib/logstash/filters/urldecode.rb +57 -0
- data/lib/logstash/filters/useragent.rb +112 -0
- data/lib/logstash/filters/uuid.rb +58 -0
- data/lib/logstash/filters/xml.rb +139 -0
- data/lib/logstash/filters/zeromq.rb +123 -0
- data/lib/logstash/filterworker.rb +122 -0
- data/lib/logstash/inputs/base.rb +125 -0
- data/lib/logstash/inputs/collectd.rb +306 -0
- data/lib/logstash/inputs/drupal_dblog.rb +323 -0
- data/lib/logstash/inputs/drupal_dblog/jdbcconnection.rb +66 -0
- data/lib/logstash/inputs/elasticsearch.rb +140 -0
- data/lib/logstash/inputs/eventlog.rb +129 -0
- data/lib/logstash/inputs/eventlog/racob_fix.rb +44 -0
- data/lib/logstash/inputs/exec.rb +69 -0
- data/lib/logstash/inputs/file.rb +146 -0
- data/lib/logstash/inputs/ganglia.rb +127 -0
- data/lib/logstash/inputs/ganglia/gmondpacket.rb +146 -0
- data/lib/logstash/inputs/ganglia/xdr.rb +327 -0
- data/lib/logstash/inputs/gelf.rb +138 -0
- data/lib/logstash/inputs/gemfire.rb +222 -0
- data/lib/logstash/inputs/generator.rb +97 -0
- data/lib/logstash/inputs/graphite.rb +41 -0
- data/lib/logstash/inputs/heroku.rb +51 -0
- data/lib/logstash/inputs/imap.rb +136 -0
- data/lib/logstash/inputs/irc.rb +84 -0
- data/lib/logstash/inputs/log4j.rb +136 -0
- data/lib/logstash/inputs/lumberjack.rb +53 -0
- data/lib/logstash/inputs/pipe.rb +57 -0
- data/lib/logstash/inputs/rabbitmq.rb +126 -0
- data/lib/logstash/inputs/rabbitmq/bunny.rb +118 -0
- data/lib/logstash/inputs/rabbitmq/hot_bunnies.rb +1 -0
- data/lib/logstash/inputs/rabbitmq/march_hare.rb +129 -0
- data/lib/logstash/inputs/redis.rb +263 -0
- data/lib/logstash/inputs/relp.rb +106 -0
- data/lib/logstash/inputs/s3.rb +279 -0
- data/lib/logstash/inputs/snmptrap.rb +87 -0
- data/lib/logstash/inputs/sqlite.rb +185 -0
- data/lib/logstash/inputs/sqs.rb +172 -0
- data/lib/logstash/inputs/stdin.rb +46 -0
- data/lib/logstash/inputs/stomp.rb +84 -0
- data/lib/logstash/inputs/syslog.rb +237 -0
- data/lib/logstash/inputs/tcp.rb +231 -0
- data/lib/logstash/inputs/threadable.rb +18 -0
- data/lib/logstash/inputs/twitter.rb +82 -0
- data/lib/logstash/inputs/udp.rb +81 -0
- data/lib/logstash/inputs/unix.rb +163 -0
- data/lib/logstash/inputs/varnishlog.rb +48 -0
- data/lib/logstash/inputs/websocket.rb +50 -0
- data/lib/logstash/inputs/wmi.rb +72 -0
- data/lib/logstash/inputs/xmpp.rb +81 -0
- data/lib/logstash/inputs/zenoss.rb +143 -0
- data/lib/logstash/inputs/zeromq.rb +165 -0
- data/lib/logstash/kibana.rb +113 -0
- data/lib/logstash/loadlibs.rb +9 -0
- data/lib/logstash/logging.rb +89 -0
- data/lib/logstash/monkeypatches-for-bugs.rb +2 -0
- data/lib/logstash/monkeypatches-for-debugging.rb +47 -0
- data/lib/logstash/monkeypatches-for-performance.rb +66 -0
- data/lib/logstash/multiqueue.rb +53 -0
- data/lib/logstash/namespace.rb +16 -0
- data/lib/logstash/outputs/base.rb +120 -0
- data/lib/logstash/outputs/boundary.rb +116 -0
- data/lib/logstash/outputs/circonus.rb +78 -0
- data/lib/logstash/outputs/cloudwatch.rb +351 -0
- data/lib/logstash/outputs/csv.rb +55 -0
- data/lib/logstash/outputs/datadog.rb +93 -0
- data/lib/logstash/outputs/datadog_metrics.rb +123 -0
- data/lib/logstash/outputs/elasticsearch.rb +332 -0
- data/lib/logstash/outputs/elasticsearch/elasticsearch-template.json +44 -0
- data/lib/logstash/outputs/elasticsearch_http.rb +256 -0
- data/lib/logstash/outputs/elasticsearch_river.rb +214 -0
- data/lib/logstash/outputs/email.rb +299 -0
- data/lib/logstash/outputs/exec.rb +40 -0
- data/lib/logstash/outputs/file.rb +180 -0
- data/lib/logstash/outputs/ganglia.rb +75 -0
- data/lib/logstash/outputs/gelf.rb +208 -0
- data/lib/logstash/outputs/gemfire.rb +103 -0
- data/lib/logstash/outputs/google_bigquery.rb +570 -0
- data/lib/logstash/outputs/google_cloud_storage.rb +431 -0
- data/lib/logstash/outputs/graphite.rb +143 -0
- data/lib/logstash/outputs/graphtastic.rb +185 -0
- data/lib/logstash/outputs/hipchat.rb +80 -0
- data/lib/logstash/outputs/http.rb +142 -0
- data/lib/logstash/outputs/irc.rb +80 -0
- data/lib/logstash/outputs/jira.rb +109 -0
- data/lib/logstash/outputs/juggernaut.rb +105 -0
- data/lib/logstash/outputs/librato.rb +146 -0
- data/lib/logstash/outputs/loggly.rb +93 -0
- data/lib/logstash/outputs/lumberjack.rb +51 -0
- data/lib/logstash/outputs/metriccatcher.rb +103 -0
- data/lib/logstash/outputs/mongodb.rb +81 -0
- data/lib/logstash/outputs/nagios.rb +119 -0
- data/lib/logstash/outputs/nagios_nsca.rb +123 -0
- data/lib/logstash/outputs/null.rb +18 -0
- data/lib/logstash/outputs/opentsdb.rb +101 -0
- data/lib/logstash/outputs/pagerduty.rb +79 -0
- data/lib/logstash/outputs/pipe.rb +132 -0
- data/lib/logstash/outputs/rabbitmq.rb +96 -0
- data/lib/logstash/outputs/rabbitmq/bunny.rb +135 -0
- data/lib/logstash/outputs/rabbitmq/hot_bunnies.rb +1 -0
- data/lib/logstash/outputs/rabbitmq/march_hare.rb +143 -0
- data/lib/logstash/outputs/redis.rb +245 -0
- data/lib/logstash/outputs/riak.rb +152 -0
- data/lib/logstash/outputs/riemann.rb +109 -0
- data/lib/logstash/outputs/s3.rb +356 -0
- data/lib/logstash/outputs/sns.rb +124 -0
- data/lib/logstash/outputs/solr_http.rb +78 -0
- data/lib/logstash/outputs/sqs.rb +141 -0
- data/lib/logstash/outputs/statsd.rb +116 -0
- data/lib/logstash/outputs/stdout.rb +53 -0
- data/lib/logstash/outputs/stomp.rb +67 -0
- data/lib/logstash/outputs/syslog.rb +145 -0
- data/lib/logstash/outputs/tcp.rb +145 -0
- data/lib/logstash/outputs/udp.rb +38 -0
- data/lib/logstash/outputs/websocket.rb +46 -0
- data/lib/logstash/outputs/websocket/app.rb +29 -0
- data/lib/logstash/outputs/websocket/pubsub.rb +45 -0
- data/lib/logstash/outputs/xmpp.rb +78 -0
- data/lib/logstash/outputs/zabbix.rb +108 -0
- data/lib/logstash/outputs/zeromq.rb +125 -0
- data/lib/logstash/pipeline.rb +286 -0
- data/lib/logstash/plugin.rb +150 -0
- data/lib/logstash/plugin_mixins/aws_config.rb +93 -0
- data/lib/logstash/program.rb +15 -0
- data/lib/logstash/runner.rb +238 -0
- data/lib/logstash/sized_queue.rb +8 -0
- data/lib/logstash/test.rb +183 -0
- data/lib/logstash/threadwatchdog.rb +37 -0
- data/lib/logstash/time_addon.rb +33 -0
- data/lib/logstash/util.rb +106 -0
- data/lib/logstash/util/buftok.rb +139 -0
- data/lib/logstash/util/charset.rb +39 -0
- data/lib/logstash/util/fieldreference.rb +50 -0
- data/lib/logstash/util/password.rb +25 -0
- data/lib/logstash/util/prctl.rb +11 -0
- data/lib/logstash/util/relp.rb +326 -0
- data/lib/logstash/util/require-helper.rb +18 -0
- data/lib/logstash/util/socket_peer.rb +7 -0
- data/lib/logstash/util/zenoss.rb +566 -0
- data/lib/logstash/util/zeromq.rb +47 -0
- data/lib/logstash/version.rb +6 -0
- data/locales/en.yml +170 -0
- data/logstash-event.gemspec +29 -0
- data/logstash.gemspec +128 -0
- data/patterns/firewalls +60 -0
- data/patterns/grok-patterns +91 -0
- data/patterns/haproxy +37 -0
- data/patterns/java +3 -0
- data/patterns/linux-syslog +14 -0
- data/patterns/mcollective +1 -0
- data/patterns/mcollective-patterns +4 -0
- data/patterns/nagios +108 -0
- data/patterns/postgresql +3 -0
- data/patterns/redis +3 -0
- data/patterns/ruby +2 -0
- data/pkg/build.sh +135 -0
- data/pkg/centos/after-install.sh +1 -0
- data/pkg/centos/before-install.sh +10 -0
- data/pkg/centos/before-remove.sh +11 -0
- data/pkg/centos/sysconfig +15 -0
- data/pkg/debian/after-install.sh +5 -0
- data/pkg/debian/before-install.sh +13 -0
- data/pkg/debian/before-remove.sh +13 -0
- data/pkg/debian/build.sh +34 -0
- data/pkg/debian/debian/README +6 -0
- data/pkg/debian/debian/changelog +17 -0
- data/pkg/debian/debian/compat +1 -0
- data/pkg/debian/debian/control +16 -0
- data/pkg/debian/debian/copyright +27 -0
- data/pkg/debian/debian/dirs +19 -0
- data/pkg/debian/debian/docs +0 -0
- data/pkg/debian/debian/logstash.default +39 -0
- data/pkg/debian/debian/logstash.init +201 -0
- data/pkg/debian/debian/logstash.install +1 -0
- data/pkg/debian/debian/logstash.logrotate +9 -0
- data/pkg/debian/debian/logstash.postinst +68 -0
- data/pkg/debian/debian/logstash.postrm +23 -0
- data/pkg/debian/debian/manpage.1.ex +59 -0
- data/pkg/debian/debian/preinst.ex +37 -0
- data/pkg/debian/debian/prerm.ex +40 -0
- data/pkg/debian/debian/release.conf +5 -0
- data/pkg/debian/debian/rules +80 -0
- data/pkg/debian/debian/watch.ex +22 -0
- data/pkg/logrotate.conf +8 -0
- data/pkg/logstash-web.default +41 -0
- data/pkg/logstash-web.sysv.debian +201 -0
- data/pkg/logstash-web.upstart.ubuntu +18 -0
- data/pkg/logstash.default +45 -0
- data/pkg/logstash.sysv.debian +202 -0
- data/pkg/logstash.sysv.redhat +158 -0
- data/pkg/logstash.upstart.ubuntu +20 -0
- data/pkg/rpm/SOURCES/logstash.conf +26 -0
- data/pkg/rpm/SOURCES/logstash.init +80 -0
- data/pkg/rpm/SOURCES/logstash.logrotate +8 -0
- data/pkg/rpm/SOURCES/logstash.sysconfig +3 -0
- data/pkg/rpm/SOURCES/logstash.wrapper +105 -0
- data/pkg/rpm/SPECS/logstash.spec +180 -0
- data/pkg/rpm/readme.md +4 -0
- data/pkg/ubuntu/after-install.sh +7 -0
- data/pkg/ubuntu/before-install.sh +12 -0
- data/pkg/ubuntu/before-remove.sh +13 -0
- data/pull_release_note.rb +25 -0
- data/require-analyze.rb +22 -0
- data/spec/README.md +14 -0
- data/spec/codecs/edn.rb +40 -0
- data/spec/codecs/edn_lines.rb +53 -0
- data/spec/codecs/graphite.rb +96 -0
- data/spec/codecs/json.rb +57 -0
- data/spec/codecs/json_lines.rb +51 -0
- data/spec/codecs/json_spooler.rb +43 -0
- data/spec/codecs/msgpack.rb +39 -0
- data/spec/codecs/multiline.rb +60 -0
- data/spec/codecs/oldlogstashjson.rb +55 -0
- data/spec/codecs/plain.rb +35 -0
- data/spec/codecs/spool.rb +35 -0
- data/spec/conditionals/test.rb +323 -0
- data/spec/config.rb +31 -0
- data/spec/event.rb +165 -0
- data/spec/examples/fail2ban.rb +28 -0
- data/spec/examples/graphite-input.rb +41 -0
- data/spec/examples/mysql-slow-query.rb +70 -0
- data/spec/examples/parse-apache-logs.rb +66 -0
- data/spec/examples/parse-haproxy-logs.rb +115 -0
- data/spec/examples/syslog.rb +48 -0
- data/spec/filters/alter.rb +96 -0
- data/spec/filters/anonymize.rb +189 -0
- data/spec/filters/checksum.rb +41 -0
- data/spec/filters/clone.rb +67 -0
- data/spec/filters/collate.rb +122 -0
- data/spec/filters/csv.rb +174 -0
- data/spec/filters/date.rb +285 -0
- data/spec/filters/date_performance.rb +31 -0
- data/spec/filters/dns.rb +159 -0
- data/spec/filters/drop.rb +19 -0
- data/spec/filters/elapsed.rb +294 -0
- data/spec/filters/environment.rb +43 -0
- data/spec/filters/geoip.rb +62 -0
- data/spec/filters/grep.rb +342 -0
- data/spec/filters/grok.rb +473 -0
- data/spec/filters/grok/timeout2.rb +56 -0
- data/spec/filters/grok/timeouts.rb +39 -0
- data/spec/filters/i18n.rb +25 -0
- data/spec/filters/json.rb +72 -0
- data/spec/filters/json_encode.rb +37 -0
- data/spec/filters/kv.rb +403 -0
- data/spec/filters/metrics.rb +212 -0
- data/spec/filters/multiline.rb +119 -0
- data/spec/filters/mutate.rb +180 -0
- data/spec/filters/noop.rb +221 -0
- data/spec/filters/prune.rb +441 -0
- data/spec/filters/punct.rb +18 -0
- data/spec/filters/railsparallelrequest.rb +112 -0
- data/spec/filters/range.rb +169 -0
- data/spec/filters/split.rb +58 -0
- data/spec/filters/translate.rb +70 -0
- data/spec/filters/unique.rb +25 -0
- data/spec/filters/useragent.rb +42 -0
- data/spec/filters/xml.rb +157 -0
- data/spec/inputs/file.rb +107 -0
- data/spec/inputs/gelf.rb +52 -0
- data/spec/inputs/generator.rb +30 -0
- data/spec/inputs/imap.rb +60 -0
- data/spec/inputs/redis.rb +63 -0
- data/spec/inputs/relp.rb +70 -0
- data/spec/inputs/tcp.rb +101 -0
- data/spec/jar.rb +21 -0
- data/spec/outputs/csv.rb +266 -0
- data/spec/outputs/elasticsearch.rb +161 -0
- data/spec/outputs/elasticsearch_http.rb +240 -0
- data/spec/outputs/email.rb +173 -0
- data/spec/outputs/file.rb +82 -0
- data/spec/outputs/graphite.rb +236 -0
- data/spec/outputs/redis.rb +127 -0
- data/spec/speed.rb +20 -0
- data/spec/sqlite-test.rb +81 -0
- data/spec/support/LOGSTASH-733.rb +21 -0
- data/spec/support/LOGSTASH-820.rb +25 -0
- data/spec/support/akamai-grok.rb +26 -0
- data/spec/support/date-http.rb +17 -0
- data/spec/support/postwait1.rb +26 -0
- data/spec/support/pull375.rb +21 -0
- data/spec/test_utils.rb +125 -0
- data/spec/util/fieldeval_spec.rb +44 -0
- data/test/jenkins/config.xml.erb +74 -0
- data/test/jenkins/create-jobs.rb +23 -0
- data/test/jenkins/generatorjob.config.xml +66 -0
- data/tools/Gemfile +14 -0
- data/tools/Gemfile.jruby-1.9.lock +322 -0
- data/tools/Gemfile.rbx-2.1.lock +516 -0
- data/tools/Gemfile.ruby-1.9.1.lock +310 -0
- data/tools/Gemfile.ruby-2.0.0.lock +310 -0
- metadata +629 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "logstash/namespace"
|
|
3
|
+
require "logstash/outputs/base"
|
|
4
|
+
|
|
5
|
+
# This output runs a websocket server and publishes any
|
|
6
|
+
# messages to all connected websocket clients.
|
|
7
|
+
#
|
|
8
|
+
# You can connect to it with ws://<host\>:<port\>/
|
|
9
|
+
#
|
|
10
|
+
# If no clients are connected, any messages received are ignored.
|
|
11
|
+
class LogStash::Outputs::WebSocket < LogStash::Outputs::Base
|
|
12
|
+
config_name "websocket"
|
|
13
|
+
milestone 1
|
|
14
|
+
|
|
15
|
+
# The address to serve websocket data from
|
|
16
|
+
config :host, :validate => :string, :default => "0.0.0.0"
|
|
17
|
+
|
|
18
|
+
# The port to serve websocket data from
|
|
19
|
+
config :port, :validate => :number, :default => 3232
|
|
20
|
+
|
|
21
|
+
public
|
|
22
|
+
def register
|
|
23
|
+
require "ftw"
|
|
24
|
+
require "logstash/outputs/websocket/app"
|
|
25
|
+
require "logstash/outputs/websocket/pubsub"
|
|
26
|
+
@pubsub = LogStash::Outputs::WebSocket::Pubsub.new
|
|
27
|
+
@pubsub.logger = @logger
|
|
28
|
+
@server = Thread.new(@pubsub) do |pubsub|
|
|
29
|
+
begin
|
|
30
|
+
Rack::Handler::FTW.run(LogStash::Outputs::WebSocket::App.new(pubsub, @logger),
|
|
31
|
+
:Host => @host, :Port => @port)
|
|
32
|
+
rescue => e
|
|
33
|
+
@logger.error("websocket server failed", :exception => e)
|
|
34
|
+
sleep 1
|
|
35
|
+
retry
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end # def register
|
|
39
|
+
|
|
40
|
+
public
|
|
41
|
+
def receive(event)
|
|
42
|
+
return unless output?(event)
|
|
43
|
+
@pubsub.publish(event.to_json)
|
|
44
|
+
end # def receive
|
|
45
|
+
|
|
46
|
+
end # class LogStash::Outputs::Websocket
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "logstash/namespace"
|
|
3
|
+
require "logstash/outputs/websocket"
|
|
4
|
+
require "sinatra/base"
|
|
5
|
+
require "rack/handler/ftw" # from ftw
|
|
6
|
+
require "ftw/websocket/rack" # from ftw
|
|
7
|
+
|
|
8
|
+
class LogStash::Outputs::WebSocket::App < Sinatra::Base
|
|
9
|
+
def initialize(pubsub, logger)
|
|
10
|
+
@pubsub = pubsub
|
|
11
|
+
@logger = logger
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
set :reload_templates, false
|
|
15
|
+
|
|
16
|
+
get "/" do
|
|
17
|
+
# TODO(sissel): Support filters/etc.
|
|
18
|
+
ws = ::FTW::WebSocket::Rack.new(env)
|
|
19
|
+
@logger.debug("New websocket client")
|
|
20
|
+
stream(:keep_open) do |out|
|
|
21
|
+
@pubsub.subscribe do |event|
|
|
22
|
+
ws.publish(event)
|
|
23
|
+
end # pubsub
|
|
24
|
+
end # stream
|
|
25
|
+
|
|
26
|
+
ws.rack_response
|
|
27
|
+
end # get /
|
|
28
|
+
end # class LogStash::Outputs::WebSocket::App
|
|
29
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "logstash/namespace"
|
|
3
|
+
require "logstash/outputs/websocket"
|
|
4
|
+
|
|
5
|
+
class LogStash::Outputs::WebSocket::Pubsub
|
|
6
|
+
attr_accessor :logger
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
@subscribers = []
|
|
10
|
+
@subscribers_lock = Mutex.new
|
|
11
|
+
end # def initialize
|
|
12
|
+
|
|
13
|
+
def publish(object)
|
|
14
|
+
@subscribers_lock.synchronize do
|
|
15
|
+
break if @subscribers.size == 0
|
|
16
|
+
|
|
17
|
+
failed = []
|
|
18
|
+
@subscribers.each do |subscriber|
|
|
19
|
+
begin
|
|
20
|
+
subscriber.call(object)
|
|
21
|
+
rescue => e
|
|
22
|
+
@logger.error("Failed to publish to subscriber", :subscriber => subscriber, :exception => e)
|
|
23
|
+
failed << subscriber
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
failed.each do |subscriber|
|
|
28
|
+
@subscribers.delete(subscriber)
|
|
29
|
+
end
|
|
30
|
+
end # @subscribers_lock.synchronize
|
|
31
|
+
end # def Pubsub
|
|
32
|
+
|
|
33
|
+
def subscribe(&block)
|
|
34
|
+
queue = Queue.new
|
|
35
|
+
@subscribers_lock.synchronize do
|
|
36
|
+
@subscribers << proc do |event|
|
|
37
|
+
queue << event
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
while true
|
|
42
|
+
block.call(queue.pop)
|
|
43
|
+
end
|
|
44
|
+
end # def subscribe
|
|
45
|
+
end # class LogStash::Outputs::WebSocket::Pubsub
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "logstash/outputs/base"
|
|
3
|
+
require "logstash/namespace"
|
|
4
|
+
|
|
5
|
+
# This output allows you ship events over XMPP/Jabber.
|
|
6
|
+
#
|
|
7
|
+
# This plugin can be used for posting events to humans over XMPP, or you can
|
|
8
|
+
# use it for PubSub or general message passing for logstash to logstash.
|
|
9
|
+
class LogStash::Outputs::Xmpp < LogStash::Outputs::Base
|
|
10
|
+
config_name "xmpp"
|
|
11
|
+
milestone 2
|
|
12
|
+
|
|
13
|
+
# The user or resource ID, like foo@example.com.
|
|
14
|
+
config :user, :validate => :string, :required => :true
|
|
15
|
+
|
|
16
|
+
# The xmpp password for the user/identity.
|
|
17
|
+
config :password, :validate => :password, :required => :true
|
|
18
|
+
|
|
19
|
+
# The users to send messages to
|
|
20
|
+
config :users, :validate => :array
|
|
21
|
+
|
|
22
|
+
# if muc/multi-user-chat required, give the name of the room that
|
|
23
|
+
# you want to join: room@conference.domain/nick
|
|
24
|
+
config :rooms, :validate => :array
|
|
25
|
+
|
|
26
|
+
# The xmpp server to connect to. This is optional. If you omit this setting,
|
|
27
|
+
# the host on the user/identity is used. (foo.com for user@foo.com)
|
|
28
|
+
config :host, :validate => :string
|
|
29
|
+
|
|
30
|
+
# The message to send. This supports dynamic strings like %{host}
|
|
31
|
+
config :message, :validate => :string, :required => true
|
|
32
|
+
|
|
33
|
+
public
|
|
34
|
+
def register
|
|
35
|
+
require "xmpp4r"
|
|
36
|
+
@client = connect
|
|
37
|
+
|
|
38
|
+
@mucs = []
|
|
39
|
+
@users = [] if !@users
|
|
40
|
+
|
|
41
|
+
# load the MUC Client if we are joining rooms.
|
|
42
|
+
if @rooms && !@rooms.empty?
|
|
43
|
+
require 'xmpp4r/muc'
|
|
44
|
+
@rooms.each do |room| # handle muc messages in different rooms
|
|
45
|
+
muc = Jabber::MUC::MUCClient.new(@client)
|
|
46
|
+
muc.join(room)
|
|
47
|
+
@mucs << muc
|
|
48
|
+
end # @rooms.each
|
|
49
|
+
end # if @rooms
|
|
50
|
+
end # def register
|
|
51
|
+
|
|
52
|
+
public
|
|
53
|
+
def connect
|
|
54
|
+
Jabber::debug = true
|
|
55
|
+
client = Jabber::Client.new(Jabber::JID.new(@user))
|
|
56
|
+
client.connect(@host)
|
|
57
|
+
client.auth(@password.value)
|
|
58
|
+
return client
|
|
59
|
+
end # def connect
|
|
60
|
+
|
|
61
|
+
public
|
|
62
|
+
def receive(event)
|
|
63
|
+
return unless output?(event)
|
|
64
|
+
|
|
65
|
+
string_message = event.sprintf(@message)
|
|
66
|
+
@users.each do |user|
|
|
67
|
+
msg = Jabber::Message.new(user, string_message)
|
|
68
|
+
msg.type = :chat
|
|
69
|
+
@client.send(msg)
|
|
70
|
+
end # @targets.each
|
|
71
|
+
|
|
72
|
+
msg = Jabber::Message.new(nil, string_message)
|
|
73
|
+
msg.type = :groupchat
|
|
74
|
+
@mucs.each do |muc|
|
|
75
|
+
muc.send(msg)
|
|
76
|
+
end # @mucs.each
|
|
77
|
+
end # def receive
|
|
78
|
+
end # class LogStash::Outputs::Xmpp
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "logstash/namespace"
|
|
3
|
+
require "logstash/outputs/base"
|
|
4
|
+
|
|
5
|
+
# The zabbix output is used for sending item data to zabbix via the
|
|
6
|
+
# zabbix_sender executable.
|
|
7
|
+
#
|
|
8
|
+
# For this output to work, your event must have the following fields:
|
|
9
|
+
#
|
|
10
|
+
# * "zabbix_host" (the host configured in Zabbix)
|
|
11
|
+
# * "zabbix_item" (the item key on the host in Zabbix)
|
|
12
|
+
#
|
|
13
|
+
# In Zabbix, create your host with the same name (no spaces in the name of
|
|
14
|
+
# the host supported) and create your item with the specified key as a
|
|
15
|
+
# Zabbix Trapper item.
|
|
16
|
+
#
|
|
17
|
+
# The easiest way to use this output is with the grep filter.
|
|
18
|
+
# Presumably, you only want certain events matching a given pattern
|
|
19
|
+
# to send events to zabbix, so use grep to match and also to add the required
|
|
20
|
+
# fields.
|
|
21
|
+
#
|
|
22
|
+
# filter {
|
|
23
|
+
# grep {
|
|
24
|
+
# type => "linux-syslog"
|
|
25
|
+
# match => [ "@message", "(error|ERROR|CRITICAL)" ]
|
|
26
|
+
# add_tag => [ "zabbix-sender" ]
|
|
27
|
+
# add_field => [
|
|
28
|
+
# "zabbix_host", "%{source_host}",
|
|
29
|
+
# "zabbix_item", "item.key"
|
|
30
|
+
# ]
|
|
31
|
+
# }
|
|
32
|
+
# }
|
|
33
|
+
#
|
|
34
|
+
# output {
|
|
35
|
+
# zabbix {
|
|
36
|
+
# # only process events with this tag
|
|
37
|
+
# tags => "zabbix-sender"
|
|
38
|
+
#
|
|
39
|
+
# # specify the hostname or ip of your zabbix server
|
|
40
|
+
# # (defaults to localhost)
|
|
41
|
+
# host => "localhost"
|
|
42
|
+
#
|
|
43
|
+
# # specify the port to connect to (default 10051)
|
|
44
|
+
# port => "10051"
|
|
45
|
+
#
|
|
46
|
+
# # specify the path to zabbix_sender
|
|
47
|
+
# # (defaults to "/usr/local/bin/zabbix_sender")
|
|
48
|
+
# zabbix_sender => "/usr/local/bin/zabbix_sender"
|
|
49
|
+
# }
|
|
50
|
+
# }
|
|
51
|
+
class LogStash::Outputs::Zabbix < LogStash::Outputs::Base
|
|
52
|
+
|
|
53
|
+
config_name "zabbix"
|
|
54
|
+
milestone 2
|
|
55
|
+
|
|
56
|
+
config :host, :validate => :string, :default => "localhost"
|
|
57
|
+
config :port, :validate => :number, :default => 10051
|
|
58
|
+
config :zabbix_sender, :validate => :path, :default => "/usr/local/bin/zabbix_sender"
|
|
59
|
+
|
|
60
|
+
public
|
|
61
|
+
def register
|
|
62
|
+
# nothing to do
|
|
63
|
+
end # def register
|
|
64
|
+
|
|
65
|
+
public
|
|
66
|
+
def receive(event)
|
|
67
|
+
return unless output?(event)
|
|
68
|
+
|
|
69
|
+
if !File.exists?(@zabbix_sender)
|
|
70
|
+
@logger.warn("Skipping zabbix output; zabbix_sender file is missing",
|
|
71
|
+
:zabbix_sender => @zabbix_sender, :missed_event => event)
|
|
72
|
+
return
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
host = event["zabbix_host"]
|
|
76
|
+
if !host
|
|
77
|
+
@logger.warn("Skipping zabbix output; zabbix_host field is missing",
|
|
78
|
+
:missed_event => event)
|
|
79
|
+
return
|
|
80
|
+
end
|
|
81
|
+
host = host.first if host.is_a?(Array)
|
|
82
|
+
|
|
83
|
+
item = event["zabbix_item"]
|
|
84
|
+
if !item
|
|
85
|
+
@logger.warn("Skipping zabbix output; zabbix_item field is missing",
|
|
86
|
+
:missed_event => event)
|
|
87
|
+
return
|
|
88
|
+
end
|
|
89
|
+
item = item.first if item.is_a?(Array)
|
|
90
|
+
|
|
91
|
+
zmsg = event["message"]
|
|
92
|
+
zmsg = zmsg.gsub("\n", "\\n")
|
|
93
|
+
zmsg = zmsg.gsub(/"/, "\\\"")
|
|
94
|
+
|
|
95
|
+
cmd = "#{@zabbix_sender} -z #{@host} -p #{@port} -s #{host} -k #{item} -o \"#{zmsg}\" 2>/dev/null >/dev/null"
|
|
96
|
+
|
|
97
|
+
@logger.debug("Running zabbix command", :command => cmd)
|
|
98
|
+
begin
|
|
99
|
+
# TODO(sissel): Update this to use IO.popen so we can capture the output and
|
|
100
|
+
# log it accordingly.
|
|
101
|
+
system(cmd)
|
|
102
|
+
rescue => e
|
|
103
|
+
@logger.warn("Skipping zabbix output; error calling zabbix_sender",
|
|
104
|
+
:command => cmd, :missed_event => event,
|
|
105
|
+
:exception => e, :backtrace => e.backtrace)
|
|
106
|
+
end
|
|
107
|
+
end # def receive
|
|
108
|
+
end # class LogStash::Outputs::Zabbix
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "logstash/outputs/base"
|
|
3
|
+
require "logstash/namespace"
|
|
4
|
+
|
|
5
|
+
# Write events to a 0MQ PUB socket.
|
|
6
|
+
#
|
|
7
|
+
# You need to have the 0mq 2.1.x library installed to be able to use
|
|
8
|
+
# this output plugin.
|
|
9
|
+
#
|
|
10
|
+
# The default settings will create a publisher connecting to a subscriber
|
|
11
|
+
# bound to tcp://127.0.0.1:2120
|
|
12
|
+
#
|
|
13
|
+
class LogStash::Outputs::ZeroMQ < LogStash::Outputs::Base
|
|
14
|
+
|
|
15
|
+
config_name "zeromq"
|
|
16
|
+
milestone 2
|
|
17
|
+
|
|
18
|
+
default :codec, "json"
|
|
19
|
+
|
|
20
|
+
# 0mq socket address to connect or bind.
|
|
21
|
+
# Please note that `inproc://` will not work with logstashi.
|
|
22
|
+
# For each we use a context per thread.
|
|
23
|
+
# By default, inputs bind/listen and outputs connect.
|
|
24
|
+
config :address, :validate => :array, :default => ["tcp://127.0.0.1:2120"]
|
|
25
|
+
|
|
26
|
+
# The default logstash topologies work as follows:
|
|
27
|
+
#
|
|
28
|
+
# * pushpull - inputs are pull, outputs are push
|
|
29
|
+
# * pubsub - inputs are subscribers, outputs are publishers
|
|
30
|
+
# * pair - inputs are clients, inputs are servers
|
|
31
|
+
#
|
|
32
|
+
# If the predefined topology flows don't work for you,
|
|
33
|
+
# you can change the 'mode' setting
|
|
34
|
+
# TODO (lusis) add req/rep MAYBE
|
|
35
|
+
# TODO (lusis) add router/dealer
|
|
36
|
+
config :topology, :validate => ["pushpull", "pubsub", "pair"], :required => true
|
|
37
|
+
|
|
38
|
+
# This is used for the 'pubsub' topology only.
|
|
39
|
+
# On inputs, this allows you to filter messages by topic.
|
|
40
|
+
# On outputs, this allows you to tag a message for routing.
|
|
41
|
+
# NOTE: ZeroMQ does subscriber-side filtering
|
|
42
|
+
# NOTE: Topic is evaluated with `event.sprintf` so macros are valid here.
|
|
43
|
+
config :topic, :validate => :string, :default => ""
|
|
44
|
+
|
|
45
|
+
# Server mode binds/listens. Client mode connects.
|
|
46
|
+
config :mode, :validate => ["server", "client"], :default => "client"
|
|
47
|
+
|
|
48
|
+
# This exposes zmq_setsockopt for advanced tuning.
|
|
49
|
+
# See http://api.zeromq.org/2-1:zmq-setsockopt for details.
|
|
50
|
+
#
|
|
51
|
+
# This is where you would set values like:
|
|
52
|
+
#
|
|
53
|
+
# * ZMQ::HWM - high water mark
|
|
54
|
+
# * ZMQ::IDENTITY - named queues
|
|
55
|
+
# * ZMQ::SWAP_SIZE - space for disk overflow
|
|
56
|
+
#
|
|
57
|
+
# Example: sockopt => ["ZMQ::HWM", 50, "ZMQ::IDENTITY", "my_named_queue"]
|
|
58
|
+
config :sockopt, :validate => :hash
|
|
59
|
+
|
|
60
|
+
public
|
|
61
|
+
def register
|
|
62
|
+
require "ffi-rzmq"
|
|
63
|
+
require "logstash/util/zeromq"
|
|
64
|
+
self.class.send(:include, LogStash::Util::ZeroMQ)
|
|
65
|
+
|
|
66
|
+
if @mode == "server"
|
|
67
|
+
workers_not_supported("With 'mode => server', only one zeromq socket may bind to a port and may not be shared among threads. Going to single-worker mode for this plugin!")
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Translate topology shorthand to socket types
|
|
71
|
+
case @topology
|
|
72
|
+
when "pair"
|
|
73
|
+
zmq_const = ZMQ::PAIR
|
|
74
|
+
when "pushpull"
|
|
75
|
+
zmq_const = ZMQ::PUSH
|
|
76
|
+
when "pubsub"
|
|
77
|
+
zmq_const = ZMQ::PUB
|
|
78
|
+
end # case socket_type
|
|
79
|
+
|
|
80
|
+
@zsocket = context.socket(zmq_const)
|
|
81
|
+
|
|
82
|
+
error_check(@zsocket.setsockopt(ZMQ::LINGER, 1),
|
|
83
|
+
"while setting ZMQ::LINGER == 1)")
|
|
84
|
+
|
|
85
|
+
if @sockopt
|
|
86
|
+
setopts(@zsocket, @sockopt)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
@address.each do |addr|
|
|
90
|
+
setup(@zsocket, addr)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
@codec.on_event(&method(:publish))
|
|
94
|
+
end # def register
|
|
95
|
+
|
|
96
|
+
public
|
|
97
|
+
def teardown
|
|
98
|
+
error_check(@zsocket.close, "while closing the socket")
|
|
99
|
+
end # def teardown
|
|
100
|
+
|
|
101
|
+
private
|
|
102
|
+
def server?
|
|
103
|
+
@mode == "server"
|
|
104
|
+
end # def server?
|
|
105
|
+
|
|
106
|
+
public
|
|
107
|
+
def receive(event)
|
|
108
|
+
return unless output?(event)
|
|
109
|
+
|
|
110
|
+
@codec.encode(event)
|
|
111
|
+
end # def receive
|
|
112
|
+
|
|
113
|
+
def publish(payload)
|
|
114
|
+
@logger.debug? && @logger.debug("0mq: sending", :event => payload)
|
|
115
|
+
if @topology == "pubsub"
|
|
116
|
+
# TODO(sissel): Need to figure out how to fit this into the codecs system.
|
|
117
|
+
#@logger.debug("0mq output: setting topic to: #{event.sprintf(@topic)}")
|
|
118
|
+
#error_check(@zsocket.send_string(event.sprintf(@topic), ZMQ::SNDMORE),
|
|
119
|
+
#"in topic send_string")
|
|
120
|
+
end
|
|
121
|
+
error_check(@zsocket.send_string(payload), "in send_string")
|
|
122
|
+
rescue => e
|
|
123
|
+
@logger.warn("0mq output exception", :address => @address, :exception => e)
|
|
124
|
+
end
|
|
125
|
+
end # class LogStash::Outputs::ZeroMQ
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "logstash/config/file"
|
|
3
|
+
require "logstash/namespace"
|
|
4
|
+
require "thread" # stdlib
|
|
5
|
+
require "logstash/filters/base"
|
|
6
|
+
require "logstash/inputs/base"
|
|
7
|
+
require "logstash/outputs/base"
|
|
8
|
+
require "logstash/errors"
|
|
9
|
+
require "stud/interval" # gem stud
|
|
10
|
+
|
|
11
|
+
class LogStash::Pipeline
|
|
12
|
+
def initialize(configstr)
|
|
13
|
+
@logger = Cabin::Channel.get(LogStash)
|
|
14
|
+
grammar = LogStashConfigParser.new
|
|
15
|
+
@config = grammar.parse(configstr)
|
|
16
|
+
if @config.nil?
|
|
17
|
+
raise LogStash::ConfigurationError, grammar.failure_reason
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# This will compile the config to ruby and evaluate the resulting code.
|
|
21
|
+
# The code will initialize all the plugins and define the
|
|
22
|
+
# filter and output methods.
|
|
23
|
+
code = @config.compile
|
|
24
|
+
# The config code is hard to represent as a log message...
|
|
25
|
+
# So just print it.
|
|
26
|
+
@logger.debug? && @logger.debug("Compiled pipeline code:\n#{code}")
|
|
27
|
+
begin
|
|
28
|
+
eval(code)
|
|
29
|
+
rescue => e
|
|
30
|
+
raise
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
@input_to_filter = SizedQueue.new(20)
|
|
34
|
+
|
|
35
|
+
# If no filters, pipe inputs directly to outputs
|
|
36
|
+
if !filters?
|
|
37
|
+
@filter_to_output = @input_to_filter
|
|
38
|
+
else
|
|
39
|
+
@filter_to_output = SizedQueue.new(20)
|
|
40
|
+
end
|
|
41
|
+
@settings = {
|
|
42
|
+
"filter-workers" => 1,
|
|
43
|
+
}
|
|
44
|
+
end # def initialize
|
|
45
|
+
|
|
46
|
+
def ready?
|
|
47
|
+
return @ready
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def started?
|
|
51
|
+
return @started
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def configure(setting, value)
|
|
55
|
+
@settings[setting] = value
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def filters?
|
|
59
|
+
return @filters.any?
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def run
|
|
63
|
+
@started = true
|
|
64
|
+
@input_threads = []
|
|
65
|
+
start_inputs
|
|
66
|
+
start_filters if filters?
|
|
67
|
+
start_outputs
|
|
68
|
+
|
|
69
|
+
@ready = true
|
|
70
|
+
|
|
71
|
+
@logger.info("Pipeline started")
|
|
72
|
+
wait_inputs
|
|
73
|
+
|
|
74
|
+
# In theory there's nothing to do to filters to tell them to shutdown?
|
|
75
|
+
if filters?
|
|
76
|
+
shutdown_filters
|
|
77
|
+
wait_filters
|
|
78
|
+
end
|
|
79
|
+
shutdown_outputs
|
|
80
|
+
wait_outputs
|
|
81
|
+
|
|
82
|
+
@logger.info("Pipeline shutdown complete.")
|
|
83
|
+
|
|
84
|
+
# exit code
|
|
85
|
+
return 0
|
|
86
|
+
end # def run
|
|
87
|
+
|
|
88
|
+
def wait_inputs
|
|
89
|
+
@input_threads.each(&:join)
|
|
90
|
+
rescue Interrupt
|
|
91
|
+
# rbx does weird things during do SIGINT that I haven't debugged
|
|
92
|
+
# so we catch Interrupt here and signal a shutdown. For some reason the
|
|
93
|
+
# signal handler isn't invoked it seems? I dunno, haven't looked much into
|
|
94
|
+
# it.
|
|
95
|
+
shutdown
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def shutdown_filters
|
|
99
|
+
@input_to_filter.push(LogStash::ShutdownSignal)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def wait_filters
|
|
103
|
+
@filter_threads.each(&:join) if @filter_threads
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def shutdown_outputs
|
|
107
|
+
# nothing, filters will do this
|
|
108
|
+
@filter_to_output.push(LogStash::ShutdownSignal)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def wait_outputs
|
|
112
|
+
# Wait for the outputs to stop
|
|
113
|
+
@output_threads.each(&:join)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def start_inputs
|
|
117
|
+
moreinputs = []
|
|
118
|
+
@inputs.each do |input|
|
|
119
|
+
if input.threadable && input.threads > 1
|
|
120
|
+
(input.threads-1).times do |i|
|
|
121
|
+
moreinputs << input.clone
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
@inputs += moreinputs
|
|
126
|
+
|
|
127
|
+
@inputs.each do |input|
|
|
128
|
+
input.register
|
|
129
|
+
start_input(input)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def start_filters
|
|
134
|
+
@filters.each(&:register)
|
|
135
|
+
@filter_threads = @settings["filter-workers"].times.collect do
|
|
136
|
+
Thread.new { filterworker }
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Set up the periodic flusher thread.
|
|
140
|
+
@flusher_thread = Thread.new { Stud.interval(5) { filter_flusher } }
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def start_outputs
|
|
144
|
+
@output_threads = [
|
|
145
|
+
Thread.new { outputworker }
|
|
146
|
+
]
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def start_input(plugin)
|
|
150
|
+
@input_threads << Thread.new { inputworker(plugin) }
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def inputworker(plugin)
|
|
154
|
+
LogStash::Util::set_thread_name("<#{plugin.class.config_name}")
|
|
155
|
+
begin
|
|
156
|
+
plugin.run(@input_to_filter)
|
|
157
|
+
rescue LogStash::ShutdownSignal
|
|
158
|
+
return
|
|
159
|
+
rescue => e
|
|
160
|
+
if @logger.debug?
|
|
161
|
+
@logger.error(I18n.t("logstash.pipeline.worker-error-debug",
|
|
162
|
+
:plugin => plugin.inspect, :error => e.to_s,
|
|
163
|
+
:exception => e.class,
|
|
164
|
+
:stacktrace => e.backtrace.join("\n")))
|
|
165
|
+
else
|
|
166
|
+
@logger.error(I18n.t("logstash.pipeline.worker-error",
|
|
167
|
+
:plugin => plugin.inspect, :error => e))
|
|
168
|
+
end
|
|
169
|
+
puts e.backtrace if @logger.debug?
|
|
170
|
+
plugin.teardown
|
|
171
|
+
sleep 1
|
|
172
|
+
retry
|
|
173
|
+
end
|
|
174
|
+
rescue LogStash::ShutdownSignal
|
|
175
|
+
# nothing
|
|
176
|
+
ensure
|
|
177
|
+
plugin.teardown
|
|
178
|
+
end # def inputworker
|
|
179
|
+
|
|
180
|
+
def filterworker
|
|
181
|
+
LogStash::Util::set_thread_name("|worker")
|
|
182
|
+
begin
|
|
183
|
+
while true
|
|
184
|
+
event = @input_to_filter.pop
|
|
185
|
+
if event == LogStash::ShutdownSignal
|
|
186
|
+
@input_to_filter.push(event)
|
|
187
|
+
break
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
# TODO(sissel): we can avoid the extra array creation here
|
|
192
|
+
# if we don't guarantee ordering of origin vs created events.
|
|
193
|
+
# - origin event is one that comes in naturally to the filter worker.
|
|
194
|
+
# - created events are emitted by filters like split or metrics
|
|
195
|
+
events = [event]
|
|
196
|
+
filter(event) do |newevent|
|
|
197
|
+
events << newevent
|
|
198
|
+
end
|
|
199
|
+
events.each do |event|
|
|
200
|
+
next if event.cancelled?
|
|
201
|
+
@filter_to_output.push(event)
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
rescue => e
|
|
205
|
+
@logger.error("Exception in filterworker", "exception" => e, "backtrace" => e.backtrace)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
@filters.each(&:teardown)
|
|
209
|
+
end # def filterworker
|
|
210
|
+
|
|
211
|
+
def outputworker
|
|
212
|
+
LogStash::Util::set_thread_name(">output")
|
|
213
|
+
@outputs.each(&:register)
|
|
214
|
+
@outputs.each(&:worker_setup)
|
|
215
|
+
while true
|
|
216
|
+
event = @filter_to_output.pop
|
|
217
|
+
break if event == LogStash::ShutdownSignal
|
|
218
|
+
output(event)
|
|
219
|
+
end # while true
|
|
220
|
+
@outputs.each(&:teardown)
|
|
221
|
+
end # def outputworker
|
|
222
|
+
|
|
223
|
+
# Shutdown this pipeline.
|
|
224
|
+
#
|
|
225
|
+
# This method is intended to be called from another thread
|
|
226
|
+
def shutdown
|
|
227
|
+
@input_threads.each do |thread|
|
|
228
|
+
# Interrupt all inputs
|
|
229
|
+
@logger.info("Sending shutdown signal to input thread",
|
|
230
|
+
:thread => thread)
|
|
231
|
+
thread.raise(LogStash::ShutdownSignal)
|
|
232
|
+
begin
|
|
233
|
+
thread.wakeup # in case it's in blocked IO or sleeping
|
|
234
|
+
rescue ThreadError
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Sometimes an input is stuck in a blocking I/O
|
|
238
|
+
# so we need to tell it to teardown directly
|
|
239
|
+
@inputs.each do |input|
|
|
240
|
+
input.teardown
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# No need to send the ShutdownSignal to the filters/outputs nor to wait for
|
|
245
|
+
# the inputs to finish, because in the #run method we wait for that anyway.
|
|
246
|
+
end # def shutdown
|
|
247
|
+
|
|
248
|
+
def plugin(plugin_type, name, *args)
|
|
249
|
+
args << {} if args.empty?
|
|
250
|
+
klass = LogStash::Plugin.lookup(plugin_type, name)
|
|
251
|
+
return klass.new(*args)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def filter(event, &block)
|
|
255
|
+
@filter_func.call(event, &block)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def output(event)
|
|
259
|
+
@output_func.call(event)
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def filter_flusher
|
|
263
|
+
events = []
|
|
264
|
+
@filters.each do |filter|
|
|
265
|
+
|
|
266
|
+
# Filter any events generated so far in this flush.
|
|
267
|
+
events.each do |event|
|
|
268
|
+
# TODO(sissel): watchdog on flush filtration?
|
|
269
|
+
unless event.cancelled?
|
|
270
|
+
filter.filter(event)
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# TODO(sissel): watchdog on flushes?
|
|
275
|
+
if filter.respond_to?(:flush)
|
|
276
|
+
flushed = filter.flush
|
|
277
|
+
events += flushed if !flushed.nil? && flushed.any?
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
events.each do |event|
|
|
282
|
+
@logger.debug? and @logger.debug("Pushing flushed events", :event => event)
|
|
283
|
+
@filter_to_output.push(event) unless event.cancelled?
|
|
284
|
+
end
|
|
285
|
+
end # def filter_flusher
|
|
286
|
+
end # class Pipeline
|