├── .foodcritic ├── .gitignore ├── .kitchen.yml ├── .rubocop.yml ├── .ruby-version ├── .travis.yml ├── Berksfile ├── CHANGELOG.md ├── CONTRIBUTORS ├── Gemfile ├── Guardfile ├── LICENSE ├── README.md ├── Rakefile ├── Strainerfile ├── attributes ├── default.rb └── source.rb ├── chefignore ├── files └── default │ └── haproxy ├── libraries ├── logstash_conf.rb ├── logstash_util.rb └── matchers.rb ├── metadata.rb ├── providers ├── config.rb ├── curator.rb ├── instance.rb ├── pattern.rb ├── plugins.rb └── service.rb ├── recipes ├── agent.rb ├── beaver.rb ├── default.rb ├── install.rb ├── server.rb ├── source.rb └── test.rb ├── resources ├── config.rb ├── curator.rb ├── instance.rb ├── pattern.rb ├── plugins.rb └── service.rb ├── templates └── default │ ├── config │ ├── filter_apache.conf.erb │ ├── input_file.conf.erb │ ├── input_syslog.conf.erb │ ├── output_elasticsearch.conf.erb │ ├── output_elasticsearch_http.conf.erb │ └── output_stdout.conf.erb │ ├── init │ ├── systemd │ │ └── tarball.erb │ ├── sysvinit │ │ └── tarball.erb │ └── upstart │ │ └── tarball.erb │ ├── patterns │ └── custom_patterns.erb │ ├── server.conf.erb │ ├── sv-logstash-log-run.erb │ ├── sv-logstash-run.erb │ ├── sv-logstash_web-log-run.erb │ └── sv-logstash_web-run.erb └── test ├── fixtures └── cookbooks │ └── logstash-test │ ├── attributes │ └── default.rb │ ├── metadata.rb │ └── recipes │ └── default.rb ├── integration ├── helpers │ └── serverspec │ │ └── spec_helper.rb └── server │ └── serverspec │ └── server_spec.rb └── unit └── spec ├── agent_spec.rb ├── default_spec.rb ├── haproxy_spec.rb ├── lwrp_config_spec.rb ├── lwrp_pattern_spec.rb ├── pyshipper_spec.rb ├── server_spec.rb ├── source_spec.rb ├── spec_helper.rb ├── support └── matchers.rb └── util_spec.rb /.foodcritic: -------------------------------------------------------------------------------- 1 | ~FC059 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | metadata.json 2 | .vagrant 3 | Berksfile.lock 4 | vendor/ 5 | .kitchen/ 6 | .kitchen.local.yml 7 | .bundle/ 8 | bin/ 9 | Gemfile.lock 10 | -------------------------------------------------------------------------------- /.kitchen.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: vagrant 4 | driver_config: 5 | require_chef_omnibus: 13.1 6 | customize: 7 | memory: 512 8 | cpus: 1 9 | 10 | provisioner: 11 | name: chef_zero 12 | attributes: 13 | java: 14 | jdk_version: "8" 15 | install_flavor: "oracle" 16 | oracle: 17 | accept_oracle_download_terms: true 18 | logstash: 19 | instance: 20 | server: 21 | elasticsearch_ip: '127.0.0.1' 22 | config_templates_variables: 23 | bind_host: '127.0.0.1' 24 | es_protocol: 'http' 25 | init_method: 'native' 26 | xms: '256M' 27 | xmx: '256M' 28 | logrotate_use_filesize: true 29 | logrotate_max_size: '25MB' 30 | config_templates: 31 | input_syslog: 'config/input_syslog.conf.erb' 32 | output_stdout: 'config/output_stdout.conf.erb' 33 | output_elasticsearch: 'config/output_elasticsearch.conf.erb' 34 | pattern_templates: 35 | default: 'patterns/custom_patterns.erb' 36 | 37 | platforms: 38 | - name: ubuntu-14.04 39 | run_list: 40 | - recipe[apt::default] 41 | - recipe[java::default] 42 | - name: ubuntu-16.04 43 | run_list: 44 | - recipe[apt::default] 45 | - recipe[java::default] 46 | - name: centos-6.9 47 | run_list: 48 | - recipe[java::default] 49 | - name: centos-7.3 50 | run_list: 51 | - recipe[java::default] 52 | 53 | suites: 54 | - name: server 55 | run_list: 56 | - recipe[logstash-test::default] 57 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | Exclude: 3 | - 'vendor/**/*' 4 | - 'test/support/**' 5 | - 'bin/**/*' 6 | - 'test/**' 7 | Include: 8 | - '**/Rakefile' 9 | - '**/Gemfile' 10 | - '**/Vagrantfile' 11 | - '**/Berksfile' 12 | 13 | Style/FrozenStringLiteralComment: 14 | Enabled: false 15 | 16 | CyclomaticComplexity: 17 | Enabled: false 18 | 19 | Lint/IneffectiveAccessModifier: 20 | Enabled: false 21 | 22 | Lint/UnifiedInteger: 23 | Enabled: false 24 | 25 | Lint/UselessAccessModifier: 26 | Enabled: false 27 | 28 | LineLength: 29 | Enabled: true 30 | Max: 210 31 | 32 | MethodLength: 33 | Enabled: true 34 | 35 | Metrics/BlockLength: 36 | Enabled: false 37 | 38 | AccessorMethodName: 39 | Enabled: false 40 | 41 | ClassAndModuleChildren: 42 | Enabled: false 43 | 44 | UselessAssignment: 45 | Enabled: false 46 | 47 | BlockNesting: 48 | Max: 4 49 | 50 | Documentation: 51 | Enabled: false 52 | 53 | MethodLength: 54 | Max: 50 55 | 56 | Style/WordArray: 57 | MinSize: 5 58 | 59 | Style/RedundantBegin: 60 | Enabled: false 61 | 62 | # Offense count: 2 63 | # Cop supports --auto-correct. 64 | Style/NumericLiterals: 65 | MinDigits: 6 66 | 67 | # Offense count: 9 68 | Metrics/AbcSize: 69 | Max: 78 70 | 71 | # Offense count: 8 72 | Metrics/PerceivedComplexity: 73 | Max: 25 74 | 75 | Metrics/AbcSize: 76 | Max: 100 77 | 78 | Style/NestedModifier: 79 | Enabled: false 80 | 81 | Style/ConditionalAssignment: 82 | Enabled: false 83 | 84 | Style/IdenticalConditionalBranches: 85 | Enabled: false 86 | 87 | Style/IfUnlessModifierOfIfUnless: 88 | Enabled: false 89 | 90 | Style/MutableConstant: 91 | Enabled: false 92 | 93 | Style/NumericLiteralPrefix: 94 | Enabled: false 95 | 96 | Style/RedundantParentheses: 97 | Enabled: false 98 | 99 | Style/SpaceAroundOperators: 100 | Enabled: false 101 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.3.1 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.3.1 4 | env: 5 | - USE_SYSTEM_GECODE=1 6 | addons: 7 | apt: 8 | packages: 9 | - libgecode-dev 10 | install: 11 | - bundle install --path vendor --binstubs 12 | script: 13 | - bin/berks install 14 | - bin/rake style spec 15 | sudo: false 16 | -------------------------------------------------------------------------------- /Berksfile: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | 3 | source 'https://api.berkshelf.com' if Gem::Version.new(Berkshelf::VERSION) > Gem::Version.new('3') 4 | 5 | metadata 6 | 7 | group :integration do 8 | cookbook 'apt' 9 | cookbook 'java' 10 | cookbook 'beaver' 11 | cookbook 'logstash-test', path: 'test/fixtures/cookbooks/logstash-test' 12 | end 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG for chef-logstash 2 | 3 | ## 1.0.1 4 | 5 | * MINOR - Removed chef/mixin/language references to support Chef 14 6 | * MINOR - Pinned version for 'cucumber-core' and 'gherkin' in Gemfile 7 | * MINOR - Update Ubuntu version in specs 8 | 9 | ## 1.0.0 10 | 11 | * MAJOR - Get tests passing on Chef 12.7 12 | * MAJOR - Use a versioned directory structure 13 | * MAJOR - Use systemd for Debian 8 (Jessie) 14 | * MINOR - Add Max Heap to systemd init parameters 15 | * MINOR - Add udp listening port 514 16 | * MINOR - Remove Vagrant support 17 | 18 | ## 0.12.0 19 | * MAJOR - logstash version 1.5.4 20 | * MINOR - systemd improvements 21 | * MINOR - implement join_groups attribute 22 | 23 | ## 0.11.2 24 | * MINOR - default logstash version 1.4.2 25 | * MINOR - correct status code for initv scripts 26 | * MINOR - parameterize open file limits for upstart method 27 | * MINOR - late night bad resource in server recipe. 28 | 29 | ## 0.11.0 30 | * MAJOR - depreciate non runit service types. 31 | * MINOR - fix bug where node['logstash'][instance_name] must exist. 32 | * MAJOR - remove pyshipper in favor of beaver community cookbook. 33 | * MAJOR - remove beaver in favor of community cookbook. 34 | * MAJOR - assumes ChefDK for Development/Testing 35 | * MAJOR - use keys from config_template hash to make templates reusable. 36 | 37 | ## 0.10.0: 38 | * major rework of service LWRP 39 | * rework of attribute precidence 40 | * node[logstash][default] changed to node[logstash][instance_default] 41 | 42 | This file is used to list changes made in each version of chef-logstash. 43 | 44 | 45 | ## 0.9.2: 46 | * update to fix PAX header issue on community site 47 | 48 | ## 0.9.1: 49 | 50 | * curator LWRP 51 | 52 | ## 0.9.0: 53 | 54 | _this will almost certainly break backwards compatibility_ 55 | 56 | * support for Logstash 1.4 57 | * major refactor towards being a library cookbook 58 | * instance LWRP 59 | * service LWRP 60 | * pattern LWP 61 | * config LWP 62 | 63 | ## 0.7.7: 64 | 65 | * Support for new beaver config [#239](https://github.com/lusis/chef-logstash/pull/239) 66 | * Support for multiline codec [#240](https://github.com/lusis/chef-logstash/pull/240) 67 | * Parameterize /var/lib/logstash [#242](https://github.com/lusis/chef-logstash/pull/242) 68 | * Fix parameter spacing option [#244](https://github.com/lusis/chef-logstash/pull/244) 69 | 70 | ## 0.7.6: 71 | 72 | * introduced more testing 73 | * Strainer: rubocop, knife test, foodcritic, chefspec 74 | * lots of style fixes for rubocop 75 | * skeleton spec files for each recipe 76 | * testkitchen + server spec 77 | 78 | ## 0.7.5: 79 | 80 | * added fedora systemd support 81 | * moved zeromq repos to own recipe 82 | 83 | ## 0.7.4: 84 | * bump logstash version to 1.3.2 85 | 86 | ## 0.7.3: 87 | * support for sudo with upstart for agent and server 88 | 89 | ## 0.7.2: 90 | * embedded kibana support 91 | 92 | ## 0.7.1: 93 | * various bugfixes 94 | * support for multiple logstash workers via attribute. 95 | 96 | ## 0.7.0: 97 | 98 | ### New features ### 99 | * settable gid when using runit or upstart as supervisor 100 | * default logstash version 1.2.2 101 | * attributes to specify: config_dir, home, config_file for both agent and server. 102 | * don't install rabbit by default 103 | * allow for conditionals to be set in the filters and outputs hashes. 104 | * allow for disabling data driven templates. 105 | * attributes to enable regular(ish) style chef templates. 106 | 107 | ### Bug fixes ### 108 | * Vagrantfile cleanup, support more OS 109 | * Cookbook Dependency cleanup 110 | 111 | ## 0.2.1 (June 26, 2012) 112 | 113 | New features 114 | * Use ruby hashes supplied by roles to populate inputs, filters, 115 | and outputs 116 | * redhat-family support 117 | * change default version of logstash to 1.1.1preview 118 | * add in Travis-CI support 119 | 120 | Bug fixes 121 | * keep apache default site from obscuring kibana 122 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | Bryan Berry (@bryanwb) 2 | Juanje Ojeda (@juanje) 3 | Richard Clamp (@richardc) 4 | Hector Castro (@hectcastro) 5 | @benattar 6 | ChrisLundquist (@ChrisLundquist) 7 | Phil Sturgeon (@philsturgeon) 8 | Jeremy Voorhis (@jvoorhis) 9 | Tim Meighen (@tmeighen) 10 | Anthony Goddard (@agoddard) 11 | Jeff Hubbard (@lord2800) 12 | Bernhard Köhler (@drywheat) 13 | Luis Bosque (@lbosque) 14 | Chris Mague (@maguec) 15 | Chris Geer (@geerzo) 16 | Tim Hunter (@thorrsson) 17 | Paul Czarkowski (@paulczar) 18 | Bill Ruddock (@biinari) 19 | Nick Padilla (@NickPadilla) 20 | Roman Gorodeckij (@holms) 21 | Dmitriy Budnik (@budnik) 22 | @Pneumatus 23 | Martin Smith (@martinb3) 24 | Stanisław Tuszyński (@stuszynski) 25 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | group :lint do 4 | gem 'cookstyle', '~> 1.3' 5 | gem 'foodcritic', '~> 10.3' 6 | gem 'rubocop', '~> 0.47' 7 | end 8 | 9 | group :unit do 10 | gem 'berkshelf', '~> 6.1' 11 | gem 'chef', '~> 13.1' 12 | gem 'chef-sugar' 13 | gem 'chefspec' 14 | end 15 | 16 | group :kitchen_common do 17 | gem 'test-kitchen', '~> 1.16' 18 | end 19 | 20 | group :kitchen_vagrant do 21 | gem 'kitchen-vagrant', '~> 1.1' 22 | gem 'vagrant-wrapper' 23 | end 24 | 25 | gem 'cucumber-core', '3.2.0' 26 | gem 'gherkin', '5.1.0' 27 | gem 'rake' 28 | gem 'serverspec' 29 | -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | # A sample Guardfile 2 | # More info at https://github.com/guard/guard#readme 3 | 4 | guard :rubocop do 5 | watch(%r{.+\.rb$}) 6 | watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) } 7 | end 8 | 9 | guard "foodcritic" do 10 | watch(%r{attributes/.+\.rb$}) 11 | watch(%r{providers/.+\.rb$}) 12 | watch(%r{recipes/.+\.rb$}) 13 | watch(%r{resources/.+\.rb$}) 14 | end 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This software is licensed under the Apache 2 license, quoted below. 2 | 3 | Copyright (c) 2015 Elasticsearch 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # chef-logstash [![Build Status](https://secure.travis-ci.org/lusis/chef-logstash.png?branch=master)](http://travis-ci.org/lusis/chef-logstash) 2 | 3 | Description 4 | =========== 5 | 6 | This is the semi-official 'all-in-one' Logstash cookbook. 7 | 8 | This cookbook is primarily a library cookbook. 9 | 10 | While you can still use the `agent` and `server` recipes, they are not recommended as they are very limited in what they do. 11 | 12 | If you are using logstash < 1.2 you might want to use the 0.6.x branch. 13 | If you are using logstash < 1.4 you might want to use the 0.7.x branch. 14 | 15 | Requirements 16 | ============ 17 | 18 | All of the requirements are explicitly defined in the recipes. Every 19 | effort has been made to utilize Community Cookbooks. 20 | 21 | However if you wish to use an external ElasticSearch cluster, you will 22 | need to install that yourself and change the relevant attributes for 23 | discovery. The same applies to integration with Graphite. 24 | 25 | This cookbook has been tested together with the following cookbooks, 26 | see the Berksfile for more details 27 | 28 | * [Heavywater Graphite Cookbook](https://github.com/hw-cookbooks/graphite) - This is the one I use 29 | * [Karmi's ElasticSearch Cookbook](https://github.com/elasticsearch/cookbook-elasticsearch) 30 | * [@lusis Kibana cookbook](https://github.com/lusis/chef-kibana) 31 | * [Community Beaver cookbook](https://supermarket.getchef.com/cookbooks/beaver) 32 | * [elkstack community cookbook](https://supermarket.getchef.com/cookbooks/elkstack) 33 | 34 | Attributes 35 | ========== 36 | 37 | ## Default 38 | 39 | see [attributes/default.rb](attributes/default.rb) 40 | 41 | ## Beaver (alternative to Logstash Agent) 42 | 43 | no longer used. see [Community Beaver cookbook](https://supermarket.getchef.com/cookbooks/beaver) 44 | 45 | ## Source 46 | 47 | no longer supports installing from source. 48 | 49 | Lightweight Resource Providers 50 | =================== 51 | 52 | These now do all the heavy lifting. 53 | 54 | ## logstash_instance 55 | 56 | This will install a logstash instance. It will take defaults from attributes for most attributes. 57 | 58 | see [resources/instance.rb](resources/instance.rb) 59 | 60 | ## logstash_service 61 | 62 | This will create system init scripts for managing logstash instance. It will take defaults from attributes for most attributes. 63 | 64 | see [resources/service.rb](resources/service.rb) 65 | 66 | _experimental support for pleaserun has been added. Only `native` for `Ubuntu 12.04` has been thoroughly tested._ 67 | 68 | ## logstash_config 69 | 70 | This will create logstash config files. It will take defaults from attributes for most attributes. 71 | 72 | see [resources/config.rb](resources/config.rb) 73 | 74 | ## logstash_pattern 75 | 76 | This will install custom grok patterns for logstash. It will take defaults from attributes for most attributes: 77 | 78 | see [resources/pattern.rb](resources/pattern.rb) 79 | 80 | ## logstash_plugins 81 | 82 | This will install the logstash community plugins: 83 | 84 | see [resources/plugins.rb](resources/plugins.rb) 85 | 86 | ## logstash_curator 87 | 88 | This will install the [ElasticSearch Curator](https://github.com/elasticsearch/curator) and setup a cron job. This replaces the deprecated `index_cleaner`: 89 | 90 | see [resources/curator.rb](resources/curator.rb) 91 | 92 | ## attribute precidence in logstash LWRPs 93 | 94 | We've done our best to make this intuitive and easy to use. 95 | 96 | 1. the value directly in the resource block. 97 | 2. the value from the hash node['logstash']['instance'][name] 98 | 3. the value from the hash node['logstash']['instance_default'] 99 | 100 | You should be able to override settings in any of the above places. It is recommended for readability that you set non-default options in the LWRP resource block. But do whichever makes sense to you. 101 | 102 | Searching 103 | ====== 104 | 105 | There is a search helper library `libraries/search.rb` which will help you search for values such as `elasticsearch_ip`. see the `server` recipe for an example of its usage. 106 | 107 | 108 | Testing 109 | ======= 110 | 111 | ## Rubocop, FoodCritic, Rspec, Test-Kitchen 112 | 113 | ``` 114 | $ bundle exec rake 115 | ``` 116 | 117 | ## Test Kitchen 118 | 119 | ``` 120 | $ kitchen converge server_ubuntu 121 | ``` 122 | 123 | Contributing 124 | ======== 125 | 126 | Any and all contributions are welcome. We do ask that you test your contributions with the testing framework before you send a PR. All contributions should be made against the master branch. 127 | 128 | Please update tests and changelist with your contributions. 129 | 130 | Documentation contributions will earn you lots of hugs and kisses. 131 | 132 | Usage 133 | ===== 134 | 135 | A proper readme is forthcoming but in the interim.... 136 | 137 | These two recipes show how to install and configure logstash instances via the provided `LWRPs` 138 | 139 | * [recipes/server.rb](recipes/server.rb) - This would be your indexer node 140 | * [recipes/agent.rb](recipes/agent.rb) - This would be a local host's agent for collection 141 | 142 | See the [elkstack community cookbook](https://supermarket.getchef.com/cookbooks/elkstack) for a great example of using the LWRPs provided by this cookbook. 143 | 144 | ## License and Author 145 | 146 | - Author: John E. Vincent 147 | - Author: Bryan W. Berry () 148 | - Author: Richard Clamp (@richardc) 149 | - Author: Juanje Ojeda (@juanje) 150 | - Author: @benattar 151 | - Author: Paul Czarkowski (@pczarkowski) 152 | - Copyright: 2012, John E. Vincent 153 | - Copyright: 2012, Bryan W. Berry 154 | - Copyright: 2012, Richard Clamp 155 | - Copyright: 2012, Juanje Ojeda 156 | - Copyright: 2012, @benattar 157 | - Copyright: 2014, Paul Czarkowski 158 | 159 | Licensed under the Apache License, Version 2.0 (the "License"); 160 | you may not use this file except in compliance with the License. 161 | You may obtain a copy of the License at 162 | 163 | http://www.apache.org/licenses/LICENSE-2.0 164 | 165 | Unless required by applicable law or agreed to in writing, software 166 | distributed under the License is distributed on an "AS IS" BASIS, 167 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 168 | See the License for the specific language governing permissions and 169 | limitations under the License. 170 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | require 'bundler/setup' 3 | 4 | namespace :style do 5 | require 'rubocop/rake_task' 6 | desc 'Run Ruby style checks' 7 | RuboCop::RakeTask.new(:ruby) 8 | 9 | require 'foodcritic' 10 | desc 'Run Chef style checks' 11 | FoodCritic::Rake::LintTask.new(:chef) do |t| 12 | t.options = { 13 | tags: %w( 14 | ~FC024 15 | ~FC059 16 | ) 17 | } 18 | end 19 | end 20 | 21 | desc 'Run all style checks' 22 | task style: ['style:chef', 'style:ruby'] 23 | 24 | require 'kitchen' 25 | desc 'Run Test Kitchen integration tests' 26 | task :integration do 27 | unless ENV['CI'] 28 | Kitchen.logger = Kitchen.default_file_logger 29 | Kitchen::Config.new.instances.each do |instance| 30 | instance.test(:always) 31 | end 32 | end 33 | end 34 | 35 | require 'rspec/core/rake_task' 36 | desc 'Run ChefSpec unit tests' 37 | RSpec::Core::RakeTask.new(:spec) do |t, _args| 38 | t.rspec_opts = 'test/unit' 39 | end 40 | 41 | # The default rake task should just run it all 42 | task default: %w(style spec integration) 43 | 44 | unless ENV['CI'] 45 | begin 46 | require 'kitchen/rake_tasks' 47 | Kitchen::RakeTasks.new 48 | rescue LoadError 49 | puts '>>>>> Kitchen gem not loaded, omitting tasks' unless ENV['CI'] 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /Strainerfile: -------------------------------------------------------------------------------- 1 | # Strainerfile 2 | rubocop: bundle exec rubocop -c $SANDBOX/$COOKBOOK/.rubocop.yml $SANDBOX/$COOKBOOK 3 | knife test: bundle exec knife cookbook test $COOKBOOK 4 | foodcritic: bundle exec foodcritic --epic-fail any $SANDBOX/$COOKBOOK 5 | chefspec: bundle exec rspec $SANDBOX/$COOKBOOK/test/unit/spec 6 | -------------------------------------------------------------------------------- /attributes/default.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | 3 | # roles/flags for various search/discovery 4 | default['logstash']['instance_default']['graphite_role'] = 'graphite_server' 5 | default['logstash']['instance_default']['graphite_query'] = "roles:#{node['logstash']['instance_default']['graphite_role']} AND chef_environment:#{node.chef_environment}" 6 | default['logstash']['instance_default']['elasticsearch_role'] = 'elasticsearch_server' 7 | default['logstash']['instance_default']['elasticsearch_query'] = "roles:#{node['logstash']['instance_default']['elasticsearch_role']} AND chef_environment:#{node.chef_environment}" 8 | default['logstash']['instance_default']['elasticsearch_cluster'] = 'logstash' 9 | default['logstash']['instance_default']['elasticsearch_ip'] = '' 10 | default['logstash']['instance_default']['elasticsearch_embedded'] = true 11 | 12 | # Default logstash instance variables 13 | default['logstash']['instance_default']['basedir'] = '/opt/logstash' 14 | default['logstash']['instance_default']['user'] = 'logstash' 15 | default['logstash']['instance_default']['group'] = 'logstash' 16 | default['logstash']['instance_default']['user_opts'] = { homedir: '/var/lib/logstash', uid: nil, gid: nil } 17 | default['logstash']['instance_default']['supervisor_gid'] = node['logstash']['instance_default']['group'] 18 | default['logstash']['instance_default']['pid_dir'] = '/var/run/logstash' 19 | default['logstash']['instance_default']['create_account'] = true 20 | default['logstash']['instance_default']['join_groups'] = [] 21 | default['logstash']['instance_default']['homedir'] = '/var/lib/logstash' 22 | 23 | default['logstash']['instance_default']['version'] = '1.5.4' 24 | default['logstash']['instance_default']['source_url'] = 'https://download.elasticsearch.org/logstash/logstash/logstash-1.5.4.tar.gz' 25 | default['logstash']['instance_default']['checksum'] = 'f03075ee534ce6e7667679447f56543ce05cebbdb7b65a9396a5e538bf3e9fa8' 26 | default['logstash']['instance_default']['install_type'] = 'tarball' 27 | 28 | default['logstash']['instance_default']['plugins_version'] = '1.4.5' 29 | default['logstash']['instance_default']['plugins_source_url'] = 'https://download.elasticsearch.org/logstash/logstash/logstash-contrib-1.4.5.tar.gz' 30 | default['logstash']['instance_default']['plugins_checksum'] = 'e4fa08cac70f97e30d4d043fcab817b72c301631713376c5c21824d5d89cae3e' 31 | default['logstash']['instance_default']['plugins_install_type'] = 'native' # native|tarball ( only native after 1.5 ) 32 | default['logstash']['instance_default']['plugins_check_if_installed'] = 'lib/logstash/filters/translate.rb' 33 | 34 | default['logstash']['instance_default']['log_file'] = 'logstash.log' 35 | default['logstash']['instance_default']['java_home'] = '/usr/lib/jvm/java-6-openjdk' # openjdk6 on ubuntu 36 | default['logstash']['instance_default']['java_opts'] = '' 37 | default['logstash']['instance_default']['xms'] = node['memory'] ? "#{(node['memory']['total'].to_i * 0.2).floor / 1024}M" : '256M' 38 | default['logstash']['instance_default']['xmx'] = node['memory'] ? "#{(node['memory']['total'].to_i * 0.6).floor / 1024}M" : '256M' 39 | default['logstash']['instance_default']['gc_opts'] = '-XX:+UseParallelOldGC' 40 | default['logstash']['instance_default']['ipv4_only'] = false 41 | default['logstash']['instance_default']['debug'] = false 42 | default['logstash']['instance_default']['pluginpath'] = true 43 | default['logstash']['instance_default']['workers'] = 1 44 | 45 | default['logstash']['instance_default']['pattern_templates_cookbook'] = 'logstash' 46 | default['logstash']['instance_default']['pattern_templates'] = {} 47 | default['logstash']['instance_default']['pattern_templates_variables'] = {} 48 | 49 | default['logstash']['instance_default']['base_config_cookbook'] = 'logstash' 50 | default['logstash']['instance_default']['base_config'] = '' # set if want data driven 51 | 52 | default['logstash']['instance_default']['config_file'] = '' 53 | default['logstash']['instance_default']['config_templates'] = {} 54 | default['logstash']['instance_default']['config_templates_cookbook'] = 'logstash' 55 | default['logstash']['instance_default']['config_templates_variables'] = {} 56 | 57 | default['logstash']['instance_default']['init_method'] = 'runit' 58 | default['logstash']['instance_default']['service_templates_cookbook'] = 'logstash' 59 | 60 | # default locations for runit templates 61 | default['logstash']['instance_default']['runit_run_template_name'] = 'logstash' 62 | default['logstash']['instance_default']['runit_log_template_name'] = 'logstash' 63 | 64 | default['logstash']['instance_default']['limit_nofile_soft'] = 65550 65 | default['logstash']['instance_default']['limit_nofile_hard'] = 65550 66 | 67 | # roles/flags for various autoconfig/discovery components 68 | default['logstash']['instance_default']['enable_embedded_es'] = false 69 | default['logstash']['instance_default']['bind_host_interface'] = '' 70 | default['logstash']['instance_default']['es_index'] = nil 71 | 72 | default['logstash']['instance_default']['inputs'] = [] 73 | default['logstash']['instance_default']['filters'] = [] 74 | default['logstash']['instance_default']['outputs'] = [] 75 | 76 | default['logstash']['instance_default']['web']['enable'] = false 77 | default['logstash']['instance_default']['web']['address'] = '0.0.0.0' 78 | default['logstash']['instance_default']['web']['port'] = '9292' 79 | 80 | # Logging features 81 | default['logstash']['instance_default']['logrotate_enable'] = true 82 | default['logstash']['instance_default']['logrotate_options'] = %w(missingok notifempty compress copytruncate) 83 | default['logstash']['instance_default']['logrotate_files'] = '*.log' 84 | default['logstash']['instance_default']['logrotate_frequency'] = 'daily' 85 | default['logstash']['instance_default']['logrotate_max_backup'] = 10 86 | default['logstash']['instance_default']['logrotate_size'] = '10M' 87 | default['logstash']['instance_default']['logrotate_max_size'] = '10M' 88 | default['logstash']['instance_default']['logrotate_use_filesize'] = false 89 | 90 | # Curator 91 | default['logstash']['instance_default']['curator_bin_dir'] = '/usr/local/bin' 92 | default['logstash']['instance_default']['curator_days_to_keep'] = '31' 93 | default['logstash']['instance_default']['curator_cron_minute'] = '0' 94 | default['logstash']['instance_default']['curator_cron_hour'] = '*' 95 | default['logstash']['instance_default']['curator_cron_log_file'] = '/dev/null' 96 | default['logstash']['instance_default']['curator_index_prefix'] = 'logstash-' 97 | default['logstash']['instance_default']['curator_time_unit'] = 'days' 98 | default['logstash']['instance_default']['curator_timestring'] = '\%Y.\%m.\%d' 99 | 100 | # Make sure instance key exists 101 | default['logstash']['instance'] 102 | -------------------------------------------------------------------------------- /attributes/source.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | default['logstash']['source']['repo'] = 'git://github.com/logstash/logstash.git' 3 | default['logstash']['source']['sha'] = nil 4 | default['logstash']['source']['java_home'] = '/usr/lib/jvm/java-6-openjdk/' # openjdk6 on ubuntu 5 | -------------------------------------------------------------------------------- /chefignore: -------------------------------------------------------------------------------- 1 | # OS generated files # 2 | ###################### 3 | .DS_Store 4 | Icon? 5 | nohup.out 6 | ehthumbs.db 7 | Thumbs.db 8 | 9 | # SASS # 10 | ######## 11 | .sass-cache 12 | 13 | # EDITORS # 14 | ########### 15 | \#* 16 | .#* 17 | *~ 18 | *.sw[a-z] 19 | *.bak 20 | REVISION 21 | TAGS* 22 | tmtags 23 | *_flymake.* 24 | *_flymake 25 | *.tmproj 26 | .project 27 | .settings 28 | mkmf.log 29 | 30 | ## COMPILED ## 31 | ############## 32 | a.out 33 | *.o 34 | *.pyc 35 | *.so 36 | *.com 37 | *.class 38 | *.dll 39 | *.exe 40 | */rdoc/ 41 | 42 | # Testing # 43 | ########### 44 | .watchr 45 | .rspec 46 | spec/* 47 | spec/fixtures/* 48 | test/* 49 | features/* 50 | Guardfile 51 | Procfile 52 | 53 | # SCM # 54 | ####### 55 | .git 56 | */.git 57 | .gitignore 58 | .gitmodules 59 | .gitconfig 60 | .gitattributes 61 | .svn 62 | */.bzr/* 63 | */.hg/* 64 | */.svn/* 65 | 66 | # Berkshelf # 67 | ############# 68 | Berksfile 69 | Berksfile.lock 70 | cookbooks/* 71 | tmp 72 | 73 | # Cookbooks # 74 | ############# 75 | CONTRIBUTING 76 | CHANGELOG* 77 | 78 | # Strainer # 79 | ############ 80 | Colanderfile 81 | Strainerfile 82 | .colander 83 | .strainer 84 | 85 | # Vagrant # 86 | ########### 87 | .vagrant 88 | Vagrantfile 89 | 90 | # Travis # 91 | ########## 92 | .travis.yml 93 | -------------------------------------------------------------------------------- /files/default/haproxy: -------------------------------------------------------------------------------- 1 | # a fixup for haproxy, should be merged into https://github.com/logstash/logstash/blob/master/patterns/haproxy 2 | HAPROXYCAPTUREDREQUESTHEADERS %{NOTSPACE:request_header_host}\|%{DATA:request_header_x_forwarded_for}\|%{DATA:request_header_accept_language}\|%{NOTSPACE:request_header_referer}\|%{DATA:request_header_user_agent} 3 | HAPROXYCAPTUREDRESPONSEHEADERS %{DATA:response_header_content_type}\|%{DATA:response_header_content_encoding}\|%{DATA:response_header_cache_control}\|%{DATA:response_header_last_modified} -------------------------------------------------------------------------------- /libraries/logstash_conf.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # rubocop:disable RedundantReturn 3 | require 'rubygems' 4 | 5 | # Evaluate objects for logstash config file. 6 | class Erubis::RubyEvaluator::LogstashConf 7 | def self.key_to_str(k) 8 | case k.class.to_s 9 | when 'String' 10 | return "'#{k}'" 11 | when 'Fixnum', 'Float' 12 | return k.to_s 13 | when 'Regex' 14 | return k.inspect 15 | end 16 | return k 17 | end 18 | 19 | def self.hash_to_str(h, indent = 0) 20 | result = [] 21 | h.each do |k, v| 22 | indent += 4 23 | result << indent(indent) + key_value_to_str(k, v, indent) 24 | indent -= 4 25 | end 26 | result.join("\n") 27 | end 28 | 29 | def self.value_to_str(v, indent = 0) 30 | case v 31 | when String, Symbol, Fixnum, Float 32 | "\"#{v}\"" 33 | when Array 34 | "[#{v.map { |e| value_to_str(e, indent) }.join(', ')}]" 35 | when Hash, Mash 36 | "{\n" + hash_to_str(v, indent) + "\n" + indent(indent) + '}' 37 | when TrueClass, FalseClass 38 | v.to_s 39 | else 40 | v.inspect 41 | end 42 | end 43 | 44 | def self.key_value_to_str(k, v, indent = 0) 45 | if v.nil? 46 | key_to_str(k) 47 | else 48 | # k.inspect + " => " + v.inspect 49 | key_to_str(k) + ' => ' + value_to_str(v, indent) 50 | end 51 | end 52 | 53 | def self.plugin_to_arr(plugin, patterns_dir_plugins = nil, patterns_dir = nil, indent = 0) # , type_to_condition) 54 | result = [] 55 | plugin.each do |name, hash| 56 | indent += 4 57 | result << indent(indent) + name.to_s + ' {' 58 | result << indent(indent) + key_value_to_str('patterns_dir', patterns_dir, indent) if patterns_dir_plugins.include?(name.to_s) && patterns_dir && !hash.key?('patterns_dir') 59 | hash.sort.each do |k, v| 60 | indent += 4 61 | result << indent(indent) + key_value_to_str(k, v, indent) 62 | indent -= 4 63 | end 64 | result << indent(indent) + '}' 65 | indent -= 4 66 | end 67 | return result.join("\n") 68 | end 69 | 70 | def self.section_to_str(section, version = nil, patterns_dir = nil, indent = 0) 71 | result = [] 72 | patterns_dir_plugins = ['grok'] 73 | patterns_dir_plugins << 'multiline' if Gem::Version.new(version) >= Gem::Version.new('1.1.2') unless version.nil? 74 | section.each do |segment| 75 | result << '' 76 | if segment.key?('condition') || segment.key?('block') 77 | indent += 4 78 | result << indent(indent) + segment['condition'] + ' {' if segment['condition'] 79 | result << plugin_to_arr(segment['block'], patterns_dir_plugins, patterns_dir, indent) 80 | result << indent(indent) + '}' if segment['condition'] 81 | indent -= 4 82 | else 83 | indent += 4 84 | result << plugin_to_arr(segment, patterns_dir_plugins, patterns_dir, indent) # , type_to_condition) 85 | indent -= 4 86 | end 87 | end 88 | return result.join("\n") 89 | end 90 | end 91 | 92 | def indent(i) 93 | res = '' 94 | i.times { res << ' ' } 95 | res 96 | end 97 | -------------------------------------------------------------------------------- /libraries/logstash_util.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | 3 | module Logstash 4 | def self.service_ip(node, instance = 'default', service = 'elasticsearch', interface = nil) 5 | if Chef::Config[:solo] 6 | service_ip = get_attribute_or_default(node, instance, "#{service}_ip") 7 | else 8 | results = [] 9 | service_query = get_attribute_or_default(node, instance, "#{service}_query") 10 | Chef::Search::Query.new.search(:node, service_query) { |o| results << o } 11 | if !results.empty? 12 | service_ip = get_ip_for_node(results[0], interface) 13 | else 14 | service_ip = get_attribute_or_default(node, instance, "#{service}_ip") 15 | end 16 | end 17 | end 18 | 19 | def self.get_ip_for_node(node, interface) 20 | if interface.nil? 21 | service_ip = node['ipaddress'] 22 | else 23 | service_ip = node['network']['interfaces'][interface]['addresses'].to_hash.find do |_, addr_info| 24 | addr_info['family'] == 'inet' 25 | end.first 26 | end 27 | end 28 | 29 | def self.get_attribute_or_default(node, instance_name, attribute_name) 30 | instance_attr = {} unless node['logstash']['instance'][instance_name] 31 | instance_attr = deep_fetch(node, 'logstash', 'instance', instance_name, attribute_name) 32 | default_attr = deep_fetch(node, 'logstash', 'instance_default', attribute_name) 33 | instance_attr || default_attr 34 | end 35 | 36 | def self.determine_native_init(node) 37 | platform_major_version = determine_platform_major_version(node) 38 | case node['platform'] 39 | when 'ubuntu' 40 | if platform_major_version >= 6.10 && platform_major_version < 16 41 | 'upstart' 42 | elsif platform_major_version >= 16.04 43 | 'systemd' 44 | else 45 | 'sysvinit' 46 | end 47 | when 'debian' 48 | if platform_major_version <= 7 49 | 'sysvinit' 50 | else 51 | 'systemd' 52 | end 53 | when 'redhat', 'centos', 'scientific' 54 | if platform_major_version <= 6 55 | 'sysvinit' 56 | else 57 | 'systemd' 58 | end 59 | when 'amazon' 60 | if platform_major_version < 2011.02 61 | 'sysvinit' 62 | else 63 | 'upstart' 64 | end 65 | when 'fedora' 66 | if platform_major_version < 15 67 | 'sysvinit' 68 | else 69 | 'systemd' 70 | end 71 | else 72 | Chef::Log.fatal("We cannot determine your distribution's native init system") 73 | end 74 | end 75 | 76 | def self.upstart_supports_user?(node) 77 | platform_major_version = determine_platform_major_version(node) 78 | case node['platform'] 79 | when 'ubuntu' 80 | if platform_major_version < 12.04 81 | false 82 | else 83 | true 84 | end 85 | when 'redhat', 'centos', 'scientific', 'amazon' 86 | false 87 | else 88 | Chef::Log.fatal("#{node['platform']} does not use upstart") 89 | end 90 | end 91 | 92 | def self.determine_platform_major_version(node) 93 | if node['platform'] == 'ubuntu' || node['platform'] == 'amazon' 94 | node['platform_version'].to_f 95 | else 96 | node['platform_version'].split('.').first.to_i 97 | end 98 | end 99 | 100 | private 101 | 102 | # Adapted from @sathvargo's chef-sugar project, as there's no way to install 103 | # a gem via libraries, and we didn't want to much up the recipes too much yet: 104 | # https://github.com/sethvargo/chef-sugar/blob/master/lib/chef/sugar/node.rb 105 | def self.deep_fetch(node, *keys) 106 | keys.map!(&:to_s) 107 | keys.reduce(node.attributes.to_hash) do |hash, key| 108 | hash[key] 109 | end 110 | rescue NoMethodError 111 | nil 112 | end 113 | end 114 | -------------------------------------------------------------------------------- /libraries/matchers.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # used by ChefSpec for LWRPs 3 | 4 | if defined?(ChefSpec) 5 | ChefSpec.define_matcher(:logstash_instance) 6 | ChefSpec.define_matcher(:logstash_config) 7 | ChefSpec.define_matcher(:logstash_pattern) 8 | ChefSpec.define_matcher(:logstash_plugins) 9 | ChefSpec.define_matcher(:logstash_service) 10 | ChefSpec.define_matcher(:logstash_curator) 11 | 12 | # LWRP - Instance 13 | def create_logstash_instance(name) 14 | ChefSpec::Matchers::ResourceMatcher.new(:logstash_instance, :create, name) 15 | end 16 | 17 | def delete_logstash_instance(name) 18 | ChefSpec::Matchers::ResourceMatcher.new(:logstash_instance, :delete, name) 19 | end 20 | 21 | # LWRP - Config 22 | def create_logstash_config(name) 23 | ChefSpec::Matchers::ResourceMatcher.new(:logstash_config, :create, name) 24 | end 25 | 26 | # LWRP - Pattern 27 | def create_logstash_pattern(name) 28 | ChefSpec::Matchers::ResourceMatcher.new(:logstash_pattern, :create, name) 29 | end 30 | 31 | # LWRP - Plugins 32 | def create_logstash_plugins(name) 33 | ChefSpec::Matchers::ResourceMatcher.new(:logstash_plugins, :create, name) 34 | end 35 | 36 | # LWRP - Service 37 | def enable_logstash_service(name) 38 | ChefSpec::Matchers::ResourceMatcher.new(:logstash_service, :enable, name) 39 | end 40 | 41 | def restart_logstash_service(name) 42 | ChefSpec::Matchers::ResourceMatcher.new(:logstash_service, :restart, name) 43 | end 44 | 45 | def start_logstash_service(name) 46 | ChefSpec::Matchers::ResourceMatcher.new(:logstash_service, :start, name) 47 | end 48 | 49 | def reload_logstash_service(name) 50 | ChefSpec::Matchers::ResourceMatcher.new(:logstash_service, :reload, name) 51 | end 52 | 53 | def stop_logstash_service(name) 54 | ChefSpec::Matchers::ResourceMatcher.new(:logstash_service, :stop, name) 55 | end 56 | 57 | def create_logstash_curator(name) 58 | ChefSpec::Matchers::ResourceMatcher.new(:logstash_curator, :create, name) 59 | end 60 | 61 | end 62 | -------------------------------------------------------------------------------- /metadata.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | name 'logstash' 3 | maintainer 'John E. Vincent' 4 | maintainer_email 'lusis.org+github.com@gmail.com' 5 | license 'Apache-2.0' 6 | description 'Installs/Configures logstash' 7 | long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) 8 | 9 | version '1.0.1' 10 | 11 | %w(ubuntu debian redhat centos scientific amazon fedora).each do |os| 12 | supports os 13 | end 14 | 15 | depends 'build-essential' 16 | depends 'runit' 17 | depends 'git' 18 | depends 'ant' 19 | depends 'logrotate' 20 | depends 'ark' 21 | depends 'poise-python' 22 | depends 'curl' 23 | depends 'beaver' 24 | 25 | chef_version '>= 13.0' if respond_to?(:chef_version) 26 | issues_url 'https://github.com/lusis/chef-logstash/issues' 27 | source_url 'https://github.com/lusis/chef-logstash' 28 | -------------------------------------------------------------------------------- /providers/config.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # Cookbook Name:: logstash 3 | # Provider:: config 4 | # Author:: John E. Vincent 5 | # License:: Apache 2.0 6 | # 7 | # Copyright 2014, John E. Vincent 8 | 9 | def load_current_resource 10 | @instance = new_resource.instance 11 | @basedir = Logstash.get_attribute_or_default(node, @instance, 'basedir') 12 | @templates = new_resource.templates || Logstash.get_attribute_or_default(node, @instance, 'config_templates') 13 | @templates_cookbook = new_resource.templates_cookbook || Logstash.get_attribute_or_default(node, @instance, 'config_templates_cookbook') 14 | 15 | # merge user overrides into defaults for configuration variables 16 | attributes = Logstash.get_attribute_or_default(node, @instance, 'config_templates_variables') 17 | defaults = node['logstash']['instance_default']['config_templates_variables'] 18 | @variables = ({}).merge(new_resource.variables || {}).merge(defaults || {}).merge(attributes || {}) 19 | 20 | @owner = new_resource.owner || Logstash.get_attribute_or_default(node, @instance, 'user') 21 | @group = new_resource.group || Logstash.get_attribute_or_default(node, @instance, 'group') 22 | @mode = new_resource.mode || '0644' 23 | @path = new_resource.path || "#{@basedir}/#{@instance}/etc/conf.d" 24 | @service_name = new_resource.service_name || @instance 25 | end 26 | 27 | use_inline_resources 28 | 29 | action :create do 30 | conf = conf_vars 31 | # Chef::Log.info("config vars: #{conf.inspect}") 32 | conf[:templates].each do |template, file| 33 | tp = template "#{conf[:path]}/#{::File.basename(template).chomp(::File.extname(template))}" do 34 | source file 35 | cookbook conf[:templates_cookbook] 36 | owner conf[:owner] 37 | group conf[:group] 38 | mode conf[:mode] 39 | variables conf[:variables] 40 | action :create 41 | end 42 | new_resource.updated_by_last_action(tp.updated_by_last_action?) 43 | end 44 | end 45 | 46 | private 47 | 48 | def conf_vars 49 | conf = { 50 | instance: @instance, 51 | templates: @templates, 52 | variables: @variables, 53 | path: @path, 54 | owner: @owner, 55 | group: @group, 56 | mode: @mode, 57 | service_name: @service_name, 58 | templates_cookbook: @templates_cookbook 59 | } 60 | conf 61 | end 62 | -------------------------------------------------------------------------------- /providers/curator.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # Cookbook Name:: logstash 3 | # Provider:: curator 4 | # Author:: John E. Vincent 5 | # License:: Apache 2.0 6 | # 7 | # Copyright 2014, John E. Vincent 8 | 9 | def load_current_resource 10 | @instance = new_resource.instance || 'default' 11 | @days_to_keep = new_resource.days_to_keep || Logstash.get_attribute_or_default(node, @instance, 'curator_days_to_keep') 12 | @minute = new_resource.minute || Logstash.get_attribute_or_default(node, @instance, 'curator_cron_minute') 13 | @hour = new_resource.hour || Logstash.get_attribute_or_default(node, @instance, 'curator_cron_hour') 14 | @log_file = new_resource.log_file || Logstash.get_attribute_or_default(node, @instance, 'curator_cron_log_file') 15 | @user = new_resource.user || Logstash.get_attribute_or_default(node, @instance, 'user') 16 | @bin_dir = new_resource.bin_dir || Logstash.get_attribute_or_default(node, @instance, 'curator_bin_dir') 17 | @index_prefix = new_resource.index_prefix || Logstash.get_attribute_or_default(node, @instance, 'curator_index_prefix') 18 | @time_unit = new_resource.time_unit || Logstash.get_attribute_or_default(node, @instance, 'curator_time_unit') 19 | @timestring = new_resource.timestring || Logstash.get_attribute_or_default(node, @instance, 'curator_timestring') 20 | end 21 | 22 | action :create do 23 | cur_instance = @instance 24 | cur_days_to_keep = @days_to_keep 25 | cur_log_file = @log_file 26 | cur_hour = @hour 27 | cur_minute = @minute 28 | cur_user = @user 29 | cur_bin_dir = @bin_dir 30 | cur_index_prefix = @index_prefix 31 | cur_time_unit = @time_unit 32 | cur_timestring = @timestring 33 | 34 | pr = python_runtime '2' do 35 | action :install 36 | end 37 | new_resource.updated_by_last_action(pr.updated_by_last_action?) 38 | 39 | pp = python_package 'elasticsearch-curator' do 40 | action :install 41 | end 42 | new_resource.updated_by_last_action(pp.updated_by_last_action?) 43 | 44 | server_ip = ::Logstash.service_ip(node, cur_instance, 'elasticsearch') 45 | curator_args = "--host #{server_ip} delete indices --older-than #{cur_days_to_keep} --time-unit #{cur_time_unit} --timestring '#{cur_timestring}' --prefix #{cur_index_prefix} &> #{cur_log_file}" 46 | cr = cron "curator-#{cur_instance}" do 47 | command "#{cur_bin_dir}/curator #{curator_args}" 48 | user cur_user 49 | minute cur_minute 50 | hour cur_hour 51 | action [:create] 52 | end 53 | new_resource.updated_by_last_action(cr.updated_by_last_action?) 54 | end 55 | 56 | action :delete do 57 | cur_instance = @instance 58 | cur_days_to_keep = @days_to_keep 59 | cur_log_file = @log_file 60 | cur_hour = @hour 61 | cur_minute = @minute 62 | cur_user = @user 63 | cur_bin_dir = @bin_dir 64 | cur_index_prefix = @index_prefix 65 | 66 | pr = python_runtime '2' do 67 | action :install 68 | end 69 | new_resource.updated_by_last_action(pr.updated_by_last_action?) 70 | 71 | pp = python_package 'elasticsearch-curator' do 72 | action :uninstall 73 | end 74 | new_resource.updated_by_last_action(pp.updated_by_last_action?) 75 | 76 | host = ::Logstash.service_ip(node, cur_instance, 'elasticsearch') 77 | curator_args = "--host #{host} delete indices --older-than #{cur_days_to_keep} --time-unit #{cur_time_unit} --timestring '#{cur_timestring}' --prefix #{cur_index_prefix} 2>&1 > #{cur_log_file}" 78 | cr = cron "curator-#{cur_instance}" do 79 | command "#{cur_bin_dir}/curator #{curator_args}" 80 | user cur_user 81 | minute cur_minute 82 | hour cur_hour 83 | action [:delete] 84 | end 85 | new_resource.updated_by_last_action(cr.updated_by_last_action?) 86 | end 87 | -------------------------------------------------------------------------------- /providers/instance.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # Cookbook Name:: logstash 3 | # Provider:: instance 4 | # Author:: John E. Vincent 5 | # License:: Apache 2.0 6 | # 7 | # Copyright 2014, John E. Vincent 8 | 9 | require 'pathname' 10 | 11 | def load_current_resource 12 | @name = new_resource.name || 'default' 13 | @base_directory = new_resource.base_directory || Logstash.get_attribute_or_default(node, @name, 'basedir') 14 | @install_type = new_resource.install_type || Logstash.get_attribute_or_default(node, @name, 'install_type') 15 | @version = new_resource.version || Logstash.get_attribute_or_default(node, @name, 'version') 16 | @checksum = new_resource.checksum || Logstash.get_attribute_or_default(node, @name, 'checksum') 17 | @source_url = new_resource.source_url || Logstash.get_attribute_or_default(node, @name, 'source_url') 18 | @repo = new_resource.repo 19 | @sha = new_resource.sha 20 | @java_home = new_resource.java_home || Logstash.get_attribute_or_default(node, @name, 'java_home') 21 | @create_account = new_resource.create_account || Logstash.get_attribute_or_default(node, @name, 'create_account') 22 | @user = new_resource.user || Logstash.get_attribute_or_default(node, @name, 'user') 23 | @group = new_resource.group || Logstash.get_attribute_or_default(node, @name, 'group') 24 | @join_groups = new_resource.join_groups || Logstash.get_attribute_or_default(node, @name, 'join_groups') 25 | @useropts = new_resource.user_opts || Logstash.get_attribute_or_default(node, @name, 'user_opts') 26 | @instance_dir = "#{@base_directory}/#{@version}/#{new_resource.name}".clone 27 | @unversioned_instance_dir = "#{@base_directory}/#{new_resource.name}".clone 28 | @logrotate_size = new_resource.logrotate_size || Logstash.get_attribute_or_default(node, @name, 'logrotate_max_size') 29 | @logrotate_size = new_resource.user_opts || Logstash.get_attribute_or_default(node, @name, 'logrotate_size') 30 | @logrotate_max_size = new_resource.user_opts || Logstash.get_attribute_or_default(node, @name, 'logrotate_max_size') 31 | @logrotate_use_filesize = new_resource.logrotate_use_filesize || Logstash.get_attribute_or_default(node, @name, 'logrotate_use_filesize') 32 | @logrotate_frequency = new_resource.logrotate_frequency || Logstash.get_attribute_or_default(node, @name, 'logrotate_frequency') 33 | @logrotate_max_backup = new_resource.logrotate_max_backup || Logstash.get_attribute_or_default(node, @name, 'logrotate_max_backup') 34 | @logrotate_options = new_resource.logrotate_options || Logstash.get_attribute_or_default(node, @name, 'logrotate_options') 35 | @logrotate_enable = new_resource.logrotate_enable || Logstash.get_attribute_or_default(node, @name, 'logrotate_enable') 36 | @logrotate_files = new_resource.logrotate_files || Logstash.get_attribute_or_default(node, @name, 'logrotate_files') 37 | @log_file = "#{@unversioned_instance_dir}/log/#{@logrotate_files}" unless Pathname.new(@logrotate_files).absolute? 38 | end 39 | 40 | action :delete do 41 | ls = ls_vars 42 | 43 | idr = directory ls[:instance_dir] do 44 | recursive true 45 | action :delete 46 | end 47 | new_resource.updated_by_last_action(idr.updated_by_last_action?) 48 | 49 | if ::File.symlink? ls[:unversioned_instance_dir] 50 | ul = link ls[:unversioned_instance_dir] do 51 | action :delete 52 | end 53 | new_resource.updated_by_last_action(ul.updated_by_last_action?) 54 | else 55 | udr = directory ls[:unversioned_instance_dir] do 56 | recursive true 57 | action :delete 58 | end 59 | new_resource.updated_by_last_action(udr.updated_by_last_action?) 60 | end 61 | end 62 | 63 | action :create do 64 | ls = ls_vars 65 | 66 | # handle instances set up with previous cookbook versions 67 | unless ::File.symlink? ls[:unversioned_instance_dir] 68 | udr = directory ls[:unversioned_instance_dir] do 69 | recursive true 70 | action :delete 71 | end 72 | new_resource.updated_by_last_action(udr.updated_by_last_action?) 73 | end 74 | 75 | if ls[:create_account] 76 | ur = user ls[:user] do 77 | home ls[:homedir] 78 | system true 79 | action :create 80 | manage_home true 81 | uid ls[:uid] 82 | end 83 | new_resource.updated_by_last_action(ur.updated_by_last_action?) 84 | 85 | gr = group ls[:group] do 86 | gid ls[:gid] 87 | members ls[:user] 88 | append true 89 | system true 90 | end 91 | new_resource.updated_by_last_action(gr.updated_by_last_action?) 92 | end 93 | 94 | ls[:join_groups].each do |grp| 95 | gr = group grp do 96 | action :modify 97 | members ls[:user] 98 | append true 99 | end 100 | new_resource.updated_by_last_action(gr.updated_by_last_action?) 101 | end 102 | 103 | case @install_type 104 | when 'tarball' 105 | @run_context.include_recipe 'ark::default' 106 | arkit = ark ls[:name] do 107 | url ls[:source_url] 108 | checksum ls[:checksum] 109 | owner ls[:user] 110 | group ls[:group] 111 | mode 0755 112 | version ls[:version] 113 | path "#{ls[:basedir]}/#{ls[:version]}" 114 | action :put 115 | end 116 | new_resource.updated_by_last_action(arkit.updated_by_last_action?) 117 | 118 | %w(bin etc lib log tmp etc/conf.d patterns).each do |ldir| 119 | r = directory "#{ls[:instance_dir]}/#{ldir}" do 120 | action :create 121 | mode '0755' 122 | owner ls[:user] 123 | group ls[:group] 124 | end 125 | new_resource.updated_by_last_action(r.updated_by_last_action?) 126 | end 127 | 128 | when 'jar' 129 | bdr = directory @base_directory do 130 | action :create 131 | mode '0755' 132 | owner ls[:user] 133 | group ls[:group] 134 | end 135 | new_resource.updated_by_last_action(bdr.updated_by_last_action?) 136 | 137 | idr = directory ls[:instance_dir] do 138 | action :create 139 | mode '0755' 140 | owner ls[:user] 141 | group ls[:group] 142 | end 143 | new_resource.updated_by_last_action(idr.updated_by_last_action?) 144 | 145 | %w(bin etc lib log tmp etc/conf.d patterns).each do |ldir| 146 | r = directory "#{ls[:instance_dir]}/#{ldir}" do 147 | action :create 148 | mode '0755' 149 | owner ls[:user] 150 | group ls[:group] 151 | end 152 | new_resource.updated_by_last_action(r.updated_by_last_action?) 153 | end 154 | 155 | rfr = remote_file "#{ls[:instance_dir]}/lib/logstash-#{ls[:version]}.jar" do 156 | owner ls[:user] 157 | group ls[:group] 158 | mode '0755' 159 | source ls[:source_url] 160 | checksum ls[:checksum] 161 | end 162 | new_resource.updated_by_last_action(rfr.updated_by_last_action?) 163 | 164 | lr = link "#{ls[:instance_dir]}/lib/logstash.jar" do 165 | to "#{ls[:instance_dir]}/lib/logstash-#{ls[:version]}.jar" 166 | only_if { new_resource.auto_symlink } 167 | end 168 | new_resource.updated_by_last_action(lr.updated_by_last_action?) 169 | 170 | when 'source' 171 | bdr = directory @base_directory do 172 | action :create 173 | mode '0755' 174 | owner ls[:user] 175 | group ls[:group] 176 | end 177 | new_resource.updated_by_last_action(bdr.updated_by_last_action?) 178 | 179 | idr = directory ls[:instance_dir] do 180 | action :create 181 | mode '0755' 182 | owner ls[:user] 183 | group ls[:group] 184 | end 185 | new_resource.updated_by_last_action(idr.updated_by_last_action?) 186 | 187 | %w(bin etc lib log tmp etc/conf.d patterns).each do |ldir| 188 | r = directory "#{ls[:instance_dir]}/#{ldir}" do 189 | action :create 190 | mode '0755' 191 | owner ls[:user] 192 | group ls[:group] 193 | end 194 | new_resource.updated_by_last_action(r.updated_by_last_action?) 195 | end 196 | 197 | sd = directory "#{ls[:instance_dir]}/source" do 198 | action :create 199 | owner ls[:user] 200 | group ls[:group] 201 | mode '0755' 202 | end 203 | new_resource.updated_by_last_action(sd.updated_by_last_action?) 204 | 205 | gr = git "#{ls[:instance_dir]}/source" do 206 | repository @repo 207 | reference @sha 208 | action :sync 209 | user ls[:user] 210 | group ls[:group] 211 | end 212 | new_resource.updated_by_last_action(gr.updated_by_last_action?) 213 | 214 | source_version = @sha || "v#{@version}" 215 | er = execute 'build-logstash' do 216 | cwd "#{ls[:instance_dir]}/source" 217 | environment(JAVA_HOME: @java_home) 218 | user ls_user # Changed from root cause building as root...WHA? 219 | command "make clean && make VERSION=#{source_version} jar" 220 | action :run 221 | creates "#{ls[:instance_dir]}/source/build/logstash-#{source_version}--monolithic.jar" 222 | not_if "test -f #{ls[:instance_dir]}/source/build/logstash-#{source_version}--monolithic.jar" 223 | end 224 | new_resource.updated_by_last_action(er.updated_by_last_action?) 225 | lr = link "#{ls[:instance_dir]}/lib/logstash.jar" do 226 | to "#{ls[:instance_dir]}/source/build/logstash-#{source_version}--monolithic.jar" 227 | only_if { new_resource.auto_symlink } 228 | end 229 | new_resource.updated_by_last_action(lr.updated_by_last_action?) 230 | else 231 | Chef::Application.fatal!("Unknown install type: #{@install_type}") 232 | end 233 | ul = link ls[:unversioned_instance_dir] do 234 | to ls[:instance_dir] 235 | end 236 | new_resource.updated_by_last_action(ul.updated_by_last_action?) 237 | logrotate(ls) if ls[:logrotate_enable] 238 | end 239 | 240 | private 241 | 242 | def logrotate(ls) 243 | name = ls[:name] 244 | 245 | @run_context.include_recipe 'logrotate::default' 246 | 247 | logrotate_app "logstash_#{name}" do 248 | path ls[:logrotate_files] 249 | size ls[:logrotate_size] if ls[:logrotate_use_filesize] 250 | maxsize ls[:logrotate_max_size] if ls[:logrotate_use_filesize] 251 | frequency ls[:logrotate_frequency] 252 | rotate ls[:logrotate_max_backup] 253 | options ls[:logrotate_options] 254 | postrotate ["service logstash_#{name} restart > /dev/null"] 255 | create "664 #{ls[:user]} #{ls[:group]}" 256 | end 257 | end 258 | 259 | def ls_vars 260 | ls = { 261 | homedir: @useropts['homedir'], 262 | uid: @useropts['uid'], 263 | gid: @useropts['gid'], 264 | source_url: @source_url, 265 | version: @version, 266 | checksum: @checksum, 267 | basedir: @base_directory, 268 | create_account: @create_account, 269 | user: @user, 270 | group: @group, 271 | join_groups: @join_groups, 272 | name: @name, 273 | instance_dir: @instance_dir, 274 | unversioned_instance_dir: @unversioned_instance_dir, 275 | enable_logrotate: @enable_logrotate, 276 | logrotate_files: @logrotate_files, 277 | logrotate_size: @logrotate_size, 278 | logrotate_max_size: @logrotate_max_size, 279 | logrotate_use_filesize: @logrotate_use_filesize, 280 | logrotate_frequency: @logrotate_frequency, 281 | logrotate_max_backup: @logrotate_max_backup, 282 | logrotate_options: @logrotate_options, 283 | logrotate_enable: @logrotate_enable 284 | } 285 | ls 286 | end 287 | -------------------------------------------------------------------------------- /providers/pattern.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # Cookbook Name:: logstash 3 | # Provider:: patterns 4 | # Author:: John E. Vincent 5 | # License:: Apache 2.0 6 | # 7 | # Copyright 2014, John E. Vincent 8 | 9 | def load_current_resource 10 | @instance = new_resource.instance 11 | @basedir = Logstash.get_attribute_or_default(node, @instance, 'basedir') 12 | @templates = new_resource.templates || Logstash.get_attribute_or_default(node, @instance, 'pattern_templates') 13 | @variables = new_resource.variables || Logstash.get_attribute_or_default(node, @instance, 'pattern_templates_variables') 14 | @owner = new_resource.owner || Logstash.get_attribute_or_default(node, @instance, 'user') 15 | @group = new_resource.group || Logstash.get_attribute_or_default(node, @instance, 'group') 16 | @templates_cookbook = new_resource.templates_cookbook || Logstash.get_attribute_or_default(node, @instance, 'pattern_templates_cookbook') 17 | @mode = new_resource.mode || '0644' 18 | @path = new_resource.path || "#{@basedir}/#{@instance}/patterns" 19 | end 20 | 21 | action :create do 22 | pattern = pattern_vars 23 | # Chef::Log.info("config vars: #{pattern.inspect}") 24 | pattern[:templates].each do |_template, file| 25 | tp = template "#{pattern[:path]}/#{::File.basename(file).chomp(::File.extname(file))}" do 26 | source file 27 | cookbook pattern[:templates_cookbook] 28 | owner pattern[:owner] 29 | group pattern[:group] 30 | mode pattern[:mode] 31 | variables pattern[:variables] 32 | notifies :restart, "logstash_service[#{pattern[:instance]}]" 33 | action :create 34 | end 35 | new_resource.updated_by_last_action(tp.updated_by_last_action?) 36 | end 37 | end 38 | 39 | private 40 | 41 | def pattern_vars 42 | pattern = { 43 | instance: @instance, 44 | templates: @templates, 45 | variables: @variables, 46 | path: @path, 47 | owner: @owner, 48 | group: @group, 49 | mode: @mode, 50 | templates_cookbook: @templates_cookbook 51 | } 52 | pattern 53 | end 54 | -------------------------------------------------------------------------------- /providers/plugins.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # Cookbook Name:: logstash 3 | # Provider:: plugins 4 | # Author:: John E. Vincent 5 | # License:: Apache 2.0 6 | # 7 | # Copyright 2014, John E. Vincent 8 | 9 | def load_current_resource 10 | @name = new_resource.name || 'contrib' 11 | @instance = new_resource.instance || 'default' 12 | 13 | @base_directory = new_resource.base_directory || Logstash.get_attribute_or_default(node, @instance, 'basedir') 14 | @version = new_resource.version || Logstash.get_attribute_or_default(node, @instance, 'plugins_version') 15 | @checksum = new_resource.checksum || Logstash.get_attribute_or_default(node, @instance, 'plugins_checksum') 16 | @source_url = new_resource.source_url || Logstash.get_attribute_or_default(node, @instance, 'plugins_source_url') 17 | @user = new_resource.user || Logstash.get_attribute_or_default(node, @instance, 'user') 18 | @group = new_resource.group || Logstash.get_attribute_or_default(node, @instance, 'group') 19 | @instance_dir = "#{@base_directory}/#{@instance}" 20 | @install_type = new_resource.install_type || Logstash.get_attribute_or_default(node, @instance, 'plugins_install_type') 21 | @install_check = new_resource.install_check || Logstash.get_attribute_or_default(node, @instance, 'plugins_check_if_installed') 22 | end 23 | 24 | action :create do 25 | ls_version = @version 26 | ls_checksum = @checksum 27 | ls_source_url = @source_url 28 | ls_basedir = @base_directory 29 | ls_user = @user 30 | ls_group = @group 31 | ls_name = @name 32 | ls_instance = @instance 33 | ls_instance_dir = @instance_dir 34 | ls_install_check = @install_check 35 | 36 | case @install_type 37 | when 'native' 38 | ex = execute "bin/plugin install #{ls_name}" do 39 | command "bin/plugin install #{ls_name}" 40 | user ls_user 41 | group ls_group 42 | cwd ls_instance_dir 43 | notifies :restart, "logstash_service[#{ls_instance}]" 44 | # this is a temp workaround to make the plugin command idempotent. 45 | not_if { ::File.exist?("#{ls_instance_dir}/#{ls_install_check}") } 46 | end 47 | new_resource.updated_by_last_action(ex.updated_by_last_action?) 48 | when 'tarball' 49 | @run_context.include_recipe 'ark::default' 50 | arkit = ark "#{ls_instance}_contrib" do 51 | name ls_instance 52 | url ls_source_url 53 | checksum ls_checksum 54 | owner ls_user 55 | group ls_group 56 | mode 0755 57 | version ls_version 58 | path ls_basedir 59 | action [:put] 60 | notifies :restart, "logstash_service[#{ls_instance}]" 61 | # this is a temp workaround to ensure idempotent. 62 | not_if { ::File.exist?("#{ls_instance_dir}/#{ls_install_check}") } 63 | end 64 | new_resource.updated_by_last_action(arkit.updated_by_last_action?) 65 | else 66 | Chef::Application.fatal!("Unknown install type: #{@install_type}") 67 | end 68 | end 69 | 70 | action :update do 71 | ls_version = @version 72 | ls_checksum = @checksum 73 | ls_source_url = @source_url 74 | ls_basedir = @base_directory 75 | ls_user = @user 76 | ls_group = @group 77 | ls_name = @name 78 | ls_instance = @instance 79 | ls_instance_dir = @instance_dir 80 | ls_install_check = @install_check 81 | 82 | case @install_type 83 | when 'native' 84 | ex = execute "bin/plugin update #{ls_name}" do 85 | command "echo 'Y' | bin/plugin update #{ls_name}" 86 | user ls_user 87 | group ls_group 88 | cwd ls_instance_dir 89 | notifies :restart, "logstash_service[#{ls_instance}]" 90 | # this is a temp workaround to make the plugin command idempotent. 91 | not_if { ::File.exist?("#{ls_instance_dir}/#{ls_install_check}") } 92 | end 93 | new_resource.updated_by_last_action(ex.updated_by_last_action?) 94 | when 'tarball' 95 | Chef::Application.fatal!('Cannot update from tarball') 96 | else 97 | Chef::Application.fatal!("Unknown install type: #{@install_type}") 98 | end 99 | end 100 | -------------------------------------------------------------------------------- /providers/service.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # Cookbook Name:: logstash 3 | # Provider:: service 4 | # Author:: John E. Vincent 5 | # License:: Apache 2.0 6 | # 7 | # Copyright 2014, John E. Vincent 8 | 9 | require 'pathname' 10 | 11 | def load_current_resource 12 | @instance = new_resource.instance 13 | @basedir = new_resource.base_directory || Logstash.get_attribute_or_default(node, @instance, 'basedir') 14 | @templates_cookbook = new_resource.templates_cookbook || Logstash.get_attribute_or_default(node, @instance, 'service_templates_cookbook') 15 | @service_name = new_resource.service_name || "logstash_#{@instance}" 16 | @home = "#{@basedir}/#{@instance}" 17 | @init_method = new_resource.init_method || Logstash.get_attribute_or_default(node, @instance, 'init_method') 18 | @command = new_resource.command || "#{@home}/bin/logstash" 19 | @user = new_resource.user || Logstash.get_attribute_or_default(node, @instance, 'user') 20 | @group = new_resource.group || Logstash.get_attribute_or_default(node, @instance, 'group') 21 | @log_file = Logstash.get_attribute_or_default(node, @instance, 'log_file') 22 | @log_file = "#{@home}/log/#{@log_file}" unless Pathname.new(@log_file).absolute? 23 | @max_heap = Logstash.get_attribute_or_default(node, @instance, 'xmx') 24 | @min_heap = Logstash.get_attribute_or_default(node, @instance, 'xms') 25 | @gc_opts = Logstash.get_attribute_or_default(node, @instance, 'gc_opts') 26 | @ipv4_only = Logstash.get_attribute_or_default(node, @instance, 'ipv4_only') 27 | @java_opts = Logstash.get_attribute_or_default(node, @instance, 'java_opts') 28 | @description = new_resource.description || @service_name 29 | @chdir = @home 30 | @workers = Logstash.get_attribute_or_default(node, @instance, 'workers') 31 | @debug = Logstash.get_attribute_or_default(node, @instance, 'debug') 32 | @pluginpath = Logstash.get_attribute_or_default(node, @instance, 'pluginpath') 33 | @install_type = Logstash.get_attribute_or_default(node, @instance, 'install_type') 34 | @supervisor_gid = Logstash.get_attribute_or_default(node, @instance, 'supervisor_gid') 35 | @runit_run_template_name = Logstash.get_attribute_or_default(node, @instance, 'runit_run_template_name') 36 | @runit_log_template_name = Logstash.get_attribute_or_default(node, @instance, 'runit_log_template_name') 37 | @nofile_soft = Logstash.get_attribute_or_default(node, @instance, 'limit_nofile_soft') 38 | @nofile_hard = Logstash.get_attribute_or_default(node, @instance, 'limit_nofile_hard') 39 | end 40 | 41 | action :restart do 42 | new_resource.updated_by_last_action(service_action(:restart)) 43 | end 44 | 45 | action :start do 46 | new_resource.updated_by_last_action(service_action(:start)) 47 | end 48 | 49 | action :stop do 50 | new_resource.updated_by_last_action(service_action(:stop)) 51 | end 52 | 53 | action :reload do 54 | new_resource.updated_by_last_action(service_action(:reload)) 55 | end 56 | 57 | action :enable do 58 | svc = svc_vars 59 | Chef::Log.info("Using init method #{svc[:init_method]} for #{svc[:service_name]}") 60 | case svc[:init_method] 61 | when 'runit' 62 | @run_context.include_recipe 'runit::default' 63 | ri = runit_service svc[:service_name] do 64 | options( 65 | name: svc[:name], 66 | home: svc[:home], 67 | max_heap: svc[:max_heap], 68 | min_heap: svc[:min_heap], 69 | gc_opts: svc[:gc_opts], 70 | java_opts: svc[:java_opts], 71 | ipv4_only: svc[:ipv4_only], 72 | debug: svc[:debug], 73 | log_file: svc[:log_file], 74 | workers: svc[:workers], 75 | install_type: svc[:install_type], 76 | supervisor_gid: svc[:supervisor_gid], 77 | user: svc[:user], 78 | web_address: svc[:web_address], 79 | web_port: svc[:web_port] 80 | ) 81 | cookbook svc[:templates_cookbook] 82 | run_template_name svc[:runit_run_template_name] 83 | log_template_name svc[:runit_log_template_name] 84 | end 85 | new_resource.updated_by_last_action(ri.updated_by_last_action?) 86 | 87 | when 'native' 88 | Chef::Log.warn("Using any init method other than runit is depreciated. It is 89 | recommended that you write your own service resources in your wrapper cookbook 90 | if the default runit is not suitable.") 91 | native_init = ::Logstash.determine_native_init(node) 92 | args = default_args 93 | 94 | if native_init == 'upstart' 95 | tp = template "/etc/init/#{svc[:service_name]}.conf" do 96 | mode '0644' 97 | source "init/upstart/#{svc[:install_type]}.erb" 98 | cookbook svc[:templates_cookbook] 99 | variables( 100 | user_supported: ::Logstash.upstart_supports_user?(node), 101 | home: svc[:home], 102 | name: svc[:name], 103 | command: svc[:command], 104 | args: args, 105 | user: svc[:user], 106 | group: svc[:group], 107 | description: svc[:description], 108 | max_heap: svc[:max_heap], 109 | min_heap: svc[:min_heap], 110 | gc_opts: svc[:gc_opts], 111 | java_opts: svc[:java_opts], 112 | ipv4_only: svc[:ipv4_only], 113 | debug: svc[:debug], 114 | log_file: svc[:log_file], 115 | workers: svc[:workers], 116 | supervisor_gid: svc[:supervisor_gid], 117 | upstart_with_sudo: svc[:upstart_with_sudo], 118 | nofile_soft: svc[:nofile_soft], 119 | nofile_hard: svc[:nofile_hard] 120 | ) 121 | notifies :restart, "service[#{svc[:service_name]}]", :delayed 122 | end 123 | new_resource.updated_by_last_action(tp.updated_by_last_action?) 124 | sv = service svc[:service_name] do 125 | provider Chef::Provider::Service::Upstart 126 | supports restart: true, reload: true, start: true, stop: true 127 | action [:enable] 128 | end 129 | new_resource.updated_by_last_action(sv.updated_by_last_action?) 130 | 131 | elsif native_init == 'systemd' 132 | ex = execute 'reload-systemd' do 133 | command 'systemctl --system daemon-reload' 134 | action :nothing 135 | end 136 | new_resource.updated_by_last_action(ex.updated_by_last_action?) 137 | vars = svc_vars.merge(args: args) 138 | tp = template "/etc/systemd/system/#{svc[:service_name]}.service" do 139 | tp = source "init/systemd/#{svc[:install_type]}.erb" 140 | cookbook svc[:templates_cookbook] 141 | owner 'root' 142 | group 'root' 143 | mode '0755' 144 | variables( 145 | home: svc[:home], 146 | user: svc[:user], 147 | min_heap: svc[:min_heap], 148 | max_heap: svc[:max_heap], 149 | supervisor_gid: svc[:supervisor_gid], 150 | args: args 151 | ) 152 | notifies :run, 'execute[reload-systemd]', :immediately 153 | notifies :restart, "service[#{svc[:service_name]}]", :delayed 154 | end 155 | new_resource.updated_by_last_action(tp.updated_by_last_action?) 156 | sv = service svc[:service_name] do 157 | provider Chef::Provider::Service::Systemd 158 | action [:enable, :start] 159 | end 160 | new_resource.updated_by_last_action(sv.updated_by_last_action?) 161 | 162 | elsif native_init == 'sysvinit' 163 | tp = template "/etc/init.d/#{svc[:service_name]}" do 164 | source "init/sysvinit/#{svc[:install_type]}.erb" 165 | cookbook svc[:templates_cookbook] 166 | owner 'root' 167 | group 'root' 168 | mode '0774' 169 | variables( 170 | home: svc[:home], 171 | name: svc[:name], 172 | command: svc[:command], 173 | args: args, 174 | user: svc[:user], 175 | group: svc[:group], 176 | description: svc[:description], 177 | max_heap: svc[:max_heap], 178 | min_heap: svc[:min_heap], 179 | gc_opts: svc[:gc_opts], 180 | java_opts: svc[:java_opts], 181 | ipv4_only: svc[:ipv4_only], 182 | debug: svc[:debug], 183 | log_file: svc[:log_file], 184 | workers: svc[:workers], 185 | supervisor_gid: svc[:supervisor_gid], 186 | config_file: "#{svc[:home]}/etc/conf.d" 187 | ) 188 | notifies :restart, "service[#{svc[:service_name]}]", :delayed 189 | end 190 | new_resource.updated_by_last_action(tp.updated_by_last_action?) 191 | sv = service svc[:service_name] do 192 | supports restart: true, reload: true, status: true 193 | action [:enable, :start] 194 | end 195 | new_resource.updated_by_last_action(sv.updated_by_last_action?) 196 | end 197 | 198 | else 199 | Chef::Log.fatal("Unsupported init method: #{svc[:init_method]}") 200 | end 201 | end 202 | 203 | private 204 | 205 | def default_args 206 | svc = svc_vars 207 | args = ['agent', '-f', "#{svc[:home]}/etc/conf.d/"] 208 | args.concat ['-vv'] if svc[:debug] 209 | args.concat ['-l', svc[:log_file]] if svc[:log_file] 210 | args.concat ['-w', svc[:workers].to_s] if svc[:workers] 211 | args 212 | end 213 | 214 | def service_action(action) 215 | svc = svc_vars 216 | case svc[:init_method] 217 | when 'native' 218 | sv = service svc[:service_name] 219 | case ::Logstash.determine_native_init(node) 220 | when 'systemd' 221 | sv.provider(Chef::Provider::Service::Systemd) 222 | when 'upstart' 223 | sv.provider(Chef::Provider::Service::Upstart) 224 | else 225 | sv.provider(Chef::Provider::Service::Init) 226 | end 227 | when 'runit' 228 | @run_context.include_recipe 'runit::default' 229 | sv = runit_service svc[:service_name] 230 | end 231 | sv.run_action(action) 232 | sv.updated_by_last_action? 233 | end 234 | 235 | def svc_vars 236 | svc = { 237 | name: @instance, 238 | service_name: @service_name, 239 | home: @home, 240 | init_method: @init_method, 241 | command: @command, 242 | description: @description, 243 | chdir: @chdir, 244 | user: @user, 245 | group: @group, 246 | log_file: @log_file, 247 | max_heap: @max_heap, 248 | min_heap: @min_heap, 249 | java_opts: @java_opts, 250 | ipv4_only: @ipv4_only, 251 | workers: @workers, 252 | debug: @debug, 253 | pluginpath: @pluginpath, 254 | install_type: @install_type, 255 | supervisor_gid: @supervisor_gid, 256 | templates_cookbook: @templates_cookbook, 257 | runit_run_template_name: @runit_run_template_name, 258 | runit_log_template_name: @runit_log_template_name, 259 | nofile_soft: @nofile_soft, 260 | nofile_hard: @nofile_hard 261 | } 262 | svc 263 | end 264 | -------------------------------------------------------------------------------- /recipes/agent.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # 3 | # Cookbook Name:: logstash 4 | # Recipe:: agent 5 | # 6 | # 7 | 8 | name = 'agent' 9 | 10 | # these should all default correctly. listing out for example. 11 | logstash_instance name do 12 | action :create 13 | end 14 | 15 | # services are hard! Let's go LWRP'ing. FIREBALL! FIREBALL! FIREBALL! 16 | logstash_service name do 17 | action [:enable] 18 | end 19 | 20 | logstash_config name do 21 | variables( 22 | input_file_name: '/var/log/syslog', 23 | input_file_type: 'syslog' 24 | ) 25 | notifies :restart, "logstash_service[#{name}]" 26 | action [:create] 27 | end 28 | 29 | logstash_pattern name do 30 | action [:create] 31 | end 32 | -------------------------------------------------------------------------------- /recipes/beaver.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # 3 | # Cookbook Name:: logstash 4 | # Recipe:: beaver 5 | # 6 | # 7 | 8 | include_recipe 'poise-python::default' 9 | include_recipe 'beaver::default' 10 | -------------------------------------------------------------------------------- /recipes/default.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # 3 | # Cookbook Name:: logstash 4 | # Recipe:: default 5 | # 6 | -------------------------------------------------------------------------------- /recipes/install.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # 3 | # Author:: John E. Vincent 4 | # Author:: Bryan W. Berry () 5 | # Copyright 2012, John E. Vincent 6 | # Copyright 2012, Bryan W. Berry 7 | # License: Apache 2.0 8 | # Cookbook Name:: logstash 9 | # Recipe:: install 10 | # 11 | # 12 | 13 | # install logstash binaries 14 | -------------------------------------------------------------------------------- /recipes/server.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # 3 | # Author:: John E. Vincent 4 | # Author:: Bryan W. Berry () 5 | # Copyright 2012, John E. Vincent 6 | # Copyright 2012, Bryan W. Berry 7 | # License: Apache 2.0 8 | # Cookbook Name:: logstash 9 | # Recipe:: server 10 | # 11 | # 12 | 13 | # install logstash 'server' 14 | 15 | name = 'server' 16 | 17 | logstash_instance name do 18 | action :create 19 | end 20 | 21 | logstash_service name do 22 | action [:enable] 23 | end 24 | 25 | logstash_config name do 26 | action [:create] 27 | notifies :restart, "logstash_service[#{name}]" 28 | end 29 | 30 | logstash_plugins 'contrib' do 31 | instance name 32 | name 'logstash-output-influxdb' 33 | action [:create] 34 | end 35 | 36 | logstash_pattern name do 37 | action [:create] 38 | end 39 | 40 | logstash_curator 'server' do 41 | action [:create] 42 | end 43 | -------------------------------------------------------------------------------- /recipes/source.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | include_recipe 'build-essential' 3 | include_recipe 'ant' 4 | include_recipe 'git' 5 | include_recipe 'logstash::default' 6 | 7 | package 'wget' 8 | 9 | logstash_version = node['logstash']['source']['sha'] || "v#{node['logstash']['server']['version']}" 10 | 11 | directory "#{node['logstash']['basedir']}/source" do 12 | action :create 13 | owner node['logstash']['user'] 14 | group node['logstash']['group'] 15 | mode '0755' 16 | end 17 | 18 | git "#{node['logstash']['basedir']}/source" do 19 | repository node['logstash']['source']['repo'] 20 | reference logstash_version 21 | action :sync 22 | user node['logstash']['user'] 23 | group node['logstash']['group'] 24 | end 25 | 26 | execute 'build-logstash' do 27 | cwd "#{node['logstash']['basedir']}/source" 28 | environment( 29 | JAVA_HOME: node['logstash']['source']['java_home'] 30 | ) 31 | user 'root' 32 | # This variant is useful for troubleshooting stupid environment problems 33 | # command "make clean && make VERSION=#{logstash_version} --debug > /tmp/make.log 2>&1" 34 | command "make clean && make VERSION=#{logstash_version} jar" 35 | action :run 36 | creates "#{node['logstash']['basedir']}/source/build/logstash-#{logstash_version}-monolithic.jar" 37 | not_if "test -f #{node['logstash']['basedir']}/source/build/logstash-#{logstash_version}-monolithic.jar" 38 | end 39 | -------------------------------------------------------------------------------- /recipes/test.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # 3 | # Cookbook Name:: logstash 4 | # Recipe:: default 5 | # 6 | 7 | logstash_instance 'tarball' do 8 | version '1.4.0.rc1' 9 | checksum 'b015fa130d589af957c9a48e6f59754f5c0954835abf44bd013547a6b6520e59' 10 | source_url 'https://download.elasticsearch.org/logstash/logstash/logstash-1.4.0.rc1.tar.gz' 11 | install_type 'tarball' 12 | end 13 | -------------------------------------------------------------------------------- /resources/config.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # Cookbook Name:: logstash 3 | # Resource:: config 4 | # Author:: John E. Vincent 5 | # Copyright 2014, John E. Vincent 6 | # License:: Apache 2.0 7 | 8 | actions :create 9 | 10 | default_action :create if defined?(default_action) 11 | 12 | attribute :instance, kind_of: String, name_attribute: true 13 | attribute :service_name, kind_of: String 14 | attribute :templates, kind_of: Hash 15 | attribute :variables, kind_of: Hash, default: {} 16 | attribute :owner, kind_of: String 17 | attribute :group, kind_of: String 18 | attribute :mode, kind_of: String 19 | attribute :path, kind_of: String 20 | attribute :templates_cookbook, kind_of: String 21 | -------------------------------------------------------------------------------- /resources/curator.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # Cookbook Name:: logstash 3 | # Resource:: config 4 | # Author:: John E. Vincent 5 | # Copyright 2014, John E. Vincent 6 | # License:: Apache 2.0 7 | 8 | actions :create, :delete 9 | 10 | default_action :create if defined?(default_action) 11 | 12 | attribute :instance, kind_of: String, name_attribute: true 13 | attribute :days_to_keep, kind_of: String 14 | attribute :minute, kind_of: String 15 | attribute :hour, kind_of: String 16 | attribute :log_file, kind_of: String 17 | attribute :user, kind_of: String 18 | attribute :bin_dir, kind_of: String 19 | attribute :index_prefix, kind_of: String 20 | attribute :time_unit, kind_of: String 21 | attribute :timestring, kind_of: String 22 | -------------------------------------------------------------------------------- /resources/instance.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # Cookbook Name:: logstash 3 | # Resource:: instance 4 | # Author:: John E. Vincent 5 | # Copyright 2014, John E. Vincent 6 | # License:: Apache 2.0 7 | 8 | actions :create, :delete 9 | 10 | default_action :create if defined?(default_action) 11 | 12 | attribute :name, kind_of: String, name_attribute: true 13 | attribute :base_directory, kind_of: String 14 | attribute :install_type, kind_of: String 15 | attribute :auto_symlink, kind_of: [TrueClass, FalseClass], default: true 16 | # version/checksum/source_url used by `jar`, `tarball` install_type 17 | attribute :version, kind_of: String 18 | attribute :checksum, kind_of: String 19 | attribute :source_url, kind_of: String 20 | # sha/repo/java_home used by `source` install_type 21 | attribute :sha, kind_of: String, default: 'HEAD' 22 | attribute :repo, kind_of: String, default: 'git://github.com/logstash/logstash.git' 23 | attribute :java_home, kind_of: String 24 | attribute :user, kind_of: String 25 | attribute :group, kind_of: String 26 | attribute :create_account, kind_of: [TrueClass, FalseClass] 27 | attribute :join_groups, kind_of: [String] 28 | attribute :logrotate_enable, kind_of: [TrueClass, FalseClass] 29 | attribute :user_opts, kind_of: [Hash] 30 | attribute :logrotate_size, kind_of: [String] 31 | attribute :logrotate_max_size, kind_of: [String] 32 | attribute :logrotate_use_filesize, kind_of: [TrueClass, FalseClass] 33 | attribute :logrotate_frequency, kind_of: [String] 34 | attribute :logrotate_max_backup, kind_of: [Integer] 35 | attribute :logrotate_options, kind_of: [String] 36 | attribute :logrotate_files, kind_of: [String] 37 | -------------------------------------------------------------------------------- /resources/pattern.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # Cookbook Name:: logstash 3 | # Resource:: patterns 4 | # Author:: John E. Vincent 5 | # Copyright 2014, John E. Vincent 6 | # License:: Apache 2.0 7 | 8 | actions :create 9 | 10 | default_action :create if defined?(default_action) 11 | 12 | attribute :instance, kind_of: String, name_attribute: true 13 | attribute :templates, kind_of: Hash 14 | attribute :variables, kind_of: Hash 15 | attribute :path, kind_of: String 16 | attribute :owner, kind_of: String 17 | attribute :group, kind_of: String 18 | attribute :mode, kind_of: String 19 | attribute :templates_cookbook, kind_of: String 20 | -------------------------------------------------------------------------------- /resources/plugins.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # Cookbook Name:: logstash 3 | # Resource:: instance 4 | # Author:: John E. Vincent 5 | # Copyright 2014, John E. Vincent 6 | # License:: Apache 2.0 7 | 8 | actions :create, :update 9 | 10 | default_action :create if defined?(default_action) 11 | 12 | attribute :name, kind_of: String, name_attribute: true 13 | attribute :instance, kind_of: String 14 | attribute :version, kind_of: String 15 | attribute :checksum, kind_of: String 16 | attribute :source_url, kind_of: String 17 | attribute :user, kind_of: String 18 | attribute :group, kind_of: String 19 | attribute :base_directory, kind_of: String 20 | attribute :install_type, kind_of: String 21 | attribute :install_check, kind_of: String 22 | -------------------------------------------------------------------------------- /resources/service.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | # Cookbook Name:: logstash 3 | # Resource:: instance 4 | # Author:: John E. Vincent 5 | # Copyright 2014, John E. Vincent 6 | # License:: Apache 2.0 7 | 8 | actions :enable, :start, :restart, :reload, :stop 9 | 10 | default_action :enable if defined?(default_action) 11 | 12 | attribute :instance, kind_of: String, name_attribute: true 13 | attribute :service_name, kind_of: String 14 | attribute :init_method, kind_of: String 15 | attribute :command, kind_of: String 16 | attribute :args, kind_of: Array 17 | attribute :description, kind_of: String 18 | attribute :user, kind_of: String 19 | attribute :group, kind_of: String 20 | attribute :templates_cookbook, kind_of: String 21 | attribute :runit_run_template_name, kind_of: String 22 | attribute :runit_log_template_name, kind_of: String 23 | attribute :base_directory, kind_of: String 24 | -------------------------------------------------------------------------------- /templates/default/config/filter_apache.conf.erb: -------------------------------------------------------------------------------- 1 | filter { 2 | if [type] == "<%= @type %>" { 3 | grok { 4 | patterns_dir => ["/logstash/patterns"] 5 | match => ["message", "%{COMBINEDAPACHELOG}" ] 6 | } 7 | date { 8 | match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z", "dd/MMM/yyyy:HH:mm:ss" ] 9 | } 10 | # geoip { 11 | # source => "clientip" 12 | # } 13 | } 14 | } -------------------------------------------------------------------------------- /templates/default/config/input_file.conf.erb: -------------------------------------------------------------------------------- 1 | input { 2 | file { 3 | path => ["<%= @input_file_name %>"] 4 | type => ["<%= @input_file_type %>"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /templates/default/config/input_syslog.conf.erb: -------------------------------------------------------------------------------- 1 | input { 2 | tcp { 3 | port => "5959" 4 | type => "syslog" 5 | } 6 | udp { 7 | port => "514" 8 | type => "syslog" 9 | } 10 | } 11 | 12 | filter { 13 | if [type] == "syslog" { 14 | grok { 15 | overwrite => "message" 16 | match => [ 17 | "message", 18 | "%{SYSLOGTIMESTAMP:timestamp} %{IPORHOST:host} (?:%{PROG:program}(?:\[%{POSINT:pid}\])?: )?%{GREEDYDATA:message}" 19 | ] 20 | } 21 | syslog_pri { } 22 | date { 23 | # season to taste for your own syslog format(s) 24 | match => [ 25 | "timestamp", 26 | "MMM d HH:mm:ss", 27 | "MMM dd HH:mm:ss", 28 | "ISO8601" 29 | ] 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /templates/default/config/output_elasticsearch.conf.erb: -------------------------------------------------------------------------------- 1 | output { 2 | elasticsearch { 3 | <% if @elasticsearch_ip -%> 4 | host => "<%= @elasticsearch_ip %>" 5 | <% end -%> 6 | <% if @elasticsearch_cluster -%> 7 | cluster => "<%= @elasticsearch_cluster %>" 8 | <% end -%> 9 | <% if @elasticsearch_embedded -%> 10 | embedded => true 11 | <% else -%> 12 | embedded => false 13 | <% end -%> 14 | <% if @bind_host -%> 15 | bind_host => "<%= @bind_host %>" 16 | <% end -%> 17 | <% if @es_index -%> 18 | index => "<%= @es_index %>" 19 | <% end -%> 20 | <% if @es_protocol -%> 21 | protocol => "<%= @es_protocol %>" 22 | <% end -%> 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /templates/default/config/output_elasticsearch_http.conf.erb: -------------------------------------------------------------------------------- 1 | output { 2 | elasticsearch_http { 3 | <% if @elasticsearch_ip -%> 4 | host => "<%= @elasticsearch_ip %>" 5 | <% else -%> 6 | host => "127.0.0.1" 7 | <% end -%> 8 | <% if @es_index -%> 9 | index => "<%= @es_index %>" 10 | <% end -%> 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /templates/default/config/output_stdout.conf.erb: -------------------------------------------------------------------------------- 1 | output { 2 | stdout { 3 | codec => rubydebug 4 | } 5 | } -------------------------------------------------------------------------------- /templates/default/init/systemd/tarball.erb: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=logstash 3 | After=network.target 4 | 5 | [Service] 6 | User=<%= @user %> 7 | Group=<%= @supervisor_gid %> 8 | WorkingDirectory=<%= @home %> 9 | LimitNOFILE=<%= @nofile_soft %> 10 | Environment="LOGSTASH_HOME=<%= @home %>" 11 | Environment="HOME=<%= @home %>" 12 | Environment="LS_HEAP_SIZE=<%= @max_heap %>" 13 | Environment="GC_OPTS=<%= @gc_opts %>" 14 | Environment='LS_JAVA_OPTS=-server -Xms<%= @min_heap %> -Xmx<%= @max_heap %> -Djava.io.tmpdir=<%= @home %>/tmp/ <%= @java_opts %> <%= "-Djava.net.preferIPv4Stack=true" if @ipv4_only %>' 15 | ExecStart=<%= "#{@home}/bin/logstash #{@args.join(' ')}" %> 16 | Restart=on-failure 17 | RestartSec=30 18 | SyslogIdentifier=logstash_<%= @name %> 19 | 20 | [Install] 21 | WantedBy=multi-user.target 22 | -------------------------------------------------------------------------------- /templates/default/init/sysvinit/tarball.erb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # logstash 4 | # 5 | # chkconfig: - 57 47 6 | # description: logstash 7 | # processname: logstash 8 | 9 | 10 | PIDDIR="/var/run/logstash" 11 | export PIDFILE="$PIDDIR/logstash-<%= @name %>.pid" 12 | export LS_HOME="<%= @home %>" 13 | export LS_HEAP_SIZE="<%= @max_heap %>" 14 | export LOGSTASH_OPTS="<%= @args.join(' ') %>" 15 | LS_USER="<%= @user %>" 16 | LS_GROUP="<%= @group %>" 17 | LS_LOG="<%= @log_file %>" 18 | LOGDIR="<%= ::File.dirname @log_file %>" 19 | export LS_JAVA_OPTS="-server -Xms<%= @min_heap %> -Xmx<%= @max_heap %> -Djava.io.tmpdir=$LS_HOME/tmp/ <%= @java_opts %> <%= '-Djava.net.preferIPv4Stack=true' if @ipv4_only %>" 20 | BIN_SCRIPT="/usr/bin/env $LS_HOME/bin/logstash $LOGSTASH_OPTS > $LS_LOG 2>&1 & echo \$! > $PIDFILE" 21 | 22 | if [ -f /etc/init.d/functions ] ; then 23 | . /etc/init.d/functions 24 | fi 25 | 26 | start() { 27 | 28 | if [ ! -d "$PIDDIR" ] ; then 29 | mkdir "$PIDDIR" 30 | chown $LS_USER:$LS_GROUP $PIDDIR 31 | fi 32 | 33 | if [ -f $PIDFILE ]; then 34 | echo -e "\033[31;1mPID file found in $PIDFILE, already running?\033[0m" 35 | ls_pid="$(cat $PIDFILE)" 36 | pid_running="$( ps ax | grep 'java' | grep $ls_pid )" 37 | 38 | if [ ! -z "$pid_running" ] ; then 39 | echo -e "\033[31;1mPID $ls_pid still alive, logstash is already running. Doing nothing\033[0m" 40 | return 0 41 | fi 42 | fi 43 | 44 | echo -e "\033[1mStarting logstash...\033[0m" 45 | pushd $LS_HOME > /dev/null 2>&1 46 | su $LS_USER -c "$BIN_SCRIPT" > /dev/null 2>&1 47 | ls_pid=$! 48 | result=$? 49 | popd > /dev/null 2>&1 50 | 51 | if [ $result -ne 0 ] ; then 52 | failure 53 | echo -e "Logstash did not start successfully" 54 | exit 1 55 | else 56 | success 57 | echo -e "Logstash started successfully" 58 | fi 59 | 60 | } 61 | 62 | 63 | 64 | function stop() { 65 | echo -n -e "\033[1mStopping logstash...\033[0m" 66 | 67 | if [ -z "$SHUTDOWN_WAIT" ]; then 68 | SHUTDOWN_WAIT=5 69 | fi 70 | 71 | if [ ! -z "$PIDFILE" ]; then 72 | if [ -f "$PIDFILE" ]; then 73 | kill -0 `cat $PIDFILE` >/dev/null 2>&1 74 | if [ $? -gt 0 ]; then 75 | echo "PID file ($PIDFILE) found but no matching process was found. Nothing to do." 76 | return 0 77 | fi 78 | else 79 | echo "\$PIDFILE was set ($PIDFILE) but the specified file does not exist. Is Logstash running? Assuming it has stopped and pro\ 80 | ceeding." 81 | return 0 82 | fi 83 | fi 84 | 85 | kill `cat $PIDFILE` >/dev/null 2>&1 86 | 87 | if [ ! -z "$PIDFILE" ]; then 88 | if [ -f "$PIDFILE" ]; then 89 | while [ $SHUTDOWN_WAIT -ge 0 ]; do 90 | kill -0 `cat $PIDFILE` >/dev/null 2>&1 91 | if [ $? -gt 0 ]; then 92 | rm $PIDFILE 93 | break 94 | fi 95 | if [ $SHUTDOWN_WAIT -gt 0 ]; then 96 | sleep 1 97 | fi 98 | SHUTDOWN_WAIT=`expr $SHUTDOWN_WAIT - 1 ` 99 | done 100 | # still not dead, we may need to resort to drastic measures 101 | if [ -f "$PIDFILE" ]; then 102 | kill -0 `cat $PIDFILE` >/dev/null 2>&1 103 | if [ $? -eq 0 ]; then 104 | echo "Application still alive, sleeping for 20 seconds before sending SIGKILL" 105 | sleep 20 106 | kill -0 `cat $PIDFILE` >/dev/null 2>&1 107 | if [ $? -eq 0 ]; then 108 | kill -9 `cat $PIDFILE` >/dev/null 2>&1 109 | echo "Killed with extreme prejudice" 110 | else 111 | echo "Application stopped, no need to use SIGKILL" 112 | fi 113 | rm $PIDFILE 114 | fi 115 | fi 116 | fi 117 | fi 118 | } 119 | 120 | restart() { 121 | stop 122 | start 123 | } 124 | 125 | status() { 126 | # GOT PIDFILE? 127 | [ -f $PIDFILE ] && pid=$(cat $PIDFILE) 128 | 129 | # RUNNING 130 | if [[ $pid && -d "/proc/$pid" ]]; then 131 | success 132 | echo -e "Logstash is running with pid $pid" 133 | fi 134 | 135 | # NOT RUNNING 136 | if [[ ! $pid || ! -d "/proc/$pid" ]]; then 137 | echo "Logstash not running" 138 | exit 3 139 | fi 140 | 141 | # STALE PID FOUND 142 | if [[ ! -d "/proc/$pid" && -f $PIDFILE ]]; then 143 | echo -e "\033[1;31;40m[!] Stale PID found in $PIDFILE\033[0m" 144 | exit 1 145 | fi 146 | } 147 | 148 | 149 | case "$1" in 150 | start) 151 | start 152 | ;; 153 | stop) 154 | stop 155 | ;; 156 | restart) 157 | restart 158 | ;; 159 | status) 160 | status $2 161 | ;; 162 | *) 163 | echo $"Usage: $0 {start|stop|restart|status [-v]|}" 164 | exit 1 165 | esac 166 | 167 | exit $? 168 | -------------------------------------------------------------------------------- /templates/default/init/upstart/tarball.erb: -------------------------------------------------------------------------------- 1 | description "Logstash" 2 | author "Chef" 3 | 4 | start on (filesystem and net-device-up) 5 | stop on runlevel [!2345] 6 | 7 | respawn 8 | respawn limit 5 30 9 | limit nofile <%= @nofile_soft %> <%= @nofile_hard %> 10 | 11 | chdir <%= @home %> 12 | 13 | <% if @user_supported -%> 14 | setuid <%= @user %> 15 | <% unless @supervisor_gid.to_s.empty? -%> 16 | setgid <%= @supervisor_gid %> 17 | <% end -%> 18 | <% end -%> 19 | 20 | script 21 | export LS_HEAP_SIZE="<%= @max_heap %>" 22 | export LOGSTASH_HOME="<%= @home %>" 23 | export HOME=$LOGSTASH_HOME 24 | export LOGSTASH_OPTS="<%= @args.join(' ') %>" 25 | export GC_OPTS="<%= @gc_opts %>" 26 | export LS_JAVA_OPTS="-server -Xms<%= @min_heap %> -Xmx<%= @max_heap %> -Djava.io.tmpdir=$LOGSTASH_HOME/tmp/ <%= @java_opts %> <%= '-Djava.net.preferIPv4Stack=true' if @ipv4_only %>" 27 | <% if @user_supported -%> 28 | exec $LOGSTASH_HOME/bin/logstash $LOGSTASH_OPTS 29 | <% else -%> 30 | exec sudo -u <%= @user %> $LOGSTASH_HOME/bin/logstash $LOGSTASH_OPTS 31 | <% end -%> 32 | end script 33 | 34 | emits logstash-server-running 35 | -------------------------------------------------------------------------------- /templates/default/patterns/custom_patterns.erb: -------------------------------------------------------------------------------- 1 | # this file was created and managed by chef. 2 | # see https://github.com/elasticsearch/logstash/tree/master/patterns 3 | # for pattern examples. 4 | -------------------------------------------------------------------------------- /templates/default/server.conf.erb: -------------------------------------------------------------------------------- 1 | input { 2 | <% if node['logstash']['server']['inputs'].empty? -%> 3 | tcp { 4 | type => "tcp-input" 5 | port => "5959" 6 | codec => "json" 7 | } 8 | <% else -%> 9 | <%= LogstashConf.section_to_str(node['logstash']['server']['inputs']) %> 10 | <% end -%> 11 | } 12 | 13 | <% unless node['logstash']['server']['filters'].empty? -%> 14 | filter { 15 | <%= LogstashConf.section_to_str(node['logstash']['server']['filters'], node['logstash']['server']['version'], @patterns_dir) %> 16 | } 17 | <% end -%> 18 | 19 | output { 20 | <% if node['logstash']['server']['debug'] -%> 21 | stdout { debug => true } 22 | <% end -%> 23 | <% if @enable_embedded_es -%> 24 | elasticsearch { embedded => true } 25 | <% elsif not @es_server_ip.empty? -%> 26 | elasticsearch { host => "<%= @es_server_ip %>" cluster => "<%= @es_cluster %>" } 27 | <% end -%> 28 | <% unless @graphite_server_ip.empty? -%> 29 | graphite { host => "<%= @graphite_server_ip %>" metrics => ["logstash.events", "1"] } 30 | <% end -%> 31 | <% # unless node['logstash']['server']['outputs'].empty? -%> 32 | <%= LogstashConf.section_to_str(node['logstash']['server']['outputs']) %> 33 | <% # end -%> 34 | } 35 | -------------------------------------------------------------------------------- /templates/default/sv-logstash-log-run.erb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec svlogd -tt ./main 3 | -------------------------------------------------------------------------------- /templates/default/sv-logstash-run.erb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ulimit -Hn 65550 4 | ulimit -Sn 65550 5 | 6 | cd /<%= @options[:home] %> 7 | exec 2>&1 8 | # Need to set LOGSTASH_HOME and HOME so sincedb will work 9 | export LS_HEAP_SIZE=<%= @options[:max_heap] %> 10 | export LOGSTASH_HOME="<%= @options[:home] %>" 11 | # Must set HEAP_DUMP_PATH if vendored jruby is to work 12 | export HEAP_DUMP_PATH="-XX:HeapDumpPath=<%= @options[:home] %>/heapdump.hprof" 13 | export GC_OPTS="<%= @options[:gc_opts] %>" 14 | export LS_JAVA_OPTS="-server -Xms<%= @options[:min_heap] %> -Xmx<%= @options[:max_heap] %> -Djava.io.tmpdir=$LOGSTASH_HOME/tmp/ <%= @options[:java_opts] %> <%= '-Djava.net.preferIPv4Stack=true' if @options[:ipv4_only] %>" 15 | LOGSTASH_OPTS="agent -f $LOGSTASH_HOME/etc/conf.d" 16 | <% if @options[:pluginpath] -%> 17 | LOGSTASH_OPTS="$LOGSTASH_OPTS --pluginpath $LOGSTASH_HOME/lib" 18 | <% end -%> 19 | <% if @options[:debug] -%> 20 | LOGSTASH_OPTS="$LOGSTASH_OPTS -vv" 21 | <% end -%> 22 | LOGSTASH_OPTS="$LOGSTASH_OPTS -l <%= @options[:log_file] %>" 23 | export LOGSTASH_OPTS="$LOGSTASH_OPTS -w <%= @options[:workers] %>" 24 | <% if @options[:supervisor_gid] -%> 25 | HOME=$LOGSTASH_HOME exec chpst -u <%= @options[:user] %>:<%= @options[:supervisor_gid] %> $LOGSTASH_HOME/bin/logstash $LOGSTASH_OPTS 26 | <% else -%> 27 | HOME=$LOGSTASH_HOME exec chpst -u <%= @options[:user] %> $LOGSTASH_HOME/bin/logstash $LOGSTASH_OPTS 28 | <% end -%> 29 | -------------------------------------------------------------------------------- /templates/default/sv-logstash_web-log-run.erb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | exec svlogd -tt ./main 3 | -------------------------------------------------------------------------------- /templates/default/sv-logstash_web-run.erb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ulimit -Hn 65550 4 | ulimit -Sn 65550 5 | 6 | cd /<%= @options[:home] %> 7 | exec 2>&1 8 | 9 | LOGSTASH_HOME="<%= @options[:home] %>" 10 | GC_OPTS="<%= @options[:gc_opts] %>" 11 | <% 12 | instance_name = @options[:name].to_s 13 | %> 14 | LOGSTASH_OPTS="web -a <%= node['logstash']['instance'][instance_name]['web']['address'] %> -p <%= node['logstash']['instance'][instance_name]['web']['port'] %>" 15 | 16 | <% if @options[:install_type] == 'tarball' -%> 17 | <% if ! @options[:supervisor_gid].empty? -%> 18 | HOME=$LOGSTASH_HOME exec chpst -u <%= @options[:user] %>:<%= @options[:supervisor_gid] %> $LOGSTASH_HOME/bin/logstash $LOGSTASH_OPTS 19 | <% else -%> 20 | HOME=$LOGSTASH_HOME exec chpst -u <%= @options[:user] %> $LOGSTASH_HOME/bin/logstash $LOGSTASH_OPTS 21 | <% end -%> 22 | <% else -%> 23 | <% if ! @options[:supervisor_gid].empty? -%> 24 | HOME=$LOGSTASH_HOME exec chpst -u <%= @options[:user] %>:<%= @options[:supervisor_gid] %> java $GC_OPTS -jar $LOGSTASH_HOME/lib/logstash.jar $LOGSTASH_OPTS 25 | <% else -%> 26 | HOME=$LOGSTASH_HOME exec chpst -u <%= @options[:user] %> java $GC_OPTS -jar $LOGSTASH_HOME/lib/logstash.jar $LOGSTASH_OPTS 27 | <% end -%> 28 | <% end -%> 29 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/logstash-test/attributes/default.rb: -------------------------------------------------------------------------------- 1 | # send log lines to localhost only 2 | default['rsyslog']['server_ip'] = '127.0.0.1' 3 | default['rsyslog']['port'] = '5959' 4 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/logstash-test/metadata.rb: -------------------------------------------------------------------------------- 1 | name 'logstash-test' 2 | version '1.0.0' 3 | 4 | depends 'chef-sugar' 5 | depends 'logstash' 6 | depends 'elasticsearch', '~> 2.5.0' 7 | depends 'rsyslog' 8 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/logstash-test/recipes/default.rb: -------------------------------------------------------------------------------- 1 | include_recipe 'chef-sugar' 2 | 3 | # configure ES instance, small memory footprint, enable and start it 4 | include_recipe 'elasticsearch' 5 | es_conf = resources('elasticsearch_configure[elasticsearch]') 6 | es_conf.allocated_memory '128m' 7 | es_svc = resources('elasticsearch_service[elasticsearch]') 8 | es_svc.service_actions [:enable, :start] 9 | 10 | # install logstash without embedded ES 11 | include_recipe 'logstash::server' 12 | 13 | # send logs to logstash now 14 | include_recipe 'rsyslog::client' 15 | -------------------------------------------------------------------------------- /test/integration/helpers/serverspec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | require 'serverspec' 3 | 4 | if (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM).nil? 5 | set :backend, :exec 6 | set :path, '/sbin:/usr/local/sbin:/bin:/usr/bin:$PATH' 7 | else 8 | set :backend, :cmd 9 | set :os, family: 'windows' 10 | end 11 | -------------------------------------------------------------------------------- /test/integration/server/serverspec/server_spec.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | require_relative 'spec_helper' 3 | 4 | # Java 1.8 5 | describe command('java -version') do 6 | its(:stderr) { should match(/java version "1.8.\d+_\d+"/) } 7 | end 8 | 9 | # Logstash Instance 10 | describe service('logstash_server') do 11 | it { should be_enabled } 12 | it { should be_running } 13 | end 14 | 15 | describe user('logstash') do 16 | it { should exist } 17 | end 18 | 19 | # Logstash Config 20 | describe file('/opt/logstash/server/etc/conf.d/input_syslog') do 21 | it { should be_file } 22 | end 23 | 24 | describe file('/opt/logstash/server/etc/conf.d/output_elasticsearch') do 25 | it { should be_file } 26 | end 27 | 28 | describe file('/opt/logstash/server/etc/conf.d/output_stdout') do 29 | it { should be_file } 30 | end 31 | 32 | describe file('/etc/logrotate.d/logstash_server') do 33 | it { should be_file } 34 | its(:content) { should match(/maxsize 25MB/) } 35 | end 36 | 37 | describe port(9200) do 38 | it { should be_listening } 39 | end 40 | 41 | describe port(5959) do 42 | it { should be_listening } 43 | end 44 | 45 | # Logstash Curator 46 | describe cron do 47 | it { should have_entry('0 * * * * /usr/local/bin/curator --host 127.0.0.1 delete indices --older-than 31 --time-unit days --timestring \'\%Y.\%m.\%d\' --prefix logstash- &> /dev/null').with_user('logstash') } 48 | end 49 | -------------------------------------------------------------------------------- /test/unit/spec/agent_spec.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | require_relative 'spec_helper' 3 | 4 | describe 'logstash::agent' do 5 | describe 'ubuntu' do 6 | let(:runner) { ChefSpec::SoloRunner.new(::UBUNTU_OPTS) } 7 | let(:node) { runner.node } 8 | let(:chef_run) do 9 | # runner.node.set['logstash'] ... 10 | runner.node.automatic['memory']['total'] = '1024kB' 11 | runner.node.normal['logstash']['instance']['agent']['basedir'] = '/opt/logstash' 12 | runner.node.normal['logstash']['instance']['agent']['user'] = 'logstash' 13 | runner.node.normal['logstash']['instance']['agent']['group'] = 'logstash' 14 | runner.node.normal['logstash']['instance']['agent']['config_templates_cookbook'] = 'logstash' 15 | runner.node.normal['logstash']['instance']['agent']['elasticsearch_ip'] = '127.0.0.1' 16 | runner.node.normal['logstash']['instance']['agent']['enable_embedded_es'] = false 17 | runner.converge(described_recipe) 18 | end 19 | include_context 'stubs-common' 20 | 21 | it 'calls the logstash_instance LWRP' do 22 | expect(chef_run).to create_logstash_instance('agent') 23 | end 24 | 25 | it 'calls the logstash_config LWRP' do 26 | expect(chef_run).to create_logstash_config('agent') 27 | end 28 | 29 | it 'calls the logstash_pattern LWRP' do 30 | expect(chef_run).to create_logstash_pattern('agent') 31 | end 32 | 33 | it 'calls the logstash_instance LWRP' do 34 | expect(chef_run).to enable_logstash_service('agent') 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /test/unit/spec/default_spec.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | require_relative 'spec_helper' 3 | 4 | describe 'logstash::default' do 5 | describe 'ubuntu' do 6 | let(:runner) { ChefSpec::SoloRunner.new(::UBUNTU_OPTS) } 7 | let(:node) { runner.node } 8 | let(:chef_run) do 9 | runner.node.normal['memory']['total'] = '1024000kb' 10 | runner.converge(described_recipe) 11 | end 12 | include_context 'stubs-common' 13 | 14 | it 'writes some chefspec code' do 15 | skip 'todo' 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /test/unit/spec/haproxy_spec.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | require_relative 'spec_helper' 3 | 4 | describe 'logstash::haproxy' do 5 | describe 'ubuntu' do 6 | let(:runner) { ChefSpec::SoloRunner.new(::UBUNTU_OPTS) } 7 | let(:node) { runner.node } 8 | let(:chef_run) do 9 | # runner.node.set['logstash'] ... 10 | runner.converge(described_recipe) 11 | end 12 | include_context 'stubs-common' 13 | 14 | it 'writes some chefspec code' do 15 | skip 'todo' 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /test/unit/spec/lwrp_config_spec.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | require_relative 'spec_helper' 3 | require_relative 'server_spec' 4 | 5 | ::LWRP = { 6 | step_into: ['logstash_config'] 7 | }.merge(::UBUNTU_OPTS) 8 | 9 | describe 'logstash::server' do 10 | describe 'ubuntu' do 11 | let(:runner) { ChefSpec::SoloRunner.new(::LWRP) } 12 | let(:node) { runner.node } 13 | let(:chef_run) do 14 | runner.node.normal['memory']['total'] = '1024000kb' 15 | runner.node.normal['logstash']['instance']['server']['basedir'] = '/opt/logstash' 16 | runner.node.normal['logstash']['instance']['server']['user'] = 'logstash' 17 | runner.node.normal['logstash']['instance']['server']['group'] = 'logstash' 18 | runner.node.normal['logstash']['instance']['server']['config_templates_cookbook'] = 'logstash' 19 | runner.node.normal['logstash']['instance']['server']['elasticsearch_ip'] = '127.0.0.1' 20 | runner.node.normal['logstash']['instance']['server']['enable_embedded_es'] = true 21 | runner.node.normal['logstash']['instance']['server']['config_templates'] = { 22 | output_stdout: 'config/output_stdout.conf.erb' 23 | } 24 | runner.converge(described_recipe) 25 | end 26 | include_context 'stubs-common' 27 | 28 | it 'installs the output_stdout template' do 29 | expect(chef_run).to create_template('/opt/logstash/server/etc/conf.d/output_stdout').with( 30 | source: 'config/output_stdout.conf.erb', 31 | cookbook: 'logstash', 32 | owner: 'logstash', 33 | group: 'logstash', 34 | mode: '0644', 35 | action: [:create] 36 | ) 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /test/unit/spec/lwrp_pattern_spec.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | require_relative 'spec_helper' 3 | require_relative 'server_spec' 4 | 5 | ::LWRP_PATTERN = { 6 | step_into: ['logstash_pattern'] 7 | }.merge(::UBUNTU_OPTS) 8 | 9 | describe 'logstash::server' do 10 | describe 'ubuntu' do 11 | let(:runner) { ChefSpec::SoloRunner.new(::LWRP_PATTERN) } 12 | let(:node) { runner.node } 13 | let(:chef_run) do 14 | runner.node.normal['memory']['total'] = '1024000kb' 15 | runner.node.normal['logstash']['instance']['server']['pattern_templates'] = { 16 | 'default' => 'patterns/custom_patterns.erb' 17 | } 18 | runner.node.normal['logstash']['instance']['server']['pattern_templates_variables'] = { 19 | 'test' => true 20 | } 21 | runner.node.normal['logstash']['instance']['server']['basedir'] = '/opt/logstash' 22 | runner.node.normal['logstash']['instance']['server']['user'] = 'logstash' 23 | runner.node.normal['logstash']['instance']['server']['group'] = 'logstash' 24 | runner.node.normal['logstash']['instance']['server']['pattern_templates_cookbook'] = 'logstash' 25 | runner.converge(described_recipe) 26 | end 27 | include_context 'stubs-common' 28 | 29 | it 'installs the pattern template' do 30 | expect(chef_run).to create_template('/opt/logstash/server/patterns/custom_patterns').with( 31 | source: 'patterns/custom_patterns.erb', 32 | cookbook: 'logstash', 33 | owner: 'logstash', 34 | group: 'logstash', 35 | mode: '0644', 36 | variables: { 'test' => true }, 37 | action: [:create] 38 | ) 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /test/unit/spec/pyshipper_spec.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | require_relative 'spec_helper' 3 | 4 | describe 'logstash::pyshipper' do 5 | describe 'ubuntu' do 6 | let(:runner) { ChefSpec::SoloRunner.new(::UBUNTU_OPTS) } 7 | let(:node) { runner.node } 8 | let(:chef_run) do 9 | # runner.node.set['logstash'] ... 10 | runner.converge(described_recipe) 11 | end 12 | include_context 'stubs-common' 13 | 14 | it 'writes some chefspec code' do 15 | skip 'todo' 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /test/unit/spec/server_spec.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | require_relative 'spec_helper' 3 | 4 | describe 'logstash::server' do 5 | describe 'ubuntu' do 6 | let(:runner) { ChefSpec::SoloRunner.new(::UBUNTU_OPTS) } 7 | let(:node) { runner.node } 8 | let(:chef_run) do 9 | # runner.node.set['logstash'] ... 10 | runner.node.automatic['memory']['total'] = '1024kB' 11 | runner.node.normal['logstash']['instance']['server']['basedir'] = '/opt/logstash' 12 | runner.node.normal['logstash']['instance']['server']['user'] = 'logstash' 13 | runner.node.normal['logstash']['instance']['server']['group'] = 'logstash' 14 | runner.node.normal['logstash']['instance']['server']['config_templates_cookbook'] = 'logstash' 15 | runner.node.normal['logstash']['instance']['server']['elasticsearch_ip'] = '127.0.0.1' 16 | runner.node.normal['logstash']['instance']['server']['enable_embedded_es'] = true 17 | runner.converge(described_recipe) 18 | end 19 | include_context 'stubs-common' 20 | 21 | it 'calls the logstash_instance LWRP' do 22 | expect(chef_run).to create_logstash_instance('server') 23 | end 24 | 25 | it 'calls the logstash_config LWRP' do 26 | expect(chef_run).to create_logstash_config('server') 27 | end 28 | 29 | it 'calls the logstash_pattern LWRP' do 30 | expect(chef_run).to create_logstash_pattern('server') 31 | end 32 | 33 | it 'calls the logstash_service LWRP' do 34 | expect(chef_run).to enable_logstash_service('server') 35 | end 36 | 37 | it 'calls the logstash_plugins LWRP' do 38 | expect(chef_run).to create_logstash_plugins('logstash-output-influxdb') 39 | end 40 | 41 | it 'calls the logstash_curator LWRP' do 42 | expect(chef_run).to create_logstash_curator('server') 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /test/unit/spec/source_spec.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | require_relative 'spec_helper' 3 | 4 | describe 'logstash::source' do 5 | describe 'ubuntu' do 6 | let(:runner) { ChefSpec::SoloRunner.new(::UBUNTU_OPTS) } 7 | let(:node) { runner.node } 8 | let(:chef_run) do 9 | # runner.node.set['logstash'] ... 10 | runner.converge(described_recipe) 11 | end 12 | include_context 'stubs-common' 13 | 14 | it 'writes some chefspec code' do 15 | skip 'todo' 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /test/unit/spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | require 'rspec/expectations' 3 | require 'chefspec' 4 | require 'chefspec/berkshelf' 5 | require 'chef/application' 6 | 7 | require_relative 'support/matchers' 8 | 9 | ::LOG_LEVEL = :fatal 10 | 11 | ::REDHAT_OPTS = { 12 | platform: 'redhat', 13 | version: '6.4', 14 | log_level: ::LOG_LEVEL 15 | } 16 | 17 | ::UBUNTU_OPTS = { 18 | platform: 'ubuntu', 19 | version: '14.04', 20 | log_level: ::LOG_LEVEL 21 | } 22 | 23 | shared_context 'stubs-common' do 24 | before do 25 | allow_any_instance_of(Chef::Application).to receive(:fatal!).and_return('fatal') 26 | stub_command("update-alternatives --display java | grep '/usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java - priority 1061'").and_return(true) 27 | stub_command("/usr/bin/python -c 'import setuptools'").and_return(true) 28 | stub_command('test -f /opt/logstash/source/build/logstash-v1.3.2-monolithic.jar').and_return(true) 29 | end 30 | end 31 | 32 | shared_examples 'example' do 33 | # it 'does not include example recipe by default' do 34 | # expect(chef_run).not_to include_recipe('example::default') 35 | # end 36 | end 37 | 38 | at_exit { ChefSpec::Coverage.report! } 39 | -------------------------------------------------------------------------------- /test/unit/spec/support/matchers.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | 3 | def enable_runit_service(resource_name) 4 | ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :enable, resource_name) 5 | end 6 | 7 | def start_runit_service(resource_name) 8 | ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :start, resource_name) 9 | end 10 | -------------------------------------------------------------------------------- /test/unit/spec/util_spec.rb: -------------------------------------------------------------------------------- 1 | # Encoding: utf-8 2 | require_relative '../../../libraries/logstash_util.rb' 3 | 4 | describe '::determine_platform_major_version' do 5 | context 'with ubuntu' do 6 | let(:node) { { 'platform' => 'ubuntu', 'platform_version' => '12.04' } } 7 | it 'returns full version' do 8 | expect(Logstash.determine_platform_major_version(node)).to eql(12.04) 9 | end 10 | end 11 | 12 | context 'with amazon' do 13 | let(:node) { { 'platform' => 'amazon', 'platform_version' => '2014.03' } } 14 | it 'returns full version' do 15 | expect(Logstash.determine_platform_major_version(node)).to eql(2014.03) 16 | end 17 | end 18 | 19 | context 'with other distributions' do 20 | let(:node) { { 'platform' => 'debian', 'platform_version' => '7.6' } } 21 | it 'returns version without point release' do 22 | expect(Logstash.determine_platform_major_version(node)).to eql(7) 23 | end 24 | end 25 | end 26 | 27 | describe '::upstart_supports_user?' do 28 | context 'with ubuntu' do 29 | context 'before user' do 30 | let(:node) { { 'platform' => 'ubuntu', 'platform_version' => '10.04' } } 31 | it 'returns false' do 32 | expect(Logstash.upstart_supports_user?(node)).to eql(false) 33 | end 34 | end 35 | context 'after user' do 36 | let(:node) { { 'platform' => 'ubuntu', 'platform_version' => '12.04' } } 37 | it 'returns true' do 38 | expect(Logstash.upstart_supports_user?(node)).to eql(true) 39 | end 40 | end 41 | end 42 | 43 | context 'with el' do 44 | let(:node) { { 'platform' => 'centos', 'platform_version' => '6' } } 45 | it 'returns false' do 46 | expect(Logstash.upstart_supports_user?(node)).to eql(false) 47 | end 48 | end 49 | end 50 | 51 | describe '::determine_native_init' do 52 | context 'with ubuntu' do 53 | context 'before upstart' do 54 | let(:node) { { 'platform' => 'ubuntu', 'platform_version' => '6.04' } } 55 | it 'returns sysvinit' do 56 | expect(Logstash.determine_native_init(node)).to eql('sysvinit') 57 | end 58 | end 59 | context 'after upstart' do 60 | let(:node) { { 'platform' => 'ubuntu', 'platform_version' => '6.10' } } 61 | it 'returns upstart' do 62 | expect(Logstash.determine_native_init(node)).to eql('upstart') 63 | end 64 | end 65 | end 66 | 67 | context 'with debian' do 68 | let(:node) { { 'platform' => 'debian', 'platform_version' => '7.6' } } 69 | it 'returns sysvinit' do 70 | expect(Logstash.determine_native_init(node)).to eql('sysvinit') 71 | end 72 | end 73 | 74 | context 'with el' do 75 | context 'with 5' do 76 | let(:node) { { 'platform' => 'centos', 'platform_version' => '5' } } 77 | it 'returns sysvinit' do 78 | expect(Logstash.determine_native_init(node)).to eql('sysvinit') 79 | end 80 | end 81 | context 'with 6' do 82 | let(:node) { { 'platform' => 'centos', 'platform_version' => '6' } } 83 | it 'returns sysvinit' do 84 | expect(Logstash.determine_native_init(node)).to eql('sysvinit') 85 | end 86 | end 87 | context 'with 7' do 88 | let(:node) { { 'platform' => 'centos', 'platform_version' => '7' } } 89 | it 'returns systemd' do 90 | expect(Logstash.determine_native_init(node)).to eql('systemd') 91 | end 92 | end 93 | end 94 | 95 | context 'with amazon' do 96 | context 'before upstart' do 97 | let(:node) { { 'platform' => 'amazon', 'platform_version' => '2010.11' } } 98 | it 'returns sysvinit' do 99 | expect(Logstash.determine_native_init(node)).to eql('sysvinit') 100 | end 101 | end 102 | context 'after upstart' do 103 | let(:node) { { 'platform' => 'amazon', 'platform_version' => '2011.02' } } 104 | it 'returns upstart' do 105 | expect(Logstash.determine_native_init(node)).to eql('upstart') 106 | end 107 | end 108 | end 109 | 110 | context 'with fedora' do 111 | context 'before systemd' do 112 | let(:node) { { 'platform' => 'fedora', 'platform_version' => '14' } } 113 | it 'returns sysvinit' do 114 | expect(Logstash.determine_native_init(node)).to eql('sysvinit') 115 | end 116 | end 117 | context 'after systemd' do 118 | let(:node) { { 'platform' => 'fedora', 'platform_version' => '15' } } 119 | it 'returns systemd' do 120 | expect(Logstash.determine_native_init(node)).to eql('systemd') 121 | end 122 | end 123 | end 124 | end 125 | --------------------------------------------------------------------------------