riemann-bacula 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8259d6fb194ccf10cd5acb756a66b2a22e1f310ed75a081f54cadcf8f7e80e99
4
+ data.tar.gz: 7ea103923b9966074450861224946190f52cdabc766f0dcb2a4fd76f5f3c8de1
5
+ SHA512:
6
+ metadata.gz: c8dff17ef2cb421f7a799755247190edfdfe39242bd55a0ce9f268109f157b7a94acc138252ea0a3e20c00d7f8b9e9be9f212e5708a0ba5464087e1aa457fb25
7
+ data.tar.gz: 03b0c38ded3a57c297435ec6f16c1b766303eee451311b3c29c141d81b70d184ac616fe8f91171663a0f1b3cfbe753e439e1044123cf4fd5ee99d76f36a04633
@@ -0,0 +1,4 @@
1
+ # DO NOT EDIT THIS FILE!
2
+ # This file is managed by ModuleSync.
3
+
4
+ * @opus-codium/core
@@ -0,0 +1,51 @@
1
+ ---
2
+ name: CI
3
+
4
+ on:
5
+ push:
6
+ branches:
7
+ - main
8
+ pull_request:
9
+ branches:
10
+ - main
11
+
12
+ jobs:
13
+ rubocop:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v3
17
+ - name: Setup ruby
18
+ uses: ruby/setup-ruby@v1
19
+ with:
20
+ ruby-version: 3.0
21
+ bundler-cache: true
22
+ - name: Run static code analysis
23
+ run: bundle exec rubocop
24
+ unit:
25
+ runs-on: ubuntu-latest
26
+ needs: rubocop
27
+ strategy:
28
+ matrix:
29
+ ruby:
30
+ - "2.6"
31
+ - "2.7"
32
+ - "3.0"
33
+ - "3.1"
34
+ name: Ruby ${{ matrix.ruby }}
35
+ steps:
36
+ - uses: actions/checkout@v3
37
+ - name: Setup ruby
38
+ uses: ruby/setup-ruby@v1
39
+ with:
40
+ ruby-version: ${{ matrix.ruby }}
41
+ bundler-cache: true
42
+ - name: Run tests without uploading code coverage
43
+ if: ${{ matrix.ruby != '3.0' }}
44
+ run: bundle exec rake
45
+ - name: Run tests and upload coverage to Code Climate
46
+ if: ${{ matrix.ruby == '3.0' }}
47
+ uses: paambaati/codeclimate-action@v3.0.0
48
+ env:
49
+ CC_TEST_REPORTER_ID: ${{ secrets.CODECLIMATE_TOKEN }}
50
+ with:
51
+ coverageCommand: bundle exec rake
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ Gemfile.lock
2
+ spec/examples.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,40 @@
1
+ ---
2
+ AllCops:
3
+ TargetRubyVersion: '2.6'
4
+ AllowSymlinksInCacheRootDirectory: true
5
+ NewCops: enable
6
+ Exclude:
7
+ - vendor/bundle/**/*
8
+ require:
9
+ - rubocop-rake
10
+ - rubocop-rspec
11
+ Layout/HashAlignment:
12
+ EnforcedHashRocketStyle: table
13
+ Layout/LineLength:
14
+ Enabled: false
15
+ Metrics/AbcSize:
16
+ Enabled: false
17
+ Metrics/BlockLength:
18
+ Enabled: false
19
+ Metrics/ClassLength:
20
+ Enabled: false
21
+ Metrics/CyclomaticComplexity:
22
+ Enabled: false
23
+ Metrics/MethodLength:
24
+ Enabled: false
25
+ Metrics/ParameterLists:
26
+ Enabled: false
27
+ Metrics/PerceivedComplexity:
28
+ Enabled: false
29
+ RSpec/SubjectStub:
30
+ Enabled: false
31
+ Style/Documentation:
32
+ Enabled: false
33
+ Style/NumericLiterals:
34
+ Enabled: false
35
+ Style/TrailingCommaInArguments:
36
+ EnforcedStyleForMultiline: consistent_comma
37
+ Style/TrailingCommaInArrayLiteral:
38
+ EnforcedStyleForMultiline: consistent_comma
39
+ Style/TrailingCommaInHashLiteral:
40
+ EnforcedStyleForMultiline: consistent_comma
data/.simplecov ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ # vim:set syntax=ruby:
4
+
5
+ SimpleCov.start do
6
+ add_filter '/spec/'
7
+ end
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in riemann-tools.gemspec
6
+ gemspec
data/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # riemann-bacula
2
+
3
+ Submits bacula information to riemann.
4
+
5
+ ## Get started
6
+
7
+ ```
8
+ gem install riemann-bacula
9
+ ```
10
+
11
+ In your Bacula Director configuration, add a Message resource like this (the provided e-mail address is not used, we are just hacking around the mail destination which sends a full transcript to the MailCommand standard input):
12
+
13
+ ```
14
+ Messages {
15
+ Name = Standard
16
+ MailCommand = "riemann-bacula"
17
+ Mail = sysadmin@example.com = all, !skipped
18
+ }
19
+ ```
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'riemann/tools/bacula/version'
4
+
5
+ require 'bundler/gem_tasks'
6
+ require 'rspec/core/rake_task'
7
+
8
+ RSpec::Core::RakeTask.new(:spec)
9
+
10
+ task default: :spec
11
+
12
+ require 'github_changelog_generator/task'
13
+
14
+ GitHubChangelogGenerator::RakeTask.new :changelog do |config|
15
+ config.user = 'opus-codium'
16
+ config.project = 'riemann-bacula'
17
+ config.exclude_labels = ['skip-changelog']
18
+ config.future_release = Riemann::Tools::Bacula::VERSION
19
+ end
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ Process.setproctitle($PROGRAM_NAME)
5
+
6
+ require 'riemann/tools/bacula'
7
+
8
+ Riemann::Tools::Bacula.run
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Riemann
4
+ module Tools # :nodoc:
5
+ class Bacula
6
+ VERSION = '1.0.0'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,213 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'strscan'
4
+
5
+ require 'riemann/tools'
6
+
7
+ module Riemann
8
+ module Tools
9
+ class Bacula
10
+ include Riemann::Tools
11
+
12
+ opt :details, 'Send detailed metrics beyond overall status', default: true
13
+
14
+ def self.process_stdin
15
+ new.process_stdin
16
+ end
17
+
18
+ def run
19
+ options
20
+ data = parse($stdin.read)
21
+ send_events(data) if data
22
+ end
23
+
24
+ def parse(text)
25
+ data = {}
26
+
27
+ text.each_line do |line|
28
+ line.chomp!
29
+
30
+ next unless line =~ /\A ([^:]+):[[:blank:]]+(.*)/
31
+
32
+ key = Regexp.last_match(1)
33
+ raw_value = Regexp.last_match(2)
34
+
35
+ data[key] = raw_value
36
+ end
37
+
38
+ return nil unless valid?(data)
39
+
40
+ enhance(data)
41
+ end
42
+
43
+ def valid?(data)
44
+ %w[
45
+ Job
46
+ Termination
47
+ ].all? { |key| data.key?(key) }
48
+ end
49
+
50
+ def enhance(data)
51
+ {
52
+ parse_size: [
53
+ 'FD Bytes Written',
54
+ 'SD Bytes Written',
55
+ 'Last Volume Bytes',
56
+ ],
57
+ parse_integer: [
58
+ 'JobId',
59
+ 'Priority',
60
+ 'Non-fatal FD errors',
61
+ 'FD Files Written',
62
+ 'SD Files Written',
63
+ 'SD Errors',
64
+ 'Volume Session Id',
65
+ 'Volume Session Time',
66
+ ],
67
+ parse_duration: [
68
+ 'Elapsed time',
69
+ ],
70
+ parse_volumes: [
71
+ 'Volume name(s)',
72
+ ],
73
+ parse_rate: [
74
+ 'Rate',
75
+ ],
76
+ parse_ratio: [
77
+ 'Software Compression',
78
+ 'Comm Line Compression',
79
+ ],
80
+ }.each do |parser, keys|
81
+ keys.each do |key|
82
+ data[key] = send(parser, data[key]) if data[key]
83
+ end
84
+ end
85
+
86
+ extract_source('Pool', data)
87
+ extract_source('Catalog', data)
88
+ extract_source('Storage', data)
89
+
90
+ extract_time('FileSet', data)
91
+
92
+ extract_client_info(data)
93
+ extract_backup_level_info(data)
94
+ extract_job_name(data)
95
+
96
+ data
97
+ end
98
+
99
+ def extract_backup_level_info(data)
100
+ case data['Backup Level']
101
+ when /\A(Differential|Incremental), since=(.*)\z/
102
+ data['Backup Level'] = Regexp.last_match(1)
103
+ data['Backup Level Since'] = Regexp.last_match(2)
104
+ when /\A(Full) \(upgraded from (Differential|Incremental)\)\z/
105
+ data['Backup Level'] = Regexp.last_match(1)
106
+ data['Backup Level upgraded from'] = Regexp.last_match(2)
107
+ end
108
+ end
109
+
110
+ def extract_client_info(data)
111
+ /\A"([^"]+)" ([^ ]+)/.match(data['Client'])
112
+
113
+ data['Client'] = Regexp.last_match(1)
114
+ data['Client Version'] = Regexp.last_match(2)
115
+ end
116
+
117
+ def extract_job_name(data)
118
+ data['Job Name'] = data['Job'].sub(/\.\d{4}-\d{2}-\d{2}_\d{2}\.\d{2}\.\d{2}_\d{2}\z/, '')
119
+ end
120
+
121
+ def extract_source(item, data)
122
+ /\A"([^"]+)" \(From (Client|Job|Pool) resource\)\z/.match(data[item])
123
+
124
+ data[item] = Regexp.last_match(1)
125
+ data["#{item} Source"] = Regexp.last_match(2)
126
+ end
127
+
128
+ def extract_time(item, data)
129
+ /\A"([^"]+)" (.*)\z/.match(data[item])
130
+
131
+ data[item] = Regexp.last_match(1)
132
+ data["#{item} time"] = Regexp.last_match(2)
133
+ end
134
+
135
+ def parse_duration(duration)
136
+ s = StringScanner.new(duration)
137
+ res = 0
138
+
139
+ until s.eos?
140
+ case
141
+ when s.scan(/\s+/)
142
+ # ignore spaces
143
+ when s.scan(/(\d+) hours?/) then res += s[0].to_i * 3600
144
+ when s.scan(/(\d+) mins?/) then res += s[0].to_i * 60
145
+ when s.scan(/(\d+) secs?/) then res += s[0].to_i
146
+ else
147
+ return -1
148
+ end
149
+ end
150
+
151
+ res
152
+ end
153
+
154
+ def parse_integer(value)
155
+ value.gsub(',', '').to_i
156
+ end
157
+
158
+ def parse_rate(value)
159
+ %r{\A(\d+\.\d+) KB/s\z}.match(value)
160
+ Regexp.last_match(1).to_f
161
+ end
162
+
163
+ def parse_ratio(value)
164
+ return 0.0 if value == 'None'
165
+
166
+ /\A(\d+\.\d+)% \d+\.\d+:\d+\z/.match(value)
167
+ Regexp.last_match(1).to_f / 100
168
+ end
169
+
170
+ def parse_size(value)
171
+ /\A([\d,]+) \([\d.]+ [KMG]?B\)\z/.match(value)
172
+ parse_integer(Regexp.last_match(1))
173
+ end
174
+
175
+ def parse_volumes(value)
176
+ value.split('|')
177
+ end
178
+
179
+ def send_events(data)
180
+ event = {}
181
+ event[:service] = "bacula backup #{data['Job Name']}"
182
+ event[:state] = case data['Termination']
183
+ when 'Backup OK' then 'ok'
184
+ when 'Backup OK -- with warnings' then 'warning'
185
+ else
186
+ 'critical'
187
+ end
188
+ event[:description] = data['Termination']
189
+ report(event)
190
+
191
+ return unless options[:details]
192
+
193
+ [
194
+ 'Elapsed time',
195
+ 'FD Files Written',
196
+ 'SD Files Written',
197
+ 'FD Bytes Written',
198
+ 'SD Bytes Written',
199
+ 'SD Errors',
200
+ 'Rate',
201
+ 'Software Compression',
202
+ 'Comm Line Compression',
203
+ 'Non-fatal FD errors',
204
+ ].each do |metric|
205
+ event = {}
206
+ event[:service] = "bacula backup #{data['Job Name']} #{data['Backup Level'].downcase} #{metric.downcase}"
207
+ event[:metric] = data[metric]
208
+ report(event)
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/riemann/tools/bacula/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'riemann-bacula'
7
+ spec.version = Riemann::Tools::Bacula::VERSION
8
+ spec.authors = ['Romain Tartière']
9
+ spec.email = ['romain@blogreen.org']
10
+
11
+ spec.summary = 'Submits bacula information to riemann'
12
+ spec.homepage = 'https://github.com/opus-codium/riemann-bacula'
13
+ spec.license = 'MIT'
14
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.6.0')
15
+
16
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org/'
17
+
18
+ spec.metadata['homepage_uri'] = spec.homepage
19
+ spec.metadata['source_code_uri'] = spec.homepage
20
+ spec.metadata['changelog_uri'] = spec.homepage
21
+
22
+ spec.metadata['rubygems_mfa_required'] = 'true'
23
+
24
+ # Specify which files should be added to the gem when it is released.
25
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
26
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
27
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
28
+ end
29
+ spec.bindir = 'bin'
30
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
31
+ spec.require_paths = ['lib']
32
+
33
+ spec.add_runtime_dependency 'riemann-tools', '~> 1.0'
34
+
35
+ spec.add_development_dependency 'github_changelog_generator'
36
+ spec.add_development_dependency 'rake'
37
+ spec.add_development_dependency 'rspec'
38
+ spec.add_development_dependency 'rubocop'
39
+ spec.add_development_dependency 'rubocop-rake'
40
+ spec.add_development_dependency 'rubocop-rspec'
41
+ spec.add_development_dependency 'simplecov'
42
+ end
metadata ADDED
@@ -0,0 +1,174 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: riemann-bacula
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Romain Tartière
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-10-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: riemann-tools
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: github_changelog_generator
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop-rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: simplecov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description:
126
+ email:
127
+ - romain@blogreen.org
128
+ executables:
129
+ - riemann-bacula
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - ".github/CODEOWNERS"
134
+ - ".github/workflows/ci.yml"
135
+ - ".gitignore"
136
+ - ".rspec"
137
+ - ".rubocop.yml"
138
+ - ".simplecov"
139
+ - Gemfile
140
+ - README.md
141
+ - Rakefile
142
+ - bin/riemann-bacula
143
+ - lib/riemann/tools/bacula.rb
144
+ - lib/riemann/tools/bacula/version.rb
145
+ - riemann-bacula.gemspec
146
+ homepage: https://github.com/opus-codium/riemann-bacula
147
+ licenses:
148
+ - MIT
149
+ metadata:
150
+ allowed_push_host: https://rubygems.org/
151
+ homepage_uri: https://github.com/opus-codium/riemann-bacula
152
+ source_code_uri: https://github.com/opus-codium/riemann-bacula
153
+ changelog_uri: https://github.com/opus-codium/riemann-bacula
154
+ rubygems_mfa_required: 'true'
155
+ post_install_message:
156
+ rdoc_options: []
157
+ require_paths:
158
+ - lib
159
+ required_ruby_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - ">="
162
+ - !ruby/object:Gem::Version
163
+ version: 2.6.0
164
+ required_rubygems_version: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ">="
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ requirements: []
170
+ rubygems_version: 3.2.5
171
+ signing_key:
172
+ specification_version: 4
173
+ summary: Submits bacula information to riemann
174
+ test_files: []