logstash-lib 1.3.2
Sign up to get free protection for your applications and to get access to all the features.
- 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,145 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/filters/base"
|
3
|
+
require "logstash/namespace"
|
4
|
+
require "tempfile"
|
5
|
+
|
6
|
+
# Add GeoIP fields from Maxmind database
|
7
|
+
#
|
8
|
+
# GeoIP filter, adds information about the geographical location of IP addresses.
|
9
|
+
#
|
10
|
+
# Starting at version 1.3.0 of logstash, a [geoip][location] field is created if
|
11
|
+
# the GeoIP lookup returns a latitude and longitude. The field is stored in
|
12
|
+
# [GeoJSON](http://geojson.org/geojson-spec.html) format. Additionally,
|
13
|
+
# the default Elasticsearch template provided with the
|
14
|
+
# [elasticsearch output](../outputs/elasticsearch.html)
|
15
|
+
# maps the [geoip][location] field to a [geo_point](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-geo-point-type.html).
|
16
|
+
#
|
17
|
+
# As this field is a geo\_point _and_ it is still valid GeoJSON, you get
|
18
|
+
# the awesomeness of Elasticsearch's geospatial query, facet and filter functions
|
19
|
+
# and the flexibility of having GeoJSON for all other applications (like Kibana's
|
20
|
+
# [bettermap panel](https://github.com/elasticsearch/kibana/tree/master/src/app/panels/bettermap)).
|
21
|
+
#
|
22
|
+
# Logstash releases ship with the GeoLiteCity database made available from
|
23
|
+
# Maxmind with a CCA-ShareAlike 3.0 license. For more details on GeoLite, see
|
24
|
+
# <http://www.maxmind.com/en/geolite>.
|
25
|
+
class LogStash::Filters::GeoIP < LogStash::Filters::Base
|
26
|
+
config_name "geoip"
|
27
|
+
milestone 1
|
28
|
+
|
29
|
+
# GeoIP database file to use, Country, City, ASN, ISP and organization
|
30
|
+
# databases are supported
|
31
|
+
#
|
32
|
+
# If not specified, this will default to the GeoLiteCity database that ships
|
33
|
+
# with logstash.
|
34
|
+
config :database, :validate => :path
|
35
|
+
|
36
|
+
# The field containing the IP address or hostname to map via geoip. If
|
37
|
+
# this field is an array, only the first value will be used.
|
38
|
+
config :source, :validate => :string, :required => true
|
39
|
+
|
40
|
+
# Array of geoip fields that we want to be included in our event.
|
41
|
+
#
|
42
|
+
# Possible fields depend on the database type. By default, all geoip fields
|
43
|
+
# are included in the event.
|
44
|
+
#
|
45
|
+
# For the built in GeoLiteCity database, the following are available:
|
46
|
+
# city\_name, continent\_code, country\_code2, country\_code3, country\_name,
|
47
|
+
# dma\_code, ip, latitude, longitude, postal\_code, region\_name, timezone
|
48
|
+
config :fields, :validate => :array
|
49
|
+
|
50
|
+
# Specify into what field you want the geoip data.
|
51
|
+
# This can be useful for example if you have a src\_ip and dst\_ip and want
|
52
|
+
# information of both IP's.
|
53
|
+
#
|
54
|
+
# If you save the data to another target than "geoip" and want to use the
|
55
|
+
# geo\_point related functions in elasticsearch, you need to alter the template
|
56
|
+
# provided with the elasticsearch output and configure the output to use the
|
57
|
+
# new template.
|
58
|
+
#
|
59
|
+
# Even if you don't use the geo\_point mapping, the [target][location] field
|
60
|
+
# is still valid GeoJSON.
|
61
|
+
config :target, :validate => :string, :default => 'geoip'
|
62
|
+
|
63
|
+
public
|
64
|
+
def register
|
65
|
+
require "geoip"
|
66
|
+
if @database.nil?
|
67
|
+
if __FILE__ =~ /^(jar:)?file:\/.+!.+/
|
68
|
+
begin
|
69
|
+
# Running from a jar, assume GeoLiteCity.dat is at the root.
|
70
|
+
jar_path = [__FILE__.split("!").first, "/GeoLiteCity.dat"].join("!")
|
71
|
+
tmp_file = Tempfile.new('logstash-geoip')
|
72
|
+
tmp_file.write(File.read(jar_path))
|
73
|
+
tmp_file.close # this file is reaped when ruby exits
|
74
|
+
@database = tmp_file.path
|
75
|
+
rescue => ex
|
76
|
+
raise "Failed to cache, due to: #{ex}\n#{ex.backtrace}"
|
77
|
+
end
|
78
|
+
else
|
79
|
+
if File.exists?("GeoLiteCity.dat")
|
80
|
+
@database = "GeoLiteCity.dat"
|
81
|
+
elsif File.exists?("vendor/geoip/GeoLiteCity.dat")
|
82
|
+
@database = "vendor/geoip/GeoLiteCity.dat"
|
83
|
+
else
|
84
|
+
raise "You must specify 'database => ...' in your geoip filter"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
@logger.info("Using geoip database", :path => @database)
|
89
|
+
@geoip = ::GeoIP.new(@database)
|
90
|
+
|
91
|
+
@geoip_type = case @geoip.database_type
|
92
|
+
when GeoIP::GEOIP_CITY_EDITION_REV0, GeoIP::GEOIP_CITY_EDITION_REV1
|
93
|
+
:city
|
94
|
+
when GeoIP::GEOIP_COUNTRY_EDITION
|
95
|
+
:country
|
96
|
+
when GeoIP::GEOIP_ASNUM_EDITION
|
97
|
+
:asn
|
98
|
+
when GeoIP::GEOIP_ISP_EDITION, GeoIP::GEOIP_ORG_EDITION
|
99
|
+
:isp
|
100
|
+
else
|
101
|
+
raise RuntimeException.new "This GeoIP database is not currently supported"
|
102
|
+
end
|
103
|
+
|
104
|
+
end # def register
|
105
|
+
|
106
|
+
public
|
107
|
+
def filter(event)
|
108
|
+
return unless filter?(event)
|
109
|
+
geo_data = nil
|
110
|
+
|
111
|
+
begin
|
112
|
+
ip = event[@source]
|
113
|
+
ip = ip.first if ip.is_a? Array
|
114
|
+
geo_data = @geoip.send(@geoip_type, ip)
|
115
|
+
rescue SocketError => e
|
116
|
+
@logger.error("IP Field contained invalid IP address or hostname", :field => @field, :event => event)
|
117
|
+
rescue Exception => e
|
118
|
+
@logger.error("Unknown error while looking up GeoIP data", :exception => e, :field => @field, :event => event)
|
119
|
+
end
|
120
|
+
|
121
|
+
return if geo_data.nil?
|
122
|
+
|
123
|
+
geo_data_hash = geo_data.to_hash
|
124
|
+
geo_data_hash.delete(:request)
|
125
|
+
event[@target] = {} if event[@target].nil?
|
126
|
+
geo_data_hash.each do |key, value|
|
127
|
+
next if value.nil? || (value.is_a?(String) && value.empty?)
|
128
|
+
if @fields.nil? || @fields.empty?
|
129
|
+
# no fields requested, so add all geoip hash items to
|
130
|
+
# the event's fields.
|
131
|
+
# convert key to string (normally a Symbol)
|
132
|
+
event[@target][key.to_s] = value
|
133
|
+
elsif @fields.include?(key.to_s)
|
134
|
+
# Check if the key is in our fields array
|
135
|
+
# convert key to string (normally a Symbol)
|
136
|
+
event[@target][key.to_s] = value
|
137
|
+
end
|
138
|
+
end # geo_data_hash.each
|
139
|
+
if event[@target].key?('latitude') && event[@target].key?('longitude')
|
140
|
+
# If we have latitude and longitude values, add the location field as GeoJSON array
|
141
|
+
event[@target]['location'] = [ event[@target]["longitude"].to_f, event[@target]["latitude"].to_f ]
|
142
|
+
end
|
143
|
+
filter_matched(event)
|
144
|
+
end # def filter
|
145
|
+
end # class LogStash::Filters::GeoIP
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/filters/base"
|
3
|
+
require "logstash/namespace"
|
4
|
+
|
5
|
+
# Grep filter. Useful for dropping events you don't want to pass, or
|
6
|
+
# adding tags or fields to events that match.
|
7
|
+
#
|
8
|
+
# Events not matched are dropped. If 'negate' is set to true (defaults false),
|
9
|
+
# then matching events are dropped.
|
10
|
+
class LogStash::Filters::Grep < LogStash::Filters::Base
|
11
|
+
|
12
|
+
config_name "grep"
|
13
|
+
milestone 3
|
14
|
+
|
15
|
+
# Drop events that don't match
|
16
|
+
#
|
17
|
+
# If this is set to false, no events will be dropped at all. Rather, the
|
18
|
+
# requested tags and fields will be added to matching events, and
|
19
|
+
# non-matching events will be passed through unchanged.
|
20
|
+
config :drop, :validate => :boolean, :default => true
|
21
|
+
|
22
|
+
# Negate the match. Similar to 'grep -v'
|
23
|
+
#
|
24
|
+
# If this is set to true, then any positive matches will result in the
|
25
|
+
# event being cancelled and dropped. Non-matching will be allowed
|
26
|
+
# through.
|
27
|
+
config :negate, :validate => :boolean, :default => false
|
28
|
+
|
29
|
+
# A hash of matches of field => regexp. If multiple matches are specified,
|
30
|
+
# all must match for the grep to be considered successful. Normal regular
|
31
|
+
# expressions are supported here.
|
32
|
+
#
|
33
|
+
# For example:
|
34
|
+
#
|
35
|
+
# filter {
|
36
|
+
# grep {
|
37
|
+
# match => [ "message", "hello world" ]
|
38
|
+
# }
|
39
|
+
# }
|
40
|
+
#
|
41
|
+
# The above will drop all events with a message not matching "hello world" as
|
42
|
+
# a regular expression.
|
43
|
+
config :match, :validate => :hash, :default => {}
|
44
|
+
|
45
|
+
# Use case-insensitive matching. Similar to 'grep -i'
|
46
|
+
#
|
47
|
+
# If enabled, ignore case distinctions in the patterns.
|
48
|
+
config :ignore_case, :validate => :boolean, :default => false
|
49
|
+
|
50
|
+
public
|
51
|
+
def register
|
52
|
+
@logger.warn("The 'grep' plugin is no longer necessary now that you can do if/elsif/else in logstash configs. This plugin will be removed in the future. If you need to drop events, please use the drop filter. If you need to take action based on a match, use an 'if' block and the mutate filter. See the following URL for details on how to use if/elsif/else in your logstash configs:http://logstash.net/docs/#{LOGSTASH_VERSION}/configuration")
|
53
|
+
|
54
|
+
@patterns = Hash.new { |h,k| h[k] = [] }
|
55
|
+
|
56
|
+
# TODO(sissel):
|
57
|
+
@match.each do |field, pattern|
|
58
|
+
|
59
|
+
pattern = [pattern] if pattern.is_a?(String)
|
60
|
+
pattern.each do |p|
|
61
|
+
re = Regexp.new(p, @ignore_case ? Regexp::IGNORECASE : 0)
|
62
|
+
@patterns[field] << re
|
63
|
+
@logger.debug? and @logger.debug("Registered grep", :type => @type, :field => field,
|
64
|
+
:pattern => p, :regexp => re)
|
65
|
+
end
|
66
|
+
end # @match.merge.each
|
67
|
+
end # def register
|
68
|
+
|
69
|
+
public
|
70
|
+
def filter(event)
|
71
|
+
return unless filter?(event)
|
72
|
+
|
73
|
+
@logger.debug("Running grep filter", :event => event, :config => config)
|
74
|
+
matches = 0
|
75
|
+
|
76
|
+
# If negate is set but no patterns are given, drop the event.
|
77
|
+
# This is useful in cases where you want to drop all events with
|
78
|
+
# a given type or set of tags
|
79
|
+
#
|
80
|
+
# filter {
|
81
|
+
# grep {
|
82
|
+
# negate => true
|
83
|
+
# type => blah
|
84
|
+
# }
|
85
|
+
# }
|
86
|
+
if @negate && @patterns.empty?
|
87
|
+
event.cancel
|
88
|
+
return
|
89
|
+
end
|
90
|
+
|
91
|
+
@patterns.each do |field, regexes|
|
92
|
+
# For each match object, we have to match everything in order to
|
93
|
+
# apply any fields/tags.
|
94
|
+
match_count = 0
|
95
|
+
match_want = 0
|
96
|
+
regexes.each do |re|
|
97
|
+
match_want += 1
|
98
|
+
|
99
|
+
# Events without this field, with negate enabled, count as a match.
|
100
|
+
# With negate disabled, we can't possibly match, so skip ahead.
|
101
|
+
if event[field].nil?
|
102
|
+
if @negate
|
103
|
+
msg = "Field not present, but negate is true; marking as a match"
|
104
|
+
@logger.debug(msg, :field => field, :event => event)
|
105
|
+
match_count += 1
|
106
|
+
else
|
107
|
+
@logger.debug("Skipping match object, field not present",
|
108
|
+
:field => field, :event => event)
|
109
|
+
end
|
110
|
+
# Either way, don't try to process -- may end up with extra unwanted
|
111
|
+
# +1's to match_count
|
112
|
+
next
|
113
|
+
end
|
114
|
+
|
115
|
+
(event[field].is_a?(Array) ? event[field] : [event[field]]).each do |value|
|
116
|
+
value = value.to_s if value.is_a?(Numeric)
|
117
|
+
if @negate
|
118
|
+
@logger.debug("negate match", :regexp => re, :value => value)
|
119
|
+
next if re.match(value)
|
120
|
+
@logger.debug("grep not-matched (negate requested)", field => value)
|
121
|
+
else
|
122
|
+
@logger.debug("want match", :regexp => re, :value => value)
|
123
|
+
next unless re.match(value)
|
124
|
+
@logger.debug("grep matched", field => value)
|
125
|
+
end
|
126
|
+
match_count += 1
|
127
|
+
break
|
128
|
+
end # each value in event[field]
|
129
|
+
end # regexes.each
|
130
|
+
|
131
|
+
if match_count == match_want
|
132
|
+
matches += 1
|
133
|
+
@logger.debug("matched all fields", :count => match_count)
|
134
|
+
else
|
135
|
+
@logger.debug("match failed", :count => match_count, :wanted => match_want)
|
136
|
+
end # match["match"].each
|
137
|
+
end # @patterns.each
|
138
|
+
|
139
|
+
if matches == @patterns.length
|
140
|
+
filter_matched(event)
|
141
|
+
else
|
142
|
+
if @drop == true
|
143
|
+
@logger.debug("grep: dropping event, no matches")
|
144
|
+
event.cancel
|
145
|
+
else
|
146
|
+
@logger.debug("grep: no matches, but drop set to false")
|
147
|
+
end
|
148
|
+
return
|
149
|
+
end
|
150
|
+
|
151
|
+
@logger.debug("Event after grep filter", :event => event)
|
152
|
+
end # def filter
|
153
|
+
end # class LogStash::Filters::Grep
|
@@ -0,0 +1,425 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/filters/base"
|
3
|
+
require "logstash/namespace"
|
4
|
+
require "set"
|
5
|
+
|
6
|
+
# Parse arbitrary text and structure it.
|
7
|
+
#
|
8
|
+
# Grok is currently the best way in logstash to parse crappy unstructured log
|
9
|
+
# data into something structured and queryable.
|
10
|
+
#
|
11
|
+
# This tool is perfect for syslog logs, apache and other webserver logs, mysql
|
12
|
+
# logs, and in general, any log format that is generally written for humans
|
13
|
+
# and not computer consumption.
|
14
|
+
#
|
15
|
+
# Logstash ships with about 120 patterns by default. You can find them here:
|
16
|
+
# <https://github.com/logstash/logstash/tree/v%VERSION%/patterns>. You can add
|
17
|
+
# your own trivially. (See the patterns_dir setting)
|
18
|
+
#
|
19
|
+
# If you need help building patterns to match your logs, you will find the
|
20
|
+
# <http://grokdebug.herokuapp.com> too quite useful!
|
21
|
+
#
|
22
|
+
# #### Grok Basics
|
23
|
+
#
|
24
|
+
# Grok works by combining text patterns into something that matches your
|
25
|
+
# logs.
|
26
|
+
#
|
27
|
+
# The syntax for a grok pattern is `%{SYNTAX:SEMANTIC}`
|
28
|
+
#
|
29
|
+
# The `SYNTAX` is the name of the pattern that will match your text. For
|
30
|
+
# example, "3.44" will be matched by the NUMBER pattern and "55.3.244.1" will
|
31
|
+
# be matched by the IP pattern. The syntax is how you match.
|
32
|
+
#
|
33
|
+
# The `SEMANTIC` is the identifier you give to the piece of text being matched.
|
34
|
+
# For example, "3.44" could be the duration of an event, so you could call it
|
35
|
+
# simply 'duration'. Further, a string "55.3.244.1" might identify the 'client'
|
36
|
+
# making a request.
|
37
|
+
#
|
38
|
+
# Optionally you can add a data type conversion to your grok pattern. By default
|
39
|
+
# all semantics are saved as strings. If you wish to convert a semantic's data type,
|
40
|
+
# for example change a string to an integer then suffix it with the target data type.
|
41
|
+
# For example `%{NUMBER:num:int}` which converts the 'num' semantic from a string to an
|
42
|
+
# integer. Currently the only supported conversions are `int` and `float`.
|
43
|
+
#
|
44
|
+
# #### Example
|
45
|
+
#
|
46
|
+
# With that idea of a syntax and semantic, we can pull out useful fields from a
|
47
|
+
# sample log like this fictional http request log:
|
48
|
+
#
|
49
|
+
# 55.3.244.1 GET /index.html 15824 0.043
|
50
|
+
#
|
51
|
+
# The pattern for this could be:
|
52
|
+
#
|
53
|
+
# %{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}
|
54
|
+
#
|
55
|
+
# A more realistic example, let's read these logs from a file:
|
56
|
+
#
|
57
|
+
# input {
|
58
|
+
# file {
|
59
|
+
# path => "/var/log/http.log"
|
60
|
+
# }
|
61
|
+
# }
|
62
|
+
# filter {
|
63
|
+
# grok {
|
64
|
+
# match => [ "message", "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}" ]
|
65
|
+
# }
|
66
|
+
# }
|
67
|
+
#
|
68
|
+
# After the grok filter, the event will have a few extra fields in it:
|
69
|
+
#
|
70
|
+
# * client: 55.3.244.1
|
71
|
+
# * method: GET
|
72
|
+
# * request: /index.html
|
73
|
+
# * bytes: 15824
|
74
|
+
# * duration: 0.043
|
75
|
+
#
|
76
|
+
# #### Regular Expressions
|
77
|
+
#
|
78
|
+
# Grok sits on top of regular expressions, so any regular expressions are valid
|
79
|
+
# in grok as well. The regular expression library is Oniguruma, and you can see
|
80
|
+
# the full supported regexp syntax [on the Onigiruma
|
81
|
+
# site](http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt)
|
82
|
+
#
|
83
|
+
# #### Custom Patterns
|
84
|
+
#
|
85
|
+
# Sometimes logstash doesn't have a pattern you need. For this, you have
|
86
|
+
# a few options.
|
87
|
+
#
|
88
|
+
# First, you can use the Oniguruma syntax for 'named capture' which will
|
89
|
+
# let you match a piece of text and save it as a field:
|
90
|
+
#
|
91
|
+
# (?<field_name>the pattern here)
|
92
|
+
#
|
93
|
+
# For example, postfix logs have a 'queue id' that is an 10 or 11-character
|
94
|
+
# hexadecimal value. I can capture that easily like this:
|
95
|
+
#
|
96
|
+
# (?<queue_id>[0-9A-F]{10,11})
|
97
|
+
#
|
98
|
+
# Alternately, you can create a custom patterns file.
|
99
|
+
#
|
100
|
+
# * Create a directory called `patterns` with a file in it called `extra`
|
101
|
+
# (the file name doesn't matter, but name it meaningfully for yourself)
|
102
|
+
# * In that file, write the pattern you need as the pattern name, a space, then
|
103
|
+
# the regexp for that pattern.
|
104
|
+
#
|
105
|
+
# For example, doing the postfix queue id example as above:
|
106
|
+
#
|
107
|
+
# # in ./patterns/postfix
|
108
|
+
# POSTFIX_QUEUEID [0-9A-F]{10,11}
|
109
|
+
#
|
110
|
+
# Then use the `patterns_dir` setting in this plugin to tell logstash where
|
111
|
+
# your custom patterns directory is. Here's a full example with a sample log:
|
112
|
+
#
|
113
|
+
# Jan 1 06:25:43 mailserver14 postfix/cleanup[21403]: BEF25A72965: message-id=<20130101142543.5828399CCAF@mailserver14.example.com>
|
114
|
+
#
|
115
|
+
# filter {
|
116
|
+
# grok {
|
117
|
+
# patterns_dir => "./patterns"
|
118
|
+
# match => [ "message", "%{SYSLOGBASE} %{POSTFIX_QUEUEID:queue_id}: %{GREEDYDATA:syslog_message}" ]
|
119
|
+
# }
|
120
|
+
# }
|
121
|
+
#
|
122
|
+
# The above will match and result in the following fields:
|
123
|
+
#
|
124
|
+
# * timestamp: Jan 1 06:25:43
|
125
|
+
# * logsource: mailserver14
|
126
|
+
# * program: postfix/cleanup
|
127
|
+
# * pid: 21403
|
128
|
+
# * queue_id: BEF25A72965
|
129
|
+
# * syslog_message: message-id=<20130101142543.5828399CCAF@mailserver14.example.com
|
130
|
+
#
|
131
|
+
# The `timestamp`, `logsource`, `program`, and `pid` fields come from the
|
132
|
+
# SYSLOGBASE pattern which itself is defined by other patterns.
|
133
|
+
class LogStash::Filters::Grok < LogStash::Filters::Base
|
134
|
+
config_name "grok"
|
135
|
+
milestone 3
|
136
|
+
|
137
|
+
# Specify a pattern to parse with. This will match the 'message' field.
|
138
|
+
#
|
139
|
+
# If you want to match other fields than message, use the 'match' setting.
|
140
|
+
# Multiple patterns is fine.
|
141
|
+
config :pattern, :validate => :array, :deprecated => "You should use this instead: match => { \"message\" => \"your pattern here\" }"
|
142
|
+
|
143
|
+
# A hash of matches of field => value
|
144
|
+
#
|
145
|
+
# For example:
|
146
|
+
#
|
147
|
+
# filter {
|
148
|
+
# grok {
|
149
|
+
# match => [ "message", "Duration: %{NUMBER:duration}" ]
|
150
|
+
# }
|
151
|
+
# }
|
152
|
+
#
|
153
|
+
config :match, :validate => :hash, :default => {}
|
154
|
+
|
155
|
+
#
|
156
|
+
# logstash ships by default with a bunch of patterns, so you don't
|
157
|
+
# necessarily need to define this yourself unless you are adding additional
|
158
|
+
# patterns.
|
159
|
+
#
|
160
|
+
# Pattern files are plain text with format:
|
161
|
+
#
|
162
|
+
# NAME PATTERN
|
163
|
+
#
|
164
|
+
# For example:
|
165
|
+
#
|
166
|
+
# NUMBER \d+
|
167
|
+
config :patterns_dir, :validate => :array, :default => []
|
168
|
+
|
169
|
+
# Drop if matched. Note, this feature may not stay. It is preferable to combine
|
170
|
+
# grok + grep filters to do parsing + dropping.
|
171
|
+
#
|
172
|
+
# requested in: googlecode/issue/26
|
173
|
+
config :drop_if_match, :validate => :boolean, :default => false
|
174
|
+
|
175
|
+
# Break on first match. The first successful match by grok will result in the
|
176
|
+
# filter being finished. If you want grok to try all patterns (maybe you are
|
177
|
+
# parsing different things), then set this to false.
|
178
|
+
config :break_on_match, :validate => :boolean, :default => true
|
179
|
+
|
180
|
+
# If true, only store named captures from grok.
|
181
|
+
config :named_captures_only, :validate => :boolean, :default => true
|
182
|
+
|
183
|
+
# If true, keep empty captures as event fields.
|
184
|
+
config :keep_empty_captures, :validate => :boolean, :default => false
|
185
|
+
|
186
|
+
# If true, make single-value fields simply that value, not an array
|
187
|
+
# containing that one value.
|
188
|
+
config :singles, :validate => :boolean, :default => true, :deprecated => "This behavior is the default now, you don't need to set it."
|
189
|
+
|
190
|
+
# Append values to the 'tags' field when there has been no
|
191
|
+
# successful match
|
192
|
+
config :tag_on_failure, :validate => :array, :default => ["_grokparsefailure"]
|
193
|
+
|
194
|
+
# The fields to overwrite.
|
195
|
+
#
|
196
|
+
# This allows you to overwrite a value in a field that already exists.
|
197
|
+
#
|
198
|
+
# For example, if you have a syslog line in the 'message' field, you can
|
199
|
+
# overwrite the 'message' field with part of the match like so:
|
200
|
+
#
|
201
|
+
# filter {
|
202
|
+
# grok {
|
203
|
+
# match => [
|
204
|
+
# "message",
|
205
|
+
# "%{SYSLOGBASE} %{DATA:message}
|
206
|
+
# ]
|
207
|
+
# overwrite => [ "message" ]
|
208
|
+
# }
|
209
|
+
# }
|
210
|
+
#
|
211
|
+
# In this case, a line like "May 29 16:37:11 sadness logger: hello world"
|
212
|
+
# will be parsed and 'hello world' will overwrite the original message.
|
213
|
+
config :overwrite, :validate => :array, :default => []
|
214
|
+
|
215
|
+
# Detect if we are running from a jarfile, pick the right path.
|
216
|
+
@@patterns_path ||= Set.new
|
217
|
+
if __FILE__ =~ /file:\/.*\.jar!.*/
|
218
|
+
@@patterns_path += ["#{File.dirname(__FILE__)}/../../patterns/*"]
|
219
|
+
else
|
220
|
+
@@patterns_path += ["#{File.dirname(__FILE__)}/../../../patterns/*"]
|
221
|
+
end
|
222
|
+
|
223
|
+
public
|
224
|
+
def initialize(params)
|
225
|
+
super(params)
|
226
|
+
@match["message"] ||= []
|
227
|
+
@match["message"] += @pattern if @pattern # the config 'pattern' value (array)
|
228
|
+
# a cache of capture name handler methods.
|
229
|
+
@handlers = {}
|
230
|
+
end
|
231
|
+
|
232
|
+
public
|
233
|
+
def register
|
234
|
+
require "grok-pure" # rubygem 'jls-grok'
|
235
|
+
|
236
|
+
@patternfiles = []
|
237
|
+
|
238
|
+
# Have @@patterns_path show first. Last-in pattern definitions win; this
|
239
|
+
# will let folks redefine built-in patterns at runtime.
|
240
|
+
@patterns_dir = @@patterns_path.to_a + @patterns_dir
|
241
|
+
@logger.info? and @logger.info("Grok patterns path", :patterns_dir => @patterns_dir)
|
242
|
+
@patterns_dir.each do |path|
|
243
|
+
# Can't read relative paths from jars, try to normalize away '../'
|
244
|
+
while path =~ /file:\/.*\.jar!.*\/\.\.\//
|
245
|
+
# replace /foo/bar/../baz => /foo/baz
|
246
|
+
path = path.gsub(/[^\/]+\/\.\.\//, "")
|
247
|
+
@logger.debug? and @logger.debug("In-jar path to read", :path => path)
|
248
|
+
end
|
249
|
+
|
250
|
+
if File.directory?(path)
|
251
|
+
path = File.join(path, "*")
|
252
|
+
end
|
253
|
+
|
254
|
+
Dir.glob(path).each do |file|
|
255
|
+
@logger.info? and @logger.info("Grok loading patterns from file", :path => file)
|
256
|
+
@patternfiles << file
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
@patterns = Hash.new { |h,k| h[k] = [] }
|
261
|
+
|
262
|
+
@logger.info? and @logger.info("Match data", :match => @match)
|
263
|
+
|
264
|
+
@match.each do |field, patterns|
|
265
|
+
patterns = [patterns] if patterns.is_a?(String)
|
266
|
+
|
267
|
+
if !@patterns.include?(field)
|
268
|
+
@patterns[field] = Grok::Pile.new
|
269
|
+
#@patterns[field].logger = @logger
|
270
|
+
|
271
|
+
add_patterns_from_files(@patternfiles, @patterns[field])
|
272
|
+
end
|
273
|
+
@logger.info? and @logger.info("Grok compile", :field => field, :patterns => patterns)
|
274
|
+
patterns.each do |pattern|
|
275
|
+
@logger.debug? and @logger.debug("regexp: #{@type}/#{field}", :pattern => pattern)
|
276
|
+
@patterns[field].compile(pattern)
|
277
|
+
end
|
278
|
+
end # @match.each
|
279
|
+
end # def register
|
280
|
+
|
281
|
+
public
|
282
|
+
def filter(event)
|
283
|
+
return unless filter?(event)
|
284
|
+
|
285
|
+
matched = false
|
286
|
+
done = false
|
287
|
+
|
288
|
+
@logger.debug? and @logger.debug("Running grok filter", :event => event);
|
289
|
+
@patterns.each do |field, grok|
|
290
|
+
if match(grok, field, event)
|
291
|
+
matched = true
|
292
|
+
break if @break_on_match
|
293
|
+
end
|
294
|
+
#break if done
|
295
|
+
end # @patterns.each
|
296
|
+
|
297
|
+
if matched
|
298
|
+
filter_matched(event)
|
299
|
+
else
|
300
|
+
# Tag this event if we can't parse it. We can use this later to
|
301
|
+
# reparse+reindex logs if we improve the patterns given.
|
302
|
+
@tag_on_failure.each do |tag|
|
303
|
+
event["tags"] ||= []
|
304
|
+
event["tags"] << tag unless event["tags"].include?(tag)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
@logger.debug? and @logger.debug("Event now: ", :event => event)
|
309
|
+
end # def filter
|
310
|
+
|
311
|
+
private
|
312
|
+
def match(grok, field, event)
|
313
|
+
input = event[field]
|
314
|
+
if input.is_a?(Array)
|
315
|
+
success = true
|
316
|
+
input.each do |input|
|
317
|
+
grok, match = grok.match(input)
|
318
|
+
if match
|
319
|
+
match.each_capture do |capture, value|
|
320
|
+
handle(capture, value, event)
|
321
|
+
end
|
322
|
+
else
|
323
|
+
success = false
|
324
|
+
end
|
325
|
+
end
|
326
|
+
return success
|
327
|
+
#elsif input.is_a?(String)
|
328
|
+
else
|
329
|
+
# Convert anything else to string (number, hash, etc)
|
330
|
+
grok, match = grok.match(input.to_s)
|
331
|
+
return false if !match
|
332
|
+
|
333
|
+
match.each_capture do |capture, value|
|
334
|
+
handle(capture, value, event)
|
335
|
+
end
|
336
|
+
return true
|
337
|
+
end
|
338
|
+
rescue StandardError => e
|
339
|
+
@logger.warn("Grok regexp threw exception", :exception => e.message)
|
340
|
+
end
|
341
|
+
|
342
|
+
private
|
343
|
+
def handle(capture, value, event)
|
344
|
+
handler = @handlers[capture] ||= compile_capture_handler(capture)
|
345
|
+
return handler.call(value, event)
|
346
|
+
end
|
347
|
+
|
348
|
+
private
|
349
|
+
def compile_capture_handler(capture)
|
350
|
+
# SYNTAX:SEMANTIC:TYPE
|
351
|
+
syntax, semantic, coerce = capture.split(":")
|
352
|
+
|
353
|
+
# each_capture do |fullname, value|
|
354
|
+
# capture_handlers[fullname].call(value, event)
|
355
|
+
# end
|
356
|
+
|
357
|
+
code = []
|
358
|
+
code << "# for capture #{capture}"
|
359
|
+
code << "lambda do |value, event|"
|
360
|
+
#code << " p :value => value, :event => event"
|
361
|
+
if semantic.nil?
|
362
|
+
if @named_captures_only
|
363
|
+
# Abort early if we are only keeping named (semantic) captures
|
364
|
+
# and this capture has no semantic name.
|
365
|
+
code << " return"
|
366
|
+
else
|
367
|
+
field = syntax
|
368
|
+
end
|
369
|
+
else
|
370
|
+
field = semantic
|
371
|
+
end
|
372
|
+
code << " return if value.nil? || value.empty?" unless @keep_empty_captures
|
373
|
+
if coerce
|
374
|
+
case coerce
|
375
|
+
when "int"; code << " value = value.to_i"
|
376
|
+
when "float"; code << " value = value.to_f"
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
code << " # field: #{field}"
|
381
|
+
if @overwrite.include?(field)
|
382
|
+
code << " event[field] = value"
|
383
|
+
else
|
384
|
+
code << " v = event[field]"
|
385
|
+
code << " if v.nil?"
|
386
|
+
code << " event[field] = value"
|
387
|
+
code << " elsif v.is_a?(Array)"
|
388
|
+
code << " event[field] << value"
|
389
|
+
code << " elsif v.is_a?(String)"
|
390
|
+
# Promote to array since we aren't overwriting.
|
391
|
+
code << " event[field] = [v, value]"
|
392
|
+
code << " end"
|
393
|
+
end
|
394
|
+
code << " return"
|
395
|
+
code << "end"
|
396
|
+
|
397
|
+
#puts code
|
398
|
+
return eval(code.join("\n"), binding, "<grok capture #{capture}>")
|
399
|
+
end # def compile_capture_handler
|
400
|
+
|
401
|
+
private
|
402
|
+
def add_patterns_from_files(paths, pile)
|
403
|
+
paths.each { |path| add_patterns_from_file(path, pile) }
|
404
|
+
end # def add_patterns_from_files
|
405
|
+
|
406
|
+
private
|
407
|
+
def add_patterns_from_file(path, pile)
|
408
|
+
# Check if the file path is a jar, if so, we'll have to read it ourselves
|
409
|
+
# since libgrok won't know what to do with it.
|
410
|
+
if path =~ /file:\/.*\.jar!.*/
|
411
|
+
File.new(path).each do |line|
|
412
|
+
next if line =~ /^(?:\s*#|\s*$)/
|
413
|
+
# In some cases I have seen 'file.each' yield lines with newlines at
|
414
|
+
# the end. I don't know if this is a bug or intentional, but we need
|
415
|
+
# to chomp it.
|
416
|
+
name, pattern = line.chomp.split(/\s+/, 2)
|
417
|
+
@logger.debug? and @logger.debug("Adding pattern from file", :name => name,
|
418
|
+
:pattern => pattern, :path => path)
|
419
|
+
pile.add_pattern(name, pattern)
|
420
|
+
end
|
421
|
+
else
|
422
|
+
pile.add_patterns_from_file(path)
|
423
|
+
end
|
424
|
+
end # def add_patterns_from_file
|
425
|
+
end # class LogStash::Filters::Grok
|