kitchen_blame 0.1.0 → 0.2.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 +4 -4
- data/CHANGELOG.md +19 -0
- data/lib/kitchen_blame/cli.rb +6 -0
- data/lib/kitchen_blame/version.rb +1 -1
- data/lib/kitchen_blame.rb +31 -14
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 186f2029646cb8aa537f69f02a085cd6b68cda5d
|
4
|
+
data.tar.gz: 2a6d6dde0a425c33c5806a05b4790a9d7a457df6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42c193a5f13a2850cdde11b241a70469f0d9b265a3c14d6443635fd378714daeda813ca45acbb937ae1adca846dd28ed399dc8c5908340b1fd324d7bf730e6ed
|
7
|
+
data.tar.gz: 12a47ab2e5c96823be027a8749d84687b997e64e0786d27adbbf40c7a33240f10a06811c05f126931e85c026c8e36818d9a8599ba171d02cd3411025416cfe94
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
5
|
+
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
## [Unreleased]
|
8
|
+
|
9
|
+
## [0.2.0] - 2017-07-05
|
10
|
+
### Added
|
11
|
+
- version subcommand
|
12
|
+
### Changed
|
13
|
+
- Code cleanup
|
14
|
+
### Fixed
|
15
|
+
- Fixed defect in parsing kitchen logs with errors
|
16
|
+
|
17
|
+
## [0.1.0] - 2017-06-16
|
18
|
+
### Added
|
19
|
+
- Initial Release
|
data/lib/kitchen_blame/cli.rb
CHANGED
@@ -17,6 +17,7 @@ require 'thor'
|
|
17
17
|
require 'kitchen_blame'
|
18
18
|
|
19
19
|
module KitchenBlame
|
20
|
+
# Processes command line invocation
|
20
21
|
class CLI < Thor
|
21
22
|
desc 'create KEY LOG', 'Use ssh KEY to analyze create time in a test kitchen LOG'
|
22
23
|
def create(key, log)
|
@@ -32,5 +33,10 @@ module KitchenBlame
|
|
32
33
|
def duration(log)
|
33
34
|
KitchenBlame::Blame.analyze_duration(log)
|
34
35
|
end
|
36
|
+
|
37
|
+
desc 'version', 'Output kitchen blame version'
|
38
|
+
def version
|
39
|
+
puts "kitchen blame version: #{KitchenBlame::VERSION}"
|
40
|
+
end
|
35
41
|
end
|
36
42
|
end
|
data/lib/kitchen_blame.rb
CHANGED
@@ -18,6 +18,7 @@ require 'date'
|
|
18
18
|
require 'json'
|
19
19
|
|
20
20
|
module KitchenBlame
|
21
|
+
# Main class
|
21
22
|
class Blame
|
22
23
|
# Return the DateTime object from a regex match with a named capture of 'time'
|
23
24
|
def self.extract_time(match)
|
@@ -44,47 +45,63 @@ module KitchenBlame
|
|
44
45
|
end
|
45
46
|
|
46
47
|
def self.analyze_create(key_path, log)
|
47
|
-
|
48
|
-
|
49
|
-
create_time = extract_time(match_data)
|
50
|
-
ip = File.foreach(log).grep(/Attaching floating IP </).first[/\<(?<ip>.*)\>/, 'ip']
|
51
|
-
server_log_entries = `ssh -i #{key_path} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no vagrant@#{ip} 'sudo journalctl -o json --no-pager' 2>/dev/null`.split("\n")
|
52
|
-
server_log_entries = server_log_entries.map { |entry| JSON.parse(entry) }
|
53
|
-
boot_start = extract_syslog_time(server_log_entries.first)
|
54
|
-
create_duration = measure_duration(create_time, boot_start)
|
55
|
-
|
48
|
+
server_log_entries = server_log_entries(key_path, log)
|
49
|
+
create_duration = image_create(log, server_log_entries)
|
56
50
|
startup_finished_entry = server_log_entries.find { |entry| entry['MESSAGE'].include?('Startup finished') }
|
51
|
+
boot_start = extract_syslog_time(server_log_entries.first)
|
57
52
|
boot_finish = extract_syslog_time(startup_finished_entry)
|
58
53
|
boot_duration = measure_duration(boot_start, boot_finish)
|
59
|
-
puts "
|
54
|
+
puts "Image create took #{create_duration} seconds"
|
60
55
|
puts "Boot took #{boot_duration} seconds"
|
61
56
|
puts "Systemd timing: #{startup_finished_entry['MESSAGE']}"
|
62
57
|
end
|
63
58
|
|
59
|
+
def self.server_log_entries(key_path, log)
|
60
|
+
ip = File.foreach(log).grep(/Attaching floating IP </).first[/\<(?<ip>.*)\>/, 'ip']
|
61
|
+
server_log_entries = `ssh -i #{key_path} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no vagrant@#{ip} 'sudo journalctl -o json --no-pager' 2>/dev/null`.split("\n")
|
62
|
+
server_log_entries.map { |entry| JSON.parse(entry) }
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.image_create(log, server_log_entries)
|
66
|
+
boot_start = extract_syslog_time(server_log_entries.first)
|
67
|
+
create_line = File.foreach(log).grep(/Creating/).first
|
68
|
+
match_data = /.,\s\[(?<time>.*)\]\s+[^:]+:(?<log>.*)$/.match(create_line)
|
69
|
+
create_time = extract_time(match_data)
|
70
|
+
measure_duration(create_time, boot_start)
|
71
|
+
end
|
72
|
+
|
73
|
+
# rubocop:disable MethodLength
|
64
74
|
def self.analyze_recipe(log)
|
65
|
-
IO.readlines(log).grep(/Recipe:/).map do |line|
|
75
|
+
recipe_lines = IO.readlines(log).grep(/Recipe:/).map do |line|
|
66
76
|
match_data = /\[(?<time>.*)\].*Recipe:\s(?<recipe>.*)$/.match(line)
|
77
|
+
next unless match_data
|
67
78
|
time = extract_time(match_data)
|
68
79
|
recipe = match_data[:recipe]
|
69
80
|
{ recipe: recipe, time: time }
|
70
|
-
end
|
81
|
+
end
|
82
|
+
recipe_lines.compact.each_cons(2) do |pair|
|
71
83
|
recipe = pair.first[:recipe]
|
72
84
|
duration = measure_pair(pair)
|
73
85
|
puts "#{duration} seconds for recipe #{recipe}"
|
74
86
|
end
|
75
87
|
end
|
88
|
+
# rubocop:enable MethodLength
|
76
89
|
|
90
|
+
# rubocop:disable MethodLength
|
77
91
|
def self.analyze_duration(log)
|
78
|
-
IO.readlines(log).map do |line|
|
92
|
+
log_lines = IO.readlines(log).map do |line|
|
79
93
|
match_data = /.,\s\[(?<time>.*)\]\s+[^:]+:(?<log>.*)$/.match(line)
|
94
|
+
next unless match_data
|
80
95
|
time = extract_time(match_data)
|
81
96
|
log = match_data[:log]
|
82
97
|
{ log: log, time: time }
|
83
|
-
end
|
98
|
+
end
|
99
|
+
log_lines.compact.each_cons(2) do |pair|
|
84
100
|
log = pair.first[:log]
|
85
101
|
duration = measure_pair(pair)
|
86
102
|
puts "#{duration} seconds for entry #{log}"
|
87
103
|
end
|
88
104
|
end
|
105
|
+
# rubocop:enable MethodLength
|
89
106
|
end
|
90
107
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kitchen_blame
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian O'Connell
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-07-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -62,6 +62,7 @@ extensions: []
|
|
62
62
|
extra_rdoc_files: []
|
63
63
|
files:
|
64
64
|
- ".gitignore"
|
65
|
+
- CHANGELOG.md
|
65
66
|
- Gemfile
|
66
67
|
- LICENSE
|
67
68
|
- README.md
|
@@ -92,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
93
|
version: '0'
|
93
94
|
requirements: []
|
94
95
|
rubyforge_project:
|
95
|
-
rubygems_version: 2.6.
|
96
|
+
rubygems_version: 2.6.6
|
96
97
|
signing_key:
|
97
98
|
specification_version: 4
|
98
99
|
summary: Analyzes Test Kitchen logs to assist in optimizations.
|