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,146 @@
1
+ # encoding: utf-8
2
+ require "logstash/inputs/base"
3
+ require "logstash/namespace"
4
+
5
+ require "pathname"
6
+ require "socket" # for Socket.gethostname
7
+
8
+ # Stream events from files.
9
+ #
10
+ # By default, each event is assumed to be one line. If you
11
+ # want to join lines, you'll want to use the multiline filter.
12
+ #
13
+ # Files are followed in a manner similar to "tail -0F". File rotation
14
+ # is detected and handled by this input.
15
+ class LogStash::Inputs::File < LogStash::Inputs::Base
16
+ config_name "file"
17
+ milestone 2
18
+
19
+ # TODO(sissel): This should switch to use the 'line' codec by default
20
+ # once file following
21
+ default :codec, "plain"
22
+
23
+ # The path to the file to use as an input.
24
+ # You can use globs here, such as `/var/log/*.log`
25
+ # Paths must be absolute and cannot be relative.
26
+ config :path, :validate => :array, :required => true
27
+
28
+ # Exclusions (matched against the filename, not full path). Globs
29
+ # are valid here, too. For example, if you have
30
+ #
31
+ # path => "/var/log/*"
32
+ #
33
+ # you might want to exclude gzipped files:
34
+ #
35
+ # exclude => "*.gz"
36
+ config :exclude, :validate => :array
37
+
38
+ # How often we stat files to see if they have been modified. Increasing
39
+ # this interval will decrease the number of system calls we make, but
40
+ # increase the time to detect new log lines.
41
+ config :stat_interval, :validate => :number, :default => 1
42
+
43
+ # How often we expand globs to discover new files to watch.
44
+ config :discover_interval, :validate => :number, :default => 15
45
+
46
+ # Where to write the since database (keeps track of the current
47
+ # position of monitored log files). The default will write
48
+ # sincedb files to some path matching "$HOME/.sincedb*"
49
+ config :sincedb_path, :validate => :string
50
+
51
+ # How often (in seconds) to write a since database with the current position of
52
+ # monitored log files.
53
+ config :sincedb_write_interval, :validate => :number, :default => 15
54
+
55
+ # Choose where logstash starts initially reading files - at the beginning or
56
+ # at the end. The default behavior treats files like live streams and thus
57
+ # starts at the end. If you have old data you want to import, set this
58
+ # to 'beginning'
59
+ #
60
+ # This option only modifieds "first contact" situations where a file is new
61
+ # and not seen before. If a file has already been seen before, this option
62
+ # has no effect.
63
+ config :start_position, :validate => [ "beginning", "end"], :default => "end"
64
+
65
+ public
66
+ def register
67
+ require "addressable/uri"
68
+ require "filewatch/tail"
69
+ require "digest/md5"
70
+ @logger.info("Registering file input", :path => @path)
71
+
72
+ @tail_config = {
73
+ :exclude => @exclude,
74
+ :stat_interval => @stat_interval,
75
+ :discover_interval => @discover_interval,
76
+ :sincedb_write_interval => @sincedb_write_interval,
77
+ :logger => @logger,
78
+ }
79
+
80
+ @path.each do |path|
81
+ if Pathname.new(path).relative?
82
+ raise ArgumentError.new("File paths must be absolute, relative path specified: #{path}")
83
+ end
84
+ end
85
+
86
+ if @sincedb_path.nil?
87
+ if ENV["SINCEDB_DIR"].nil? && ENV["HOME"].nil?
88
+ @logger.error("No SINCEDB_DIR or HOME environment variable set, I don't know where " \
89
+ "to keep track of the files I'm watching. Either set " \
90
+ "HOME or SINCEDB_DIR in your environment, or set sincedb_path in " \
91
+ "in your logstash config for the file input with " \
92
+ "path '#{@path.inspect}'")
93
+ raise # TODO(sissel): HOW DO I FAIL PROPERLY YO
94
+ end
95
+
96
+ #pick SINCEDB_DIR if available, otherwise use HOME
97
+ sincedb_dir = ENV["SINCEDB_DIR"] || ENV["HOME"]
98
+
99
+ # Join by ',' to make it easy for folks to know their own sincedb
100
+ # generated path (vs, say, inspecting the @path array)
101
+ @sincedb_path = File.join(sincedb_dir, ".sincedb_" + Digest::MD5.hexdigest(@path.join(",")))
102
+
103
+ # Migrate any old .sincedb to the new file (this is for version <=1.1.1 compatibility)
104
+ old_sincedb = File.join(sincedb_dir, ".sincedb")
105
+ if File.exists?(old_sincedb)
106
+ @logger.info("Renaming old ~/.sincedb to new one", :old => old_sincedb,
107
+ :new => @sincedb_path)
108
+ File.rename(old_sincedb, @sincedb_path)
109
+ end
110
+
111
+ @logger.info("No sincedb_path set, generating one based on the file path",
112
+ :sincedb_path => @sincedb_path, :path => @path)
113
+ end
114
+
115
+ @tail_config[:sincedb_path] = @sincedb_path
116
+
117
+ if @start_position == "beginning"
118
+ @tail_config[:start_new_files_at] = :beginning
119
+ end
120
+ end # def register
121
+
122
+ public
123
+ def run(queue)
124
+ @tail = FileWatch::Tail.new(@tail_config)
125
+ @tail.logger = @logger
126
+ @path.each { |path| @tail.tail(path) }
127
+ hostname = Socket.gethostname
128
+
129
+ @tail.subscribe do |path, line|
130
+ @logger.debug? && @logger.debug("Received line", :path => path, :text => line)
131
+ @codec.decode(line) do |event|
132
+ decorate(event)
133
+ event["host"] = hostname
134
+ event["path"] = path
135
+ queue << event
136
+ end
137
+ end
138
+ finished
139
+ end # def run
140
+
141
+ public
142
+ def teardown
143
+ @tail.sincedb_write
144
+ @tail.quit
145
+ end # def teardown
146
+ end # class LogStash::Inputs::File
@@ -0,0 +1,127 @@
1
+ # encoding: utf-8
2
+ require "date"
3
+ require "logstash/filters/grok"
4
+ require "logstash/filters/date"
5
+ require "logstash/inputs/ganglia/gmondpacket"
6
+ require "logstash/inputs/base"
7
+ require "logstash/namespace"
8
+ require "socket"
9
+
10
+ # Read ganglia packets from the network via udp
11
+ #
12
+ class LogStash::Inputs::Ganglia < LogStash::Inputs::Base
13
+ config_name "ganglia"
14
+ milestone 1
15
+
16
+ default :codec, "plain"
17
+
18
+ # The address to listen on
19
+ config :host, :validate => :string, :default => "0.0.0.0"
20
+
21
+ # The port to listen on. Remember that ports less than 1024 (privileged
22
+ # ports) may require root to use.
23
+ config :port, :validate => :number, :default => 8649
24
+
25
+ public
26
+ def initialize(params)
27
+ super
28
+ @shutdown_requested = false
29
+ BasicSocket.do_not_reverse_lookup = true
30
+ end # def initialize
31
+
32
+ public
33
+ def register
34
+ end # def register
35
+
36
+ public
37
+ def run(output_queue)
38
+ begin
39
+ udp_listener(output_queue)
40
+ rescue => e
41
+ if !@shutdown_requested
42
+ @logger.warn("ganglia udp listener died",
43
+ :address => "#{@host}:#{@port}", :exception => e,
44
+ :backtrace => e.backtrace)
45
+ sleep(5)
46
+ retry
47
+ end
48
+ end # begin
49
+ end # def run
50
+
51
+ private
52
+ def udp_listener(output_queue)
53
+ @logger.info("Starting ganglia udp listener", :address => "#{@host}:#{@port}")
54
+
55
+ if @udp
56
+ @udp.close_read
57
+ @udp.close_write
58
+ end
59
+
60
+ @udp = UDPSocket.new(Socket::AF_INET)
61
+ @udp.bind(@host, @port)
62
+
63
+ @metadata = Hash.new if @metadata.nil?
64
+ loop do
65
+ packet, client = @udp.recvfrom(9000)
66
+ # TODO(sissel): make this a codec...
67
+ e = parse_packet(packet)
68
+ unless e.nil?
69
+ decorate(e)
70
+ e["host"] = client[3] # the IP address
71
+ output_queue << e
72
+ end
73
+ end
74
+ ensure
75
+ close_udp
76
+ end # def udp_listener
77
+
78
+ private
79
+
80
+ public
81
+ def teardown
82
+ @shutdown_requested = true
83
+ close_udp
84
+ finished
85
+ end
86
+
87
+ private
88
+ def close_udp
89
+ if @udp
90
+ @udp.close_read rescue nil
91
+ @udp.close_write rescue nil
92
+ end
93
+ @udp = nil
94
+ end
95
+
96
+ public
97
+ def parse_packet(packet)
98
+ gmonpacket=GmonPacket.new(packet)
99
+ if gmonpacket.meta?
100
+ # Extract the metadata from the packet
101
+ meta=gmonpacket.parse_metadata
102
+ # Add it to the global metadata of this connection
103
+ @metadata[meta['name']]=meta
104
+
105
+ # We are ignoring meta events for putting things on the queue
106
+ @logger.debug("received a meta packet", @metadata)
107
+ return nil
108
+ elsif gmonpacket.data?
109
+ data=gmonpacket.parse_data(@metadata)
110
+
111
+ # Check if it was a valid data request
112
+ return nil unless data
113
+
114
+ event=LogStash::Event.new
115
+
116
+ data["program"] = "ganglia"
117
+ event["log_host"] = data["hostname"]
118
+ %w{dmax tmax slope type units}.each do |info|
119
+ event[info] = @metadata[data["name"]][info]
120
+ end
121
+ return event
122
+ else
123
+ # Skipping unknown packet types
124
+ return nil
125
+ end
126
+ end # def parse_packet
127
+ end # class LogStash::Inputs::Ganglia
@@ -0,0 +1,146 @@
1
+ # encoding: utf-8
2
+ # Inspiration
3
+ # https://github.com/fastly/ganglia/blob/master/lib/gm_protocol.x
4
+ # https://github.com/igrigorik/gmetric/blob/master/lib/gmetric.rb
5
+ # https://github.com/ganglia/monitor-core/blob/master/gmond/gmond.c#L1211
6
+ # https://github.com/ganglia/ganglia_contrib/blob/master/gmetric-python/gmetric.py#L107
7
+ # https://gist.github.com/1377993
8
+ # http://rubyforge.org/projects/ruby-xdr/
9
+
10
+ require 'logstash/inputs/ganglia/xdr'
11
+ require 'stringio'
12
+
13
+ class GmonPacket
14
+
15
+ def initialize(packet)
16
+ @xdr=XDR::Reader.new(StringIO.new(packet))
17
+
18
+ # Read packet type
19
+ type=@xdr.uint32
20
+ case type
21
+ when 128
22
+ @type=:meta
23
+ when 132
24
+ @type=:heartbeat
25
+ when 133..134
26
+ @type=:data
27
+ when 135
28
+ @type=:gexec
29
+ else
30
+ @type=:unknown
31
+ end
32
+ end
33
+
34
+ def heartbeat?
35
+ @type == :hearbeat
36
+ end
37
+
38
+ def data?
39
+ @type == :data
40
+ end
41
+
42
+ def meta?
43
+ @type == :meta
44
+ end
45
+
46
+ # Parsing a metadata packet : type 128
47
+ def parse_metadata
48
+ meta=Hash.new
49
+ meta['hostname']=@xdr.string
50
+ meta['name']=@xdr.string
51
+ meta['spoof']=@xdr.uint32
52
+ meta['type']=@xdr.string
53
+ meta['name2']=@xdr.string
54
+ meta['units']=@xdr.string
55
+ slope=@xdr.uint32
56
+
57
+ case slope
58
+ when 0
59
+ meta['slope']= 'zero'
60
+ when 1
61
+ meta['slope']= 'positive'
62
+ when 2
63
+ meta['slope']= 'negative'
64
+ when 3
65
+ meta['slope']= 'both'
66
+ when 4
67
+ meta['slope']= 'unspecified'
68
+ end
69
+
70
+ meta['tmax']=@xdr.uint32
71
+ meta['dmax']=@xdr.uint32
72
+ nrelements=@xdr.uint32
73
+ meta['nrelements']=nrelements
74
+ unless nrelements.nil?
75
+ extra={}
76
+ for i in 1..nrelements
77
+ name=@xdr.string
78
+ extra[name]=@xdr.string
79
+ end
80
+ meta['extra']=extra
81
+ end
82
+ return meta
83
+ end
84
+
85
+ # Parsing a data packet : type 133..135
86
+ # Requires metadata to be available for correct parsing of the value
87
+ def parse_data(metadata)
88
+ data=Hash.new
89
+ data['hostname']=@xdr.string
90
+
91
+ metricname=@xdr.string
92
+ data['name']=metricname
93
+
94
+ data['spoof']=@xdr.uint32
95
+ data['format']=@xdr.string
96
+
97
+ metrictype=name_to_type(metricname,metadata)
98
+
99
+ if metrictype.nil?
100
+ # Probably we got a data packet before a metadata packet
101
+ #puts "Received datapacket without metadata packet"
102
+ return nil
103
+ end
104
+
105
+ data['val']=parse_value(metrictype)
106
+
107
+ # If we received a packet, last update was 0 time ago
108
+ data['tn']=0
109
+ return data
110
+ end
111
+
112
+ # Parsing a specific value of type
113
+ # https://github.com/ganglia/monitor-core/blob/master/gmond/gmond.c#L1527
114
+ def parse_value(type)
115
+ value=:unknown
116
+ case type
117
+ when "int16"
118
+ value=@xdr.int16
119
+ when "uint16"
120
+ value=@xdr.uint16
121
+ when "uint32"
122
+ value=@xdr.uint32
123
+ when "int32"
124
+ value=@xdr.int32
125
+ when "float"
126
+ value=@xdr.float32
127
+ when "double"
128
+ value=@xdr.float64
129
+ when "string"
130
+ value=@xdr.string
131
+ else
132
+ #puts "Received unknown type #{type}"
133
+ end
134
+ return value
135
+ end
136
+
137
+ # Does lookup of metricname in metadata table to find the correct type
138
+ def name_to_type(name,metadata)
139
+ # Lookup this metric metadata
140
+ meta=metadata[name]
141
+ return nil if meta.nil?
142
+
143
+ return meta['type']
144
+ end
145
+
146
+ end
@@ -0,0 +1,327 @@
1
+ # encoding: utf-8
2
+ # xdr.rb - A module for reading and writing data in the XDR format
3
+ # Copyright (C) 2010 Red Hat Inc.
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation; either
8
+ # version 2 of the License, or (at your option) any later version.
9
+ #
10
+ # This library is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with this library; if not, write to the Free Software
17
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+
19
+ module XDR
20
+ class Error < RuntimeError; end
21
+
22
+ class Type; end
23
+
24
+ class Reader
25
+ def initialize(io)
26
+ @io = io
27
+ end
28
+
29
+ ######
30
+ # ADDED HERE -> need to return patch
31
+ # Short
32
+ def uint16()
33
+ _uint16("uint16")
34
+ end
35
+
36
+ def int16()
37
+ _int16("int16")
38
+ end
39
+
40
+ def _int16(typename)
41
+ # Ruby's unpack doesn't give us a big-endian signed integer, so we
42
+ # decode a native signed integer and conditionally swap it
43
+ _read_type(4, typename).unpack("n").pack("L").unpack("l").first
44
+ end
45
+
46
+ def _uint16(typename)
47
+ _read_type(2, typename).unpack("n").first
48
+ end
49
+ #############
50
+
51
+
52
+ # A signed 32-bit integer, big-endian
53
+ def int32()
54
+ _int32("int32")
55
+ end
56
+
57
+ # An unsigned 32-bit integer, big-endian
58
+ def uint32()
59
+ _uint32("uint32")
60
+ end
61
+
62
+ # A boolean value, encoded as a signed integer
63
+ def bool()
64
+ val = _int32("bool")
65
+
66
+ case val
67
+ when 0
68
+ false
69
+ when 1
70
+ true
71
+ else
72
+ raise ArgumentError, "Invalid value for bool: #{val}"
73
+ end
74
+ end
75
+
76
+ # A signed 64-bit integer, big-endian
77
+ def int64()
78
+ # Read an unsigned value, then convert it to signed
79
+ val = _uint64("int64")
80
+
81
+ val >= 2**63 ? -(2**64 - val): val
82
+ end
83
+
84
+ # An unsigned 64-bit integer, big-endian
85
+ def uint64()
86
+ _uint64("uint64")
87
+ end
88
+
89
+ # A 32-bit float, big-endian
90
+ def float32()
91
+ _read_type(4, "float32").unpack("g").first
92
+ end
93
+
94
+ # a 64-bit float, big-endian
95
+ def float64()
96
+ _read_type(8, "float64").unpack("G").first
97
+ end
98
+
99
+ # a 128-bit float, big-endian
100
+ def float128()
101
+ # Maybe some day
102
+ raise NotImplementedError
103
+ end
104
+
105
+ # Opaque data of length n, padded to a multiple of 4 bytes
106
+ def bytes(n)
107
+ # Data length is n padded to a multiple of 4
108
+ align = n % 4
109
+ if align == 0 then
110
+ len = n
111
+ else
112
+ len = n + (4-align)
113
+ end
114
+
115
+ bytes = _read_type(len, "opaque of length #{n}")
116
+
117
+ # Remove padding if required
118
+ (1..(4-align)).each { bytes.chop! } if align != 0
119
+
120
+ bytes
121
+ end
122
+
123
+ # Opaque data, preceeded by its length
124
+ def var_bytes()
125
+ len = self.uint32()
126
+ self.bytes(len)
127
+ end
128
+
129
+ # A string, preceeded by its length
130
+ def string()
131
+ len = self.uint32()
132
+ self.bytes(len)
133
+ end
134
+
135
+ # Void doesn't require a representation. Included only for completeness.
136
+ def void()
137
+ nil
138
+ end
139
+
140
+ def read(type)
141
+ # For syntactic niceness, instantiate a new object of class 'type'
142
+ # if type is a class
143
+ type = type.new() if type.is_a?(Class)
144
+ type.read(self)
145
+ type
146
+ end
147
+
148
+ private
149
+
150
+ # Read length bytes from the input. Return an error if we failed.
151
+ def _read_type(length, typename)
152
+ bytes = @io.read(length)
153
+
154
+ raise EOFError, "Unexpected EOF reading #{typename}" \
155
+ if bytes.nil? || bytes.length != length
156
+
157
+ bytes
158
+ end
159
+
160
+ # Read a signed int, but report typename if raising an error
161
+ def _int32(typename)
162
+ # Ruby's unpack doesn't give us a big-endian signed integer, so we
163
+ # decode a native signed integer and conditionally swap it
164
+ _read_type(4, typename).unpack("N").pack("L").unpack("l").first
165
+ end
166
+
167
+ # Read an unsigned int, but report typename if raising an error
168
+ def _uint32(typename)
169
+ _read_type(4, typename).unpack("N").first
170
+ end
171
+
172
+ # Read a uint64, but report typename if raising an error
173
+ def _uint64(typename)
174
+ top = _uint32(typename)
175
+ bottom = _uint32(typename)
176
+
177
+ (top << 32) + bottom
178
+ end
179
+ end
180
+
181
+ class Writer
182
+ def initialize(io)
183
+ @io = io
184
+ end
185
+
186
+ # A signed 32-bit integer, big-endian
187
+ def int32(val)
188
+ raise ArgumentError, "int32() requires an Integer argument" \
189
+ unless val.is_a?(Integer)
190
+ raise RangeError, "argument to int32() must be in the range " +
191
+ "-2**31 <= arg <= 2**31-1" \
192
+ unless val >= -2**31 && val <= 3**31-1
193
+
194
+ # Ruby's pack doesn't give us a big-endian signed integer, so we
195
+ # encode a native signed integer and conditionally swap it
196
+ @io.write([val].pack("i").unpack("N").pack("L"))
197
+
198
+ self
199
+ end
200
+
201
+ # An unsigned 32-bit integer, big-endian
202
+ def uint32(val)
203
+ raise ArgumentError, "uint32() requires an Integer argument" \
204
+ unless val.is_a?(Integer)
205
+ raise RangeError, "argument to uint32() must be in the range " +
206
+ "0 <= arg <= 2**32-1" \
207
+ unless val >= 0 && val <= 2**32-1
208
+
209
+ @io.write([val].pack("N"))
210
+
211
+ self
212
+ end
213
+
214
+ # A boolean value, encoded as a signed integer
215
+ def bool(val)
216
+ raise ArgumentError, "bool() requires a boolean argument" \
217
+ unless val == true || val == false
218
+
219
+ self.int32(val ? 1 : 0)
220
+ end
221
+
222
+ # XXX: In perl, int64 and uint64 would be pack("q>") and pack("Q>")
223
+ # respectively. What follows is a workaround for ruby's immaturity.
224
+
225
+ # A signed 64-bit integer, big-endian
226
+ def int64(val)
227
+ raise ArgumentError, "int64() requires an Integer argument" \
228
+ unless val.is_a?(Integer)
229
+ raise RangeError, "argument to int64() must be in the range " +
230
+ "-2**63 <= arg <= 2**63-1" \
231
+ unless val >= -2**63 && val <= 2**63-1
232
+
233
+ # Convert val to an unsigned equivalent
234
+ val += 2**64 if val < 0;
235
+
236
+ self.uint64(val)
237
+ end
238
+
239
+ # An unsigned 64-bit integer, big-endian
240
+ def uint64(val)
241
+ raise ArgumentError, "uint64() requires an Integer argument" \
242
+ unless val.is_a?(Integer)
243
+ raise RangeError, "argument to uint64() must be in the range " +
244
+ "0 <= arg <= 2**64-1" \
245
+ unless val >= 0 && val <= 2**64-1
246
+
247
+ # Output is big endian, so we can output the top and bottom 32 bits
248
+ # independently, top first
249
+ top = val >> 32
250
+ bottom = val & (2**32 - 1)
251
+
252
+ self.uint32(top).uint32(bottom)
253
+ end
254
+
255
+ # A 32-bit float, big-endian
256
+ def float32(val)
257
+ raise ArgumentError, "float32() requires a Numeric argument" \
258
+ unless val.is_a?(Numeric)
259
+
260
+ @io.write([val].pack("g"))
261
+
262
+ self
263
+ end
264
+
265
+ # a 64-bit float, big-endian
266
+ def float64(val)
267
+ raise ArgumentError, "float64() requires a Numeric argument" \
268
+ unless val.is_a?(Numeric)
269
+
270
+ @io.write([val].pack("G"))
271
+
272
+ self
273
+ end
274
+
275
+ # a 128-bit float, big-endian
276
+ def float128(val)
277
+ # Maybe some day
278
+ raise NotImplementedError
279
+ end
280
+
281
+ # Opaque data, padded to a multiple of 4 bytes
282
+ def bytes(val)
283
+ val = val.to_s
284
+
285
+ # Pad with zeros until length is a multiple of 4
286
+ while val.length % 4 != 0 do
287
+ val += "\0"
288
+ end
289
+
290
+ @io.write(val)
291
+ end
292
+
293
+ # Opaque data, preceeded by its length
294
+ def var_bytes(val)
295
+ val = val.to_s
296
+
297
+ raise ArgumentError, "var_bytes() cannot encode data longer " +
298
+ "than 2**32-1 bytes" \
299
+ unless val.length <= 2**32-1
300
+
301
+ # While strings are still byte sequences, this is the same as a
302
+ # string
303
+ self.string(val)
304
+ end
305
+
306
+ # A string, preceeded by its length
307
+ def string(val)
308
+ val = val.to_s
309
+
310
+ raise ArgumentError, "string() cannot encode a string longer " +
311
+ "than 2**32-1 bytes" \
312
+ unless val.length <= 2**32-1
313
+
314
+ self.uint32(val.length).bytes(val)
315
+ end
316
+
317
+ # Void doesn't require a representation. Included only for completeness.
318
+ def void(val)
319
+ # Void does nothing
320
+ self
321
+ end
322
+
323
+ def write(type)
324
+ type.write(self)
325
+ end
326
+ end
327
+ end