logstash-lib 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (419) hide show
  1. data/.gitignore +24 -0
  2. data/.tailor +8 -0
  3. data/.travis.yml +12 -0
  4. data/CHANGELOG +1185 -0
  5. data/CONTRIBUTING.md +61 -0
  6. data/CONTRIBUTORS +79 -0
  7. data/LICENSE +14 -0
  8. data/Makefile +460 -0
  9. data/README.md +120 -0
  10. data/STYLE.md +96 -0
  11. data/bin/logstash +37 -0
  12. data/bin/logstash-test +4 -0
  13. data/bin/logstash-web +4 -0
  14. data/bin/logstash.lib.sh +78 -0
  15. data/bot/check_pull_changelog.rb +89 -0
  16. data/docs/configuration.md +260 -0
  17. data/docs/docgen.rb +242 -0
  18. data/docs/extending/example-add-a-new-filter.md +121 -0
  19. data/docs/extending/index.md +91 -0
  20. data/docs/flags.md +43 -0
  21. data/docs/generate_index.rb +28 -0
  22. data/docs/index.html.erb +56 -0
  23. data/docs/learn.md +46 -0
  24. data/docs/life-of-an-event.md +109 -0
  25. data/docs/logging-tool-comparisons.md +60 -0
  26. data/docs/plugin-doc.html.erb +91 -0
  27. data/docs/plugin-milestones.md +41 -0
  28. data/docs/plugin-synopsis.html.erb +24 -0
  29. data/docs/release-engineering.md +46 -0
  30. data/docs/release-test-results.md +14 -0
  31. data/docs/repositories.md +35 -0
  32. data/docs/tutorials/10-minute-walkthrough/apache-elasticsearch.conf +35 -0
  33. data/docs/tutorials/10-minute-walkthrough/apache-parse.conf +33 -0
  34. data/docs/tutorials/10-minute-walkthrough/apache_log.1 +1 -0
  35. data/docs/tutorials/10-minute-walkthrough/apache_log.2.bz2 +0 -0
  36. data/docs/tutorials/10-minute-walkthrough/hello-search.conf +25 -0
  37. data/docs/tutorials/10-minute-walkthrough/hello.conf +16 -0
  38. data/docs/tutorials/10-minute-walkthrough/index.md +124 -0
  39. data/docs/tutorials/10-minute-walkthrough/step-5-output.txt +17 -0
  40. data/docs/tutorials/getting-started-centralized-overview-diagram.png +0 -0
  41. data/docs/tutorials/getting-started-centralized-overview-diagram.xml +1 -0
  42. data/docs/tutorials/getting-started-centralized.md +217 -0
  43. data/docs/tutorials/getting-started-simple.md +200 -0
  44. data/docs/tutorials/just-enough-rabbitmq-for-logstash.md +201 -0
  45. data/docs/tutorials/media/frontend-response-codes.png +0 -0
  46. data/docs/tutorials/metrics-from-logs.md +84 -0
  47. data/docs/tutorials/zeromq.md +118 -0
  48. data/extract_services.rb +29 -0
  49. data/gembag.rb +64 -0
  50. data/lib/logstash-event.rb +2 -0
  51. data/lib/logstash.rb +4 -0
  52. data/lib/logstash/JRUBY-6970-openssl.rb +22 -0
  53. data/lib/logstash/JRUBY-6970.rb +102 -0
  54. data/lib/logstash/agent.rb +305 -0
  55. data/lib/logstash/certs/cacert.pem +3895 -0
  56. data/lib/logstash/codecs/base.rb +49 -0
  57. data/lib/logstash/codecs/compress_spooler.rb +50 -0
  58. data/lib/logstash/codecs/dots.rb +18 -0
  59. data/lib/logstash/codecs/edn.rb +28 -0
  60. data/lib/logstash/codecs/edn_lines.rb +36 -0
  61. data/lib/logstash/codecs/fluent.rb +55 -0
  62. data/lib/logstash/codecs/graphite.rb +114 -0
  63. data/lib/logstash/codecs/json.rb +41 -0
  64. data/lib/logstash/codecs/json_lines.rb +52 -0
  65. data/lib/logstash/codecs/json_spooler.rb +22 -0
  66. data/lib/logstash/codecs/line.rb +58 -0
  67. data/lib/logstash/codecs/msgpack.rb +43 -0
  68. data/lib/logstash/codecs/multiline.rb +189 -0
  69. data/lib/logstash/codecs/netflow.rb +342 -0
  70. data/lib/logstash/codecs/netflow/util.rb +212 -0
  71. data/lib/logstash/codecs/noop.rb +19 -0
  72. data/lib/logstash/codecs/oldlogstashjson.rb +56 -0
  73. data/lib/logstash/codecs/plain.rb +48 -0
  74. data/lib/logstash/codecs/rubydebug.rb +22 -0
  75. data/lib/logstash/codecs/spool.rb +38 -0
  76. data/lib/logstash/config/Makefile +4 -0
  77. data/lib/logstash/config/config_ast.rb +380 -0
  78. data/lib/logstash/config/file.rb +39 -0
  79. data/lib/logstash/config/grammar.rb +3504 -0
  80. data/lib/logstash/config/grammar.treetop +241 -0
  81. data/lib/logstash/config/mixin.rb +464 -0
  82. data/lib/logstash/config/registry.rb +13 -0
  83. data/lib/logstash/config/test.conf +18 -0
  84. data/lib/logstash/errors.rb +10 -0
  85. data/lib/logstash/event.rb +262 -0
  86. data/lib/logstash/filters/advisor.rb +178 -0
  87. data/lib/logstash/filters/alter.rb +173 -0
  88. data/lib/logstash/filters/anonymize.rb +93 -0
  89. data/lib/logstash/filters/base.rb +190 -0
  90. data/lib/logstash/filters/checksum.rb +50 -0
  91. data/lib/logstash/filters/cidr.rb +76 -0
  92. data/lib/logstash/filters/cipher.rb +145 -0
  93. data/lib/logstash/filters/clone.rb +35 -0
  94. data/lib/logstash/filters/collate.rb +114 -0
  95. data/lib/logstash/filters/csv.rb +94 -0
  96. data/lib/logstash/filters/date.rb +244 -0
  97. data/lib/logstash/filters/dns.rb +201 -0
  98. data/lib/logstash/filters/drop.rb +32 -0
  99. data/lib/logstash/filters/elapsed.rb +256 -0
  100. data/lib/logstash/filters/elasticsearch.rb +73 -0
  101. data/lib/logstash/filters/environment.rb +27 -0
  102. data/lib/logstash/filters/extractnumbers.rb +84 -0
  103. data/lib/logstash/filters/gelfify.rb +52 -0
  104. data/lib/logstash/filters/geoip.rb +145 -0
  105. data/lib/logstash/filters/grep.rb +153 -0
  106. data/lib/logstash/filters/grok.rb +425 -0
  107. data/lib/logstash/filters/grokdiscovery.rb +75 -0
  108. data/lib/logstash/filters/i18n.rb +51 -0
  109. data/lib/logstash/filters/json.rb +90 -0
  110. data/lib/logstash/filters/json_encode.rb +52 -0
  111. data/lib/logstash/filters/kv.rb +232 -0
  112. data/lib/logstash/filters/metaevent.rb +68 -0
  113. data/lib/logstash/filters/metrics.rb +237 -0
  114. data/lib/logstash/filters/multiline.rb +241 -0
  115. data/lib/logstash/filters/mutate.rb +399 -0
  116. data/lib/logstash/filters/noop.rb +21 -0
  117. data/lib/logstash/filters/prune.rb +149 -0
  118. data/lib/logstash/filters/punct.rb +32 -0
  119. data/lib/logstash/filters/railsparallelrequest.rb +86 -0
  120. data/lib/logstash/filters/range.rb +142 -0
  121. data/lib/logstash/filters/ruby.rb +42 -0
  122. data/lib/logstash/filters/sleep.rb +111 -0
  123. data/lib/logstash/filters/split.rb +64 -0
  124. data/lib/logstash/filters/sumnumbers.rb +73 -0
  125. data/lib/logstash/filters/syslog_pri.rb +107 -0
  126. data/lib/logstash/filters/translate.rb +121 -0
  127. data/lib/logstash/filters/unique.rb +29 -0
  128. data/lib/logstash/filters/urldecode.rb +57 -0
  129. data/lib/logstash/filters/useragent.rb +112 -0
  130. data/lib/logstash/filters/uuid.rb +58 -0
  131. data/lib/logstash/filters/xml.rb +139 -0
  132. data/lib/logstash/filters/zeromq.rb +123 -0
  133. data/lib/logstash/filterworker.rb +122 -0
  134. data/lib/logstash/inputs/base.rb +125 -0
  135. data/lib/logstash/inputs/collectd.rb +306 -0
  136. data/lib/logstash/inputs/drupal_dblog.rb +323 -0
  137. data/lib/logstash/inputs/drupal_dblog/jdbcconnection.rb +66 -0
  138. data/lib/logstash/inputs/elasticsearch.rb +140 -0
  139. data/lib/logstash/inputs/eventlog.rb +129 -0
  140. data/lib/logstash/inputs/eventlog/racob_fix.rb +44 -0
  141. data/lib/logstash/inputs/exec.rb +69 -0
  142. data/lib/logstash/inputs/file.rb +146 -0
  143. data/lib/logstash/inputs/ganglia.rb +127 -0
  144. data/lib/logstash/inputs/ganglia/gmondpacket.rb +146 -0
  145. data/lib/logstash/inputs/ganglia/xdr.rb +327 -0
  146. data/lib/logstash/inputs/gelf.rb +138 -0
  147. data/lib/logstash/inputs/gemfire.rb +222 -0
  148. data/lib/logstash/inputs/generator.rb +97 -0
  149. data/lib/logstash/inputs/graphite.rb +41 -0
  150. data/lib/logstash/inputs/heroku.rb +51 -0
  151. data/lib/logstash/inputs/imap.rb +136 -0
  152. data/lib/logstash/inputs/irc.rb +84 -0
  153. data/lib/logstash/inputs/log4j.rb +136 -0
  154. data/lib/logstash/inputs/lumberjack.rb +53 -0
  155. data/lib/logstash/inputs/pipe.rb +57 -0
  156. data/lib/logstash/inputs/rabbitmq.rb +126 -0
  157. data/lib/logstash/inputs/rabbitmq/bunny.rb +118 -0
  158. data/lib/logstash/inputs/rabbitmq/hot_bunnies.rb +1 -0
  159. data/lib/logstash/inputs/rabbitmq/march_hare.rb +129 -0
  160. data/lib/logstash/inputs/redis.rb +263 -0
  161. data/lib/logstash/inputs/relp.rb +106 -0
  162. data/lib/logstash/inputs/s3.rb +279 -0
  163. data/lib/logstash/inputs/snmptrap.rb +87 -0
  164. data/lib/logstash/inputs/sqlite.rb +185 -0
  165. data/lib/logstash/inputs/sqs.rb +172 -0
  166. data/lib/logstash/inputs/stdin.rb +46 -0
  167. data/lib/logstash/inputs/stomp.rb +84 -0
  168. data/lib/logstash/inputs/syslog.rb +237 -0
  169. data/lib/logstash/inputs/tcp.rb +231 -0
  170. data/lib/logstash/inputs/threadable.rb +18 -0
  171. data/lib/logstash/inputs/twitter.rb +82 -0
  172. data/lib/logstash/inputs/udp.rb +81 -0
  173. data/lib/logstash/inputs/unix.rb +163 -0
  174. data/lib/logstash/inputs/varnishlog.rb +48 -0
  175. data/lib/logstash/inputs/websocket.rb +50 -0
  176. data/lib/logstash/inputs/wmi.rb +72 -0
  177. data/lib/logstash/inputs/xmpp.rb +81 -0
  178. data/lib/logstash/inputs/zenoss.rb +143 -0
  179. data/lib/logstash/inputs/zeromq.rb +165 -0
  180. data/lib/logstash/kibana.rb +113 -0
  181. data/lib/logstash/loadlibs.rb +9 -0
  182. data/lib/logstash/logging.rb +89 -0
  183. data/lib/logstash/monkeypatches-for-bugs.rb +2 -0
  184. data/lib/logstash/monkeypatches-for-debugging.rb +47 -0
  185. data/lib/logstash/monkeypatches-for-performance.rb +66 -0
  186. data/lib/logstash/multiqueue.rb +53 -0
  187. data/lib/logstash/namespace.rb +16 -0
  188. data/lib/logstash/outputs/base.rb +120 -0
  189. data/lib/logstash/outputs/boundary.rb +116 -0
  190. data/lib/logstash/outputs/circonus.rb +78 -0
  191. data/lib/logstash/outputs/cloudwatch.rb +351 -0
  192. data/lib/logstash/outputs/csv.rb +55 -0
  193. data/lib/logstash/outputs/datadog.rb +93 -0
  194. data/lib/logstash/outputs/datadog_metrics.rb +123 -0
  195. data/lib/logstash/outputs/elasticsearch.rb +332 -0
  196. data/lib/logstash/outputs/elasticsearch/elasticsearch-template.json +44 -0
  197. data/lib/logstash/outputs/elasticsearch_http.rb +256 -0
  198. data/lib/logstash/outputs/elasticsearch_river.rb +214 -0
  199. data/lib/logstash/outputs/email.rb +299 -0
  200. data/lib/logstash/outputs/exec.rb +40 -0
  201. data/lib/logstash/outputs/file.rb +180 -0
  202. data/lib/logstash/outputs/ganglia.rb +75 -0
  203. data/lib/logstash/outputs/gelf.rb +208 -0
  204. data/lib/logstash/outputs/gemfire.rb +103 -0
  205. data/lib/logstash/outputs/google_bigquery.rb +570 -0
  206. data/lib/logstash/outputs/google_cloud_storage.rb +431 -0
  207. data/lib/logstash/outputs/graphite.rb +143 -0
  208. data/lib/logstash/outputs/graphtastic.rb +185 -0
  209. data/lib/logstash/outputs/hipchat.rb +80 -0
  210. data/lib/logstash/outputs/http.rb +142 -0
  211. data/lib/logstash/outputs/irc.rb +80 -0
  212. data/lib/logstash/outputs/jira.rb +109 -0
  213. data/lib/logstash/outputs/juggernaut.rb +105 -0
  214. data/lib/logstash/outputs/librato.rb +146 -0
  215. data/lib/logstash/outputs/loggly.rb +93 -0
  216. data/lib/logstash/outputs/lumberjack.rb +51 -0
  217. data/lib/logstash/outputs/metriccatcher.rb +103 -0
  218. data/lib/logstash/outputs/mongodb.rb +81 -0
  219. data/lib/logstash/outputs/nagios.rb +119 -0
  220. data/lib/logstash/outputs/nagios_nsca.rb +123 -0
  221. data/lib/logstash/outputs/null.rb +18 -0
  222. data/lib/logstash/outputs/opentsdb.rb +101 -0
  223. data/lib/logstash/outputs/pagerduty.rb +79 -0
  224. data/lib/logstash/outputs/pipe.rb +132 -0
  225. data/lib/logstash/outputs/rabbitmq.rb +96 -0
  226. data/lib/logstash/outputs/rabbitmq/bunny.rb +135 -0
  227. data/lib/logstash/outputs/rabbitmq/hot_bunnies.rb +1 -0
  228. data/lib/logstash/outputs/rabbitmq/march_hare.rb +143 -0
  229. data/lib/logstash/outputs/redis.rb +245 -0
  230. data/lib/logstash/outputs/riak.rb +152 -0
  231. data/lib/logstash/outputs/riemann.rb +109 -0
  232. data/lib/logstash/outputs/s3.rb +356 -0
  233. data/lib/logstash/outputs/sns.rb +124 -0
  234. data/lib/logstash/outputs/solr_http.rb +78 -0
  235. data/lib/logstash/outputs/sqs.rb +141 -0
  236. data/lib/logstash/outputs/statsd.rb +116 -0
  237. data/lib/logstash/outputs/stdout.rb +53 -0
  238. data/lib/logstash/outputs/stomp.rb +67 -0
  239. data/lib/logstash/outputs/syslog.rb +145 -0
  240. data/lib/logstash/outputs/tcp.rb +145 -0
  241. data/lib/logstash/outputs/udp.rb +38 -0
  242. data/lib/logstash/outputs/websocket.rb +46 -0
  243. data/lib/logstash/outputs/websocket/app.rb +29 -0
  244. data/lib/logstash/outputs/websocket/pubsub.rb +45 -0
  245. data/lib/logstash/outputs/xmpp.rb +78 -0
  246. data/lib/logstash/outputs/zabbix.rb +108 -0
  247. data/lib/logstash/outputs/zeromq.rb +125 -0
  248. data/lib/logstash/pipeline.rb +286 -0
  249. data/lib/logstash/plugin.rb +150 -0
  250. data/lib/logstash/plugin_mixins/aws_config.rb +93 -0
  251. data/lib/logstash/program.rb +15 -0
  252. data/lib/logstash/runner.rb +238 -0
  253. data/lib/logstash/sized_queue.rb +8 -0
  254. data/lib/logstash/test.rb +183 -0
  255. data/lib/logstash/threadwatchdog.rb +37 -0
  256. data/lib/logstash/time_addon.rb +33 -0
  257. data/lib/logstash/util.rb +106 -0
  258. data/lib/logstash/util/buftok.rb +139 -0
  259. data/lib/logstash/util/charset.rb +39 -0
  260. data/lib/logstash/util/fieldreference.rb +50 -0
  261. data/lib/logstash/util/password.rb +25 -0
  262. data/lib/logstash/util/prctl.rb +11 -0
  263. data/lib/logstash/util/relp.rb +326 -0
  264. data/lib/logstash/util/require-helper.rb +18 -0
  265. data/lib/logstash/util/socket_peer.rb +7 -0
  266. data/lib/logstash/util/zenoss.rb +566 -0
  267. data/lib/logstash/util/zeromq.rb +47 -0
  268. data/lib/logstash/version.rb +6 -0
  269. data/locales/en.yml +170 -0
  270. data/logstash-event.gemspec +29 -0
  271. data/logstash.gemspec +128 -0
  272. data/patterns/firewalls +60 -0
  273. data/patterns/grok-patterns +91 -0
  274. data/patterns/haproxy +37 -0
  275. data/patterns/java +3 -0
  276. data/patterns/linux-syslog +14 -0
  277. data/patterns/mcollective +1 -0
  278. data/patterns/mcollective-patterns +4 -0
  279. data/patterns/nagios +108 -0
  280. data/patterns/postgresql +3 -0
  281. data/patterns/redis +3 -0
  282. data/patterns/ruby +2 -0
  283. data/pkg/build.sh +135 -0
  284. data/pkg/centos/after-install.sh +1 -0
  285. data/pkg/centos/before-install.sh +10 -0
  286. data/pkg/centos/before-remove.sh +11 -0
  287. data/pkg/centos/sysconfig +15 -0
  288. data/pkg/debian/after-install.sh +5 -0
  289. data/pkg/debian/before-install.sh +13 -0
  290. data/pkg/debian/before-remove.sh +13 -0
  291. data/pkg/debian/build.sh +34 -0
  292. data/pkg/debian/debian/README +6 -0
  293. data/pkg/debian/debian/changelog +17 -0
  294. data/pkg/debian/debian/compat +1 -0
  295. data/pkg/debian/debian/control +16 -0
  296. data/pkg/debian/debian/copyright +27 -0
  297. data/pkg/debian/debian/dirs +19 -0
  298. data/pkg/debian/debian/docs +0 -0
  299. data/pkg/debian/debian/logstash.default +39 -0
  300. data/pkg/debian/debian/logstash.init +201 -0
  301. data/pkg/debian/debian/logstash.install +1 -0
  302. data/pkg/debian/debian/logstash.logrotate +9 -0
  303. data/pkg/debian/debian/logstash.postinst +68 -0
  304. data/pkg/debian/debian/logstash.postrm +23 -0
  305. data/pkg/debian/debian/manpage.1.ex +59 -0
  306. data/pkg/debian/debian/preinst.ex +37 -0
  307. data/pkg/debian/debian/prerm.ex +40 -0
  308. data/pkg/debian/debian/release.conf +5 -0
  309. data/pkg/debian/debian/rules +80 -0
  310. data/pkg/debian/debian/watch.ex +22 -0
  311. data/pkg/logrotate.conf +8 -0
  312. data/pkg/logstash-web.default +41 -0
  313. data/pkg/logstash-web.sysv.debian +201 -0
  314. data/pkg/logstash-web.upstart.ubuntu +18 -0
  315. data/pkg/logstash.default +45 -0
  316. data/pkg/logstash.sysv.debian +202 -0
  317. data/pkg/logstash.sysv.redhat +158 -0
  318. data/pkg/logstash.upstart.ubuntu +20 -0
  319. data/pkg/rpm/SOURCES/logstash.conf +26 -0
  320. data/pkg/rpm/SOURCES/logstash.init +80 -0
  321. data/pkg/rpm/SOURCES/logstash.logrotate +8 -0
  322. data/pkg/rpm/SOURCES/logstash.sysconfig +3 -0
  323. data/pkg/rpm/SOURCES/logstash.wrapper +105 -0
  324. data/pkg/rpm/SPECS/logstash.spec +180 -0
  325. data/pkg/rpm/readme.md +4 -0
  326. data/pkg/ubuntu/after-install.sh +7 -0
  327. data/pkg/ubuntu/before-install.sh +12 -0
  328. data/pkg/ubuntu/before-remove.sh +13 -0
  329. data/pull_release_note.rb +25 -0
  330. data/require-analyze.rb +22 -0
  331. data/spec/README.md +14 -0
  332. data/spec/codecs/edn.rb +40 -0
  333. data/spec/codecs/edn_lines.rb +53 -0
  334. data/spec/codecs/graphite.rb +96 -0
  335. data/spec/codecs/json.rb +57 -0
  336. data/spec/codecs/json_lines.rb +51 -0
  337. data/spec/codecs/json_spooler.rb +43 -0
  338. data/spec/codecs/msgpack.rb +39 -0
  339. data/spec/codecs/multiline.rb +60 -0
  340. data/spec/codecs/oldlogstashjson.rb +55 -0
  341. data/spec/codecs/plain.rb +35 -0
  342. data/spec/codecs/spool.rb +35 -0
  343. data/spec/conditionals/test.rb +323 -0
  344. data/spec/config.rb +31 -0
  345. data/spec/event.rb +165 -0
  346. data/spec/examples/fail2ban.rb +28 -0
  347. data/spec/examples/graphite-input.rb +41 -0
  348. data/spec/examples/mysql-slow-query.rb +70 -0
  349. data/spec/examples/parse-apache-logs.rb +66 -0
  350. data/spec/examples/parse-haproxy-logs.rb +115 -0
  351. data/spec/examples/syslog.rb +48 -0
  352. data/spec/filters/alter.rb +96 -0
  353. data/spec/filters/anonymize.rb +189 -0
  354. data/spec/filters/checksum.rb +41 -0
  355. data/spec/filters/clone.rb +67 -0
  356. data/spec/filters/collate.rb +122 -0
  357. data/spec/filters/csv.rb +174 -0
  358. data/spec/filters/date.rb +285 -0
  359. data/spec/filters/date_performance.rb +31 -0
  360. data/spec/filters/dns.rb +159 -0
  361. data/spec/filters/drop.rb +19 -0
  362. data/spec/filters/elapsed.rb +294 -0
  363. data/spec/filters/environment.rb +43 -0
  364. data/spec/filters/geoip.rb +62 -0
  365. data/spec/filters/grep.rb +342 -0
  366. data/spec/filters/grok.rb +473 -0
  367. data/spec/filters/grok/timeout2.rb +56 -0
  368. data/spec/filters/grok/timeouts.rb +39 -0
  369. data/spec/filters/i18n.rb +25 -0
  370. data/spec/filters/json.rb +72 -0
  371. data/spec/filters/json_encode.rb +37 -0
  372. data/spec/filters/kv.rb +403 -0
  373. data/spec/filters/metrics.rb +212 -0
  374. data/spec/filters/multiline.rb +119 -0
  375. data/spec/filters/mutate.rb +180 -0
  376. data/spec/filters/noop.rb +221 -0
  377. data/spec/filters/prune.rb +441 -0
  378. data/spec/filters/punct.rb +18 -0
  379. data/spec/filters/railsparallelrequest.rb +112 -0
  380. data/spec/filters/range.rb +169 -0
  381. data/spec/filters/split.rb +58 -0
  382. data/spec/filters/translate.rb +70 -0
  383. data/spec/filters/unique.rb +25 -0
  384. data/spec/filters/useragent.rb +42 -0
  385. data/spec/filters/xml.rb +157 -0
  386. data/spec/inputs/file.rb +107 -0
  387. data/spec/inputs/gelf.rb +52 -0
  388. data/spec/inputs/generator.rb +30 -0
  389. data/spec/inputs/imap.rb +60 -0
  390. data/spec/inputs/redis.rb +63 -0
  391. data/spec/inputs/relp.rb +70 -0
  392. data/spec/inputs/tcp.rb +101 -0
  393. data/spec/jar.rb +21 -0
  394. data/spec/outputs/csv.rb +266 -0
  395. data/spec/outputs/elasticsearch.rb +161 -0
  396. data/spec/outputs/elasticsearch_http.rb +240 -0
  397. data/spec/outputs/email.rb +173 -0
  398. data/spec/outputs/file.rb +82 -0
  399. data/spec/outputs/graphite.rb +236 -0
  400. data/spec/outputs/redis.rb +127 -0
  401. data/spec/speed.rb +20 -0
  402. data/spec/sqlite-test.rb +81 -0
  403. data/spec/support/LOGSTASH-733.rb +21 -0
  404. data/spec/support/LOGSTASH-820.rb +25 -0
  405. data/spec/support/akamai-grok.rb +26 -0
  406. data/spec/support/date-http.rb +17 -0
  407. data/spec/support/postwait1.rb +26 -0
  408. data/spec/support/pull375.rb +21 -0
  409. data/spec/test_utils.rb +125 -0
  410. data/spec/util/fieldeval_spec.rb +44 -0
  411. data/test/jenkins/config.xml.erb +74 -0
  412. data/test/jenkins/create-jobs.rb +23 -0
  413. data/test/jenkins/generatorjob.config.xml +66 -0
  414. data/tools/Gemfile +14 -0
  415. data/tools/Gemfile.jruby-1.9.lock +322 -0
  416. data/tools/Gemfile.rbx-2.1.lock +516 -0
  417. data/tools/Gemfile.ruby-1.9.1.lock +310 -0
  418. data/tools/Gemfile.ruby-2.0.0.lock +310 -0
  419. 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