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,299 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "logstash/outputs/base"
|
|
3
|
+
require "logstash/namespace"
|
|
4
|
+
|
|
5
|
+
# Send email when any event is received.
|
|
6
|
+
class LogStash::Outputs::Email < LogStash::Outputs::Base
|
|
7
|
+
|
|
8
|
+
config_name "email"
|
|
9
|
+
milestone 1
|
|
10
|
+
|
|
11
|
+
# This setting is deprecated in favor of logstash's "conditionals" feature
|
|
12
|
+
# If you were using this setting previously, please use conditionals instead.
|
|
13
|
+
#
|
|
14
|
+
# If you need help converting your older 'match' setting to a conditional,
|
|
15
|
+
# I welcome you to join the #logstash irc channel on freenode or to email
|
|
16
|
+
# the logstash-users@googlegroups.com mailling list and ask for help! :)
|
|
17
|
+
config :match, :validate => :hash, :deprecated => true
|
|
18
|
+
|
|
19
|
+
# Who to send this email to?
|
|
20
|
+
# A fully qualified email address to send to
|
|
21
|
+
#
|
|
22
|
+
# This field also accept a comma separated list of emails like
|
|
23
|
+
# "me@host.com, you@host.com"
|
|
24
|
+
#
|
|
25
|
+
# You can also use dynamic field from the event with the %{fieldname} syntax.
|
|
26
|
+
config :to, :validate => :string, :required => true
|
|
27
|
+
|
|
28
|
+
# The From setting for email - fully qualified email address for the From:
|
|
29
|
+
config :from, :validate => :string, :default => "logstash.alert@nowhere.com"
|
|
30
|
+
|
|
31
|
+
# The Reply-To setting for email - fully qualified email address is required
|
|
32
|
+
# here.
|
|
33
|
+
config :replyto, :validate => :string
|
|
34
|
+
|
|
35
|
+
# Who to CC on this email?
|
|
36
|
+
#
|
|
37
|
+
# See "to" setting for what is valid here.
|
|
38
|
+
config :cc, :validate => :string
|
|
39
|
+
|
|
40
|
+
# how to send email: either smtp or sendmail - default to 'smtp'
|
|
41
|
+
config :via, :validate => :string, :default => "smtp"
|
|
42
|
+
|
|
43
|
+
# the options to use:
|
|
44
|
+
# smtp: address, port, enable_starttls_auto, user_name, password, authentication(bool), domain
|
|
45
|
+
# sendmail: location, arguments
|
|
46
|
+
# If you do not specify anything, you will get the following equivalent code set in
|
|
47
|
+
# every new mail object:
|
|
48
|
+
#
|
|
49
|
+
# Mail.defaults do
|
|
50
|
+
# delivery_method :smtp, { :address => "localhost",
|
|
51
|
+
# :port => 25,
|
|
52
|
+
# :domain => 'localhost.localdomain',
|
|
53
|
+
# :user_name => nil,
|
|
54
|
+
# :password => nil,
|
|
55
|
+
# :authentication => nil,(plain, login and cram_md5)
|
|
56
|
+
# :enable_starttls_auto => true }
|
|
57
|
+
#
|
|
58
|
+
# retriever_method :pop3, { :address => "localhost",
|
|
59
|
+
# :port => 995,
|
|
60
|
+
# :user_name => nil,
|
|
61
|
+
# :password => nil,
|
|
62
|
+
# :enable_ssl => true }
|
|
63
|
+
# end
|
|
64
|
+
#
|
|
65
|
+
# Mail.delivery_method.new #=> Mail::SMTP instance
|
|
66
|
+
# Mail.retriever_method.new #=> Mail::POP3 instance
|
|
67
|
+
#
|
|
68
|
+
# Each mail object inherits the default set in Mail.delivery_method, however, on
|
|
69
|
+
# a per email basis, you can override the method:
|
|
70
|
+
#
|
|
71
|
+
# mail.delivery_method :sendmail
|
|
72
|
+
#
|
|
73
|
+
# Or you can override the method and pass in settings:
|
|
74
|
+
#
|
|
75
|
+
# mail.delivery_method :sendmail, { :address => 'some.host' }
|
|
76
|
+
#
|
|
77
|
+
# You can also just modify the settings:
|
|
78
|
+
#
|
|
79
|
+
# mail.delivery_settings = { :address => 'some.host' }
|
|
80
|
+
#
|
|
81
|
+
# The passed in hash is just merged against the defaults with +merge!+ and the result
|
|
82
|
+
# assigned the mail object. So the above example will change only the :address value
|
|
83
|
+
# of the global smtp_settings to be 'some.host', keeping all other values
|
|
84
|
+
config :options, :validate => :hash, :default => {}
|
|
85
|
+
|
|
86
|
+
# subject for email
|
|
87
|
+
config :subject, :validate => :string, :default => ""
|
|
88
|
+
|
|
89
|
+
# body for email - just plain text
|
|
90
|
+
config :body, :validate => :string, :default => ""
|
|
91
|
+
|
|
92
|
+
# body for email - can contain html markup
|
|
93
|
+
config :htmlbody, :validate => :string, :default => ""
|
|
94
|
+
|
|
95
|
+
# attachments - has of name of file and file location
|
|
96
|
+
config :attachments, :validate => :array, :default => []
|
|
97
|
+
|
|
98
|
+
# contenttype : for multipart messages, set the content type and/or charset of the html part
|
|
99
|
+
config :contenttype, :validate => :string, :default => "text/html; charset=UTF-8"
|
|
100
|
+
|
|
101
|
+
public
|
|
102
|
+
def register
|
|
103
|
+
require "mail"
|
|
104
|
+
|
|
105
|
+
# Mail uses instance_eval which changes the scope of self so @options is
|
|
106
|
+
# inaccessible from inside 'Mail.defaults'. So set a local variable instead.
|
|
107
|
+
options = @options
|
|
108
|
+
|
|
109
|
+
if @via == "smtp"
|
|
110
|
+
Mail.defaults do
|
|
111
|
+
delivery_method :smtp, {
|
|
112
|
+
:address => options.fetch("smtpIporHost", "localhost"),
|
|
113
|
+
:port => options.fetch("port", 25),
|
|
114
|
+
:domain => options.fetch("domain", "localhost"),
|
|
115
|
+
:user_name => options.fetch("userName", nil),
|
|
116
|
+
:password => options.fetch("password", nil),
|
|
117
|
+
:authentication => options.fetch("authenticationType", nil),
|
|
118
|
+
:enable_starttls_auto => options.fetch("starttls", false),
|
|
119
|
+
:debug => options.fetch("debug", false)
|
|
120
|
+
}
|
|
121
|
+
end
|
|
122
|
+
elsif @via == 'sendmail'
|
|
123
|
+
Mail.defaults do
|
|
124
|
+
delivery_method :sendmail
|
|
125
|
+
end
|
|
126
|
+
else
|
|
127
|
+
Mail.defaults do
|
|
128
|
+
delivery_method :@via, options
|
|
129
|
+
end
|
|
130
|
+
end # @via tests
|
|
131
|
+
@logger.debug("Email Output Registered!", :config => @config)
|
|
132
|
+
end # def register
|
|
133
|
+
|
|
134
|
+
public
|
|
135
|
+
def receive(event)
|
|
136
|
+
return unless output?(event)
|
|
137
|
+
@logger.debug("Event being tested for Email", :tags => @tags, :event => event)
|
|
138
|
+
# Set Intersection - returns a new array with the items that are the same between the two
|
|
139
|
+
if !@tags.empty? && (event["tags"] & @tags).size == 0
|
|
140
|
+
# Skip events that have no tags in common with what we were configured
|
|
141
|
+
@logger.debug("No Tags match for Email Output!")
|
|
142
|
+
return
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
@logger.debug? && @logger.debug("Match data for Email - ", :match => @match)
|
|
146
|
+
successful = false
|
|
147
|
+
matchName = ""
|
|
148
|
+
operator = ""
|
|
149
|
+
|
|
150
|
+
# TODO(sissel): Delete this once match support is removed.
|
|
151
|
+
@match && @match.each do |name, query|
|
|
152
|
+
if successful
|
|
153
|
+
break
|
|
154
|
+
else
|
|
155
|
+
matchName = name
|
|
156
|
+
end
|
|
157
|
+
# now loop over the csv query
|
|
158
|
+
queryArray = query.split(',')
|
|
159
|
+
index = 1
|
|
160
|
+
while index < queryArray.length
|
|
161
|
+
field = queryArray.at(index -1)
|
|
162
|
+
value = queryArray.at(index)
|
|
163
|
+
index = index + 2
|
|
164
|
+
if field == ""
|
|
165
|
+
if value.downcase == "and"
|
|
166
|
+
operator = "and"
|
|
167
|
+
elsif value.downcase == "or"
|
|
168
|
+
operator = "or"
|
|
169
|
+
else
|
|
170
|
+
operator = "or"
|
|
171
|
+
@logger.error("Operator Provided Is Not Found, Currently We Only Support AND/OR Values! - defaulting to OR")
|
|
172
|
+
end
|
|
173
|
+
else
|
|
174
|
+
hasField = event[field]
|
|
175
|
+
@logger.debug? and @logger.debug("Does Event Contain Field - ", :hasField => hasField)
|
|
176
|
+
isValid = false
|
|
177
|
+
# if we have maching field and value is wildcard - we have a success
|
|
178
|
+
if hasField
|
|
179
|
+
if value == "*"
|
|
180
|
+
isValid = true
|
|
181
|
+
else
|
|
182
|
+
# we get an array so we need to loop over the values and find if we have a match
|
|
183
|
+
eventFieldValues = event[field]
|
|
184
|
+
@logger.debug? and @logger.debug("Event Field Values - ", :eventFieldValues => eventFieldValues)
|
|
185
|
+
eventFieldValues = [eventFieldValues] if not eventFieldValues.respond_to?(:each)
|
|
186
|
+
eventFieldValues.each do |eventFieldValue|
|
|
187
|
+
isValid = validateValue(eventFieldValue, value)
|
|
188
|
+
if isValid # no need to iterate any further
|
|
189
|
+
@logger.debug("VALID CONDITION FOUND - ", :eventFieldValue => eventFieldValue, :value => value)
|
|
190
|
+
break
|
|
191
|
+
end
|
|
192
|
+
end # end eventFieldValues.each do
|
|
193
|
+
end # end value == "*"
|
|
194
|
+
end # end hasField
|
|
195
|
+
# if we have an AND operator and we have a successful == false break
|
|
196
|
+
if operator == "and" && !isValid
|
|
197
|
+
successful = false
|
|
198
|
+
elsif operator == "or" && (isValid || successful)
|
|
199
|
+
successful = true
|
|
200
|
+
else
|
|
201
|
+
successful = isValid
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end # @match.each do
|
|
206
|
+
|
|
207
|
+
# The 'match' setting is deprecated and optional. If not set,
|
|
208
|
+
# default to success.
|
|
209
|
+
successful = true if @match.nil?
|
|
210
|
+
|
|
211
|
+
@logger.debug? && @logger.debug("Email Did we match any alerts for event : ", :successful => successful)
|
|
212
|
+
|
|
213
|
+
if successful
|
|
214
|
+
# first add our custom field - matchName - so we can use it in the sprintf function
|
|
215
|
+
event["matchName"] = matchName unless matchName.empty?
|
|
216
|
+
@logger.debug? and @logger.debug("Creating mail with these settings : ", :via => @via, :options => @options, :from => @from, :to => @to, :cc => @cc, :subject => @subject, :body => @body, :content_type => @contenttype, :htmlbody => @htmlbody, :attachments => @attachments, :to => to, :to => to)
|
|
217
|
+
formatedSubject = event.sprintf(@subject)
|
|
218
|
+
formattedBody = event.sprintf(@body)
|
|
219
|
+
formattedHtmlBody = event.sprintf(@htmlbody)
|
|
220
|
+
# we have a match(s) - send email
|
|
221
|
+
mail = Mail.new
|
|
222
|
+
mail.from = event.sprintf(@from)
|
|
223
|
+
mail.to = event.sprintf(@to)
|
|
224
|
+
if @replyto
|
|
225
|
+
mail.reply_to = event.sprintf(@replyto)
|
|
226
|
+
end
|
|
227
|
+
mail.cc = event.sprintf(@cc)
|
|
228
|
+
mail.subject = formatedSubject
|
|
229
|
+
if @htmlbody.empty?
|
|
230
|
+
formattedBody.gsub!(/\\n/, "\n") # Take new line in the email
|
|
231
|
+
mail.body = formattedBody
|
|
232
|
+
else
|
|
233
|
+
mail.text_part = Mail::Part.new do
|
|
234
|
+
content_type "text/plain; charset=UTF-8"
|
|
235
|
+
formattedBody.gsub!(/\\n/, "\n") # Take new line in the email
|
|
236
|
+
body formattedBody
|
|
237
|
+
end
|
|
238
|
+
mail.html_part = Mail::Part.new do
|
|
239
|
+
content_type "text/html; charset=UTF-8"
|
|
240
|
+
body formattedHtmlBody
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
@attachments.each do |fileLocation|
|
|
244
|
+
mail.add_file(fileLocation)
|
|
245
|
+
end # end @attachments.each
|
|
246
|
+
@logger.debug? and @logger.debug("Sending mail with these values : ", :from => mail.from, :to => mail.to, :cc => mail.cc, :subject => mail.subject)
|
|
247
|
+
mail.deliver!
|
|
248
|
+
end # end if successful
|
|
249
|
+
end # def receive
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
private
|
|
253
|
+
def validateValue(eventFieldValue, value)
|
|
254
|
+
valid = false
|
|
255
|
+
# order of this if-else is important - please don't change it
|
|
256
|
+
if value.start_with?(">=")# greater than or equal
|
|
257
|
+
value.gsub!(">=","")
|
|
258
|
+
if eventFieldValue.to_i >= value.to_i
|
|
259
|
+
valid = true
|
|
260
|
+
end
|
|
261
|
+
elsif value.start_with?("<=")# less than or equal
|
|
262
|
+
value.gsub!("<=","")
|
|
263
|
+
if eventFieldValue.to_i <= value.to_i
|
|
264
|
+
valid = true
|
|
265
|
+
end
|
|
266
|
+
elsif value.start_with?(">")# greater than
|
|
267
|
+
value.gsub!(">","")
|
|
268
|
+
if eventFieldValue.to_i > value.to_i
|
|
269
|
+
valid = true
|
|
270
|
+
end
|
|
271
|
+
elsif value.start_with?("<")# less than
|
|
272
|
+
value.gsub!("<","")
|
|
273
|
+
if eventFieldValue.to_i < value.to_i
|
|
274
|
+
valid = true
|
|
275
|
+
end
|
|
276
|
+
elsif value.start_with?("*")# contains
|
|
277
|
+
value.gsub!("*","")
|
|
278
|
+
if eventFieldValue.include?(value)
|
|
279
|
+
valid = true
|
|
280
|
+
end
|
|
281
|
+
elsif value.start_with?("!*")# does not contain
|
|
282
|
+
value.gsub!("!*","")
|
|
283
|
+
if !eventFieldValue.include?(value)
|
|
284
|
+
valid = true
|
|
285
|
+
end
|
|
286
|
+
elsif value.start_with?("!")# not equal
|
|
287
|
+
value.gsub!("!","")
|
|
288
|
+
if eventFieldValue != value
|
|
289
|
+
valid = true
|
|
290
|
+
end
|
|
291
|
+
else # default equal
|
|
292
|
+
if eventFieldValue == value
|
|
293
|
+
valid = true
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
return valid
|
|
297
|
+
end # end validateValue()
|
|
298
|
+
|
|
299
|
+
end # class LogStash::Outputs::Email
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "logstash/namespace"
|
|
3
|
+
require "logstash/outputs/base"
|
|
4
|
+
|
|
5
|
+
# This output will run a command for any matching event.
|
|
6
|
+
#
|
|
7
|
+
# Example:
|
|
8
|
+
#
|
|
9
|
+
# output {
|
|
10
|
+
# exec {
|
|
11
|
+
# type => abuse
|
|
12
|
+
# command => "iptables -A INPUT -s %{clientip} -j DROP"
|
|
13
|
+
# }
|
|
14
|
+
# }
|
|
15
|
+
#
|
|
16
|
+
# Run subprocesses via system ruby function
|
|
17
|
+
#
|
|
18
|
+
# WARNING: if you want it non-blocking you should use & or dtach or other such
|
|
19
|
+
# techniques
|
|
20
|
+
class LogStash::Outputs::Exec < LogStash::Outputs::Base
|
|
21
|
+
|
|
22
|
+
config_name "exec"
|
|
23
|
+
milestone 1
|
|
24
|
+
|
|
25
|
+
# Command line to execute via subprocess. Use dtach or screen to make it non blocking
|
|
26
|
+
config :command, :validate => :string, :required => true
|
|
27
|
+
|
|
28
|
+
public
|
|
29
|
+
def register
|
|
30
|
+
@logger.debug("exec output registered", :config => @config)
|
|
31
|
+
end # def register
|
|
32
|
+
|
|
33
|
+
public
|
|
34
|
+
def receive(event)
|
|
35
|
+
return unless output?(event)
|
|
36
|
+
@logger.debug("running exec command", :command => event.sprintf(@command))
|
|
37
|
+
system(event.sprintf(@command))
|
|
38
|
+
end # def receive
|
|
39
|
+
|
|
40
|
+
end
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "logstash/namespace"
|
|
3
|
+
require "logstash/outputs/base"
|
|
4
|
+
require "zlib"
|
|
5
|
+
|
|
6
|
+
# File output.
|
|
7
|
+
#
|
|
8
|
+
# Write events to files on disk. You can use fields from the
|
|
9
|
+
# event as parts of the filename.
|
|
10
|
+
class LogStash::Outputs::File < LogStash::Outputs::Base
|
|
11
|
+
|
|
12
|
+
config_name "file"
|
|
13
|
+
milestone 2
|
|
14
|
+
|
|
15
|
+
# The path to the file to write. Event fields can be used here,
|
|
16
|
+
# like "/var/log/logstash/%{host}/%{application}"
|
|
17
|
+
# One may also utilize the path option for date-based log
|
|
18
|
+
# rotation via the joda time format. This will use the event
|
|
19
|
+
# timestamp.
|
|
20
|
+
# E.g.: path => "./test-%{+YYYY-MM-dd}.txt" to create
|
|
21
|
+
# ./test-2013-05-29.txt
|
|
22
|
+
config :path, :validate => :string, :required => true
|
|
23
|
+
|
|
24
|
+
# The maximum size of file to write. When the file exceeds this
|
|
25
|
+
# threshold, it will be rotated to the current filename + ".1"
|
|
26
|
+
# If that file already exists, the previous .1 will shift to .2
|
|
27
|
+
# and so forth.
|
|
28
|
+
#
|
|
29
|
+
# NOT YET SUPPORTED
|
|
30
|
+
config :max_size, :validate => :string
|
|
31
|
+
|
|
32
|
+
# The format to use when writing events to the file. This value
|
|
33
|
+
# supports any string and can include %{name} and other dynamic
|
|
34
|
+
# strings.
|
|
35
|
+
#
|
|
36
|
+
# If this setting is omitted, the full json representation of the
|
|
37
|
+
# event will be written as a single line.
|
|
38
|
+
config :message_format, :validate => :string
|
|
39
|
+
|
|
40
|
+
# Flush interval for flushing writes to log files. 0 will flush on every meesage
|
|
41
|
+
config :flush_interval, :validate => :number, :default => 2
|
|
42
|
+
|
|
43
|
+
# Gzip output stream
|
|
44
|
+
config :gzip, :validate => :boolean, :default => false
|
|
45
|
+
|
|
46
|
+
public
|
|
47
|
+
def register
|
|
48
|
+
require "fileutils" # For mkdir_p
|
|
49
|
+
|
|
50
|
+
workers_not_supported
|
|
51
|
+
|
|
52
|
+
@files = {}
|
|
53
|
+
now = Time.now
|
|
54
|
+
@last_flush_cycle = now
|
|
55
|
+
@last_stale_cleanup_cycle = now
|
|
56
|
+
flush_interval = @flush_interval.to_i
|
|
57
|
+
@stale_cleanup_interval = 10
|
|
58
|
+
end # def register
|
|
59
|
+
|
|
60
|
+
public
|
|
61
|
+
def receive(event)
|
|
62
|
+
return unless output?(event)
|
|
63
|
+
|
|
64
|
+
path = event.sprintf(@path)
|
|
65
|
+
fd = open(path)
|
|
66
|
+
|
|
67
|
+
# TODO(sissel): Check if we should rotate the file.
|
|
68
|
+
|
|
69
|
+
if @message_format
|
|
70
|
+
output = event.sprintf(@message_format)
|
|
71
|
+
else
|
|
72
|
+
output = event.to_json
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
fd.write(output)
|
|
76
|
+
fd.write("\n")
|
|
77
|
+
|
|
78
|
+
flush(fd)
|
|
79
|
+
close_stale_files
|
|
80
|
+
end # def receive
|
|
81
|
+
|
|
82
|
+
def teardown
|
|
83
|
+
@logger.debug("Teardown: closing files")
|
|
84
|
+
@files.each do |path, fd|
|
|
85
|
+
begin
|
|
86
|
+
fd.close
|
|
87
|
+
@logger.debug("Closed file #{path}", :fd => fd)
|
|
88
|
+
rescue Exception => e
|
|
89
|
+
@logger.error("Excpetion while flushing and closing files.", :exception => e)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
finished
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
private
|
|
96
|
+
def flush(fd)
|
|
97
|
+
if flush_interval > 0
|
|
98
|
+
flush_pending_files
|
|
99
|
+
else
|
|
100
|
+
fd.flush
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# every flush_interval seconds or so (triggered by events, but if there are no events there's no point flushing files anyway)
|
|
105
|
+
def flush_pending_files
|
|
106
|
+
return unless Time.now - @last_flush_cycle >= flush_interval
|
|
107
|
+
@logger.debug("Starting flush cycle")
|
|
108
|
+
@files.each do |path, fd|
|
|
109
|
+
@logger.debug("Flushing file", :path => path, :fd => fd)
|
|
110
|
+
fd.flush
|
|
111
|
+
end
|
|
112
|
+
@last_flush_cycle = Time.now
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# every 10 seconds or so (triggered by events, but if there are no events there's no point closing files anyway)
|
|
116
|
+
def close_stale_files
|
|
117
|
+
now = Time.now
|
|
118
|
+
return unless now - @last_stale_cleanup_cycle >= @stale_cleanup_interval
|
|
119
|
+
@logger.info("Starting stale files cleanup cycle", :files => @files)
|
|
120
|
+
inactive_files = @files.select { |path, fd| not fd.active }
|
|
121
|
+
@logger.debug("%d stale files found" % inactive_files.count, :inactive_files => inactive_files)
|
|
122
|
+
inactive_files.each do |path, fd|
|
|
123
|
+
@logger.info("Closing file %s" % path)
|
|
124
|
+
fd.close
|
|
125
|
+
@files.delete(path)
|
|
126
|
+
end
|
|
127
|
+
# mark all files as inactive, a call to write will mark them as active again
|
|
128
|
+
@files.each { |path, fd| fd.active = false }
|
|
129
|
+
@last_stale_cleanup_cycle = now
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def open(path)
|
|
133
|
+
return @files[path] if @files.include?(path) and not @files[path].nil?
|
|
134
|
+
|
|
135
|
+
@logger.info("Opening file", :path => path)
|
|
136
|
+
|
|
137
|
+
dir = File.dirname(path)
|
|
138
|
+
if !Dir.exists?(dir)
|
|
139
|
+
@logger.info("Creating directory", :directory => dir)
|
|
140
|
+
FileUtils.mkdir_p(dir)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# work around a bug opening fifos (bug JRUBY-6280)
|
|
144
|
+
stat = File.stat(path) rescue nil
|
|
145
|
+
if stat and stat.ftype == "fifo" and RUBY_PLATFORM == "java"
|
|
146
|
+
fd = java.io.FileWriter.new(java.io.File.new(path))
|
|
147
|
+
else
|
|
148
|
+
fd = File.new(path, "a")
|
|
149
|
+
end
|
|
150
|
+
if gzip
|
|
151
|
+
fd = Zlib::GzipWriter.new(fd)
|
|
152
|
+
end
|
|
153
|
+
@files[path] = IOWriter.new(fd)
|
|
154
|
+
end
|
|
155
|
+
end # class LogStash::Outputs::File
|
|
156
|
+
|
|
157
|
+
# wrapper class
|
|
158
|
+
class IOWriter
|
|
159
|
+
def initialize(io)
|
|
160
|
+
@io = io
|
|
161
|
+
end
|
|
162
|
+
def write(*args)
|
|
163
|
+
@io.write(*args)
|
|
164
|
+
@active = true
|
|
165
|
+
end
|
|
166
|
+
def flush
|
|
167
|
+
@io.flush
|
|
168
|
+
if @io.class == Zlib::GzipWriter
|
|
169
|
+
@io.to_io.flush
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
def method_missing(method_name, *args, &block)
|
|
173
|
+
if @io.respond_to?(method_name)
|
|
174
|
+
@io.send(method_name, *args, &block)
|
|
175
|
+
else
|
|
176
|
+
super
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
attr_accessor :active
|
|
180
|
+
end
|