crash_analysis 0.1.5 → 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/bin/crash_analysis +1 -1
- data/lib/crash_analysis.rb +76 -94
- data/lib/crash_analysis/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8cacc9eba88eac17c2e429f8895fecda7632bb2e
|
4
|
+
data.tar.gz: 05bfacc7cc22340badf9b536c1bfdfba2a4b0c33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b7b2c700cef929c5aa098de5441a514482270b4e6784f36de0729bc199d631c680fc8f2500ebfc0b5e4aaa83f25d3f24269fe3c49c5dbfe4b4e1471ba08ab34
|
7
|
+
data.tar.gz: ff3d803826d727c031b399a340b5462140f4944d8b6e5a3e519e1cec0cdcf8d14b630fa3b38944be801700c574d1164abed220d3da2f49d1ae10257df1ba7863
|
data/bin/crash_analysis
CHANGED
data/lib/crash_analysis.rb
CHANGED
@@ -1,127 +1,109 @@
|
|
1
1
|
require "crash_analysis/version"
|
2
2
|
|
3
|
-
# Utils
|
4
|
-
class Array
|
5
|
-
def prog_each(&block)
|
6
|
-
bar_length = (`tput cols` || 80).to_i - 30
|
7
|
-
time_now = Time.now
|
8
|
-
total = self.count
|
9
|
-
last_flush = 0
|
10
|
-
flush_time = 1
|
11
|
-
self.each_with_index{|element, x|
|
12
|
-
cur = (x + 1) * 100 / total
|
13
|
-
time_left = (((Time.now - time_now) * (100 - cur)).to_f / cur).ceil
|
14
|
-
if (Time.now - last_flush).to_i >= flush_time or time_left < 1
|
15
|
-
time_left_graceful = Time.at(time_left).utc.strftime("%H:%M:%S")
|
16
|
-
if time_left > 86400
|
17
|
-
time_left_graceful = res.split(":")
|
18
|
-
time_left_graceful[0] = (time_left_graceful[0].to_i + days * 24).to_s
|
19
|
-
time_left_graceful = time_left_graceful.join(":")
|
20
|
-
end
|
21
|
-
print "\r"
|
22
|
-
cur_len = (bar_length * (x + 1)) / total
|
23
|
-
print "[" << (["#"] * cur_len).join << (["-"] * (bar_length - cur_len)).join << "] #{cur}% [#{time_left_graceful} left]"
|
24
|
-
last_flush = Time.now
|
25
|
-
end
|
26
|
-
block.call element if block
|
27
|
-
}
|
28
|
-
puts "\n"
|
29
|
-
"Done."
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
3
|
# Main
|
34
4
|
module CrashAnalysis
|
35
|
-
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
|
5
|
+
|
6
|
+
def initialize()
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.run()
|
10
|
+
puts "input logs_dir_path: "
|
11
|
+
logs_dir_path = gets.chomp
|
12
|
+
if logs_dir_path.empty? || logs_dir_path.nil? || !File.directory?(logs_dir_path)
|
13
|
+
puts "invalid logs_dir_path"
|
14
|
+
return
|
15
|
+
end
|
16
|
+
puts "input log_file_suffix(log, crash, txt etc.): "
|
17
|
+
log_file_suffix = gets.chomp
|
18
|
+
if log_file_suffix.empty? || log_file_suffix.nil?
|
19
|
+
puts "invalid log_file_suffix"
|
20
|
+
return
|
21
|
+
end
|
22
|
+
|
23
|
+
puts "init settings..."
|
24
|
+
output = []
|
25
|
+
r, io = IO.pipe
|
26
|
+
fork do
|
27
|
+
system("find /Applications/Xcode.app -name symbolicatecrash -type f", out: io, err: :out)
|
28
|
+
end
|
29
|
+
io.close
|
30
|
+
r.each_line{|l| puts l; output << l.chomp}
|
31
|
+
symbolicatecrash_path = output[0]
|
32
|
+
|
33
|
+
puts "running..."
|
34
|
+
analysis = Analysis.new()
|
35
|
+
analysis.run(logs_dir_path, log_file_suffix, symbolicatecrash_path)
|
36
|
+
|
40
37
|
end
|
41
38
|
|
42
39
|
class Analysis
|
43
40
|
|
44
41
|
def initialize()
|
45
|
-
@
|
42
|
+
@dSYM_file_name = ""
|
46
43
|
end
|
47
44
|
|
48
|
-
def run(
|
49
|
-
|
50
|
-
|
51
|
-
return
|
52
|
-
end
|
53
|
-
if filePath.nil? || filePath.empty?
|
54
|
-
puts "error: need directory path"
|
55
|
-
else
|
56
|
-
if File.directory?(filePath)
|
57
|
-
crashFileNames = traverse(filePath, rawFileSuffix)
|
58
|
-
if crashFileNames.nil? || crashFileNames.empty?
|
59
|
-
return
|
60
|
-
else
|
61
|
-
AnalysisLog(crashFileNames, rawFileSuffix, filePath)
|
62
|
-
end
|
63
|
-
else
|
64
|
-
puts "error: not a directory"
|
65
|
-
end
|
66
|
-
end
|
45
|
+
def run(logs_dir_path, log_file_suffix, symbolicatecrash_path)
|
46
|
+
crash_files = traverse(logs_dir_path, log_file_suffix)
|
47
|
+
analysis_action(crash_files, log_file_suffix, logs_dir_path, symbolicatecrash_path)
|
67
48
|
end
|
68
49
|
|
69
|
-
def traverse(
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
Dir.foreach(
|
75
|
-
|
76
|
-
if
|
77
|
-
|
78
|
-
|
50
|
+
def traverse(logs_dir_path, log_file_suffix)
|
51
|
+
crash_files = Array.new
|
52
|
+
count_app = 0
|
53
|
+
count_dSYM = 0
|
54
|
+
|
55
|
+
Dir.foreach(logs_dir_path) do |file|
|
56
|
+
file_suffix_array = file.strip.split(".")
|
57
|
+
if file_suffix_array.last == log_file_suffix
|
58
|
+
file_suffix_array.pop
|
59
|
+
crash_files << (file)
|
79
60
|
end
|
80
|
-
if
|
81
|
-
|
61
|
+
if file_suffix_array.last == "app"
|
62
|
+
count_app += 1
|
82
63
|
end
|
83
|
-
if
|
84
|
-
|
64
|
+
if file_suffix_array.last == "dSYM"
|
65
|
+
@dSYM_file_name = file
|
66
|
+
count_dSYM += 1
|
85
67
|
end
|
86
68
|
end
|
87
|
-
else
|
88
|
-
puts "Files:" + filePath
|
89
|
-
end
|
90
69
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
70
|
+
if count_app != 1 || count_dSYM !=1 || crash_files.count < 1
|
71
|
+
puts "error:\n"
|
72
|
+
puts "make sure the directory contains those files: 1 .app file & 1 .dSYM file & related crash files"
|
73
|
+
return
|
74
|
+
end
|
75
|
+
return crash_files
|
95
76
|
end
|
96
77
|
|
97
|
-
|
98
|
-
end
|
99
|
-
|
100
|
-
def AnalysisLog(crashFileNames, rawFileSuffix, filePath)
|
101
|
-
cmd = "/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash"
|
78
|
+
def analysis_action(crash_files, log_file_suffix, logs_dir_path, symbolicatecrash_path)
|
102
79
|
evn = "export DEVELOPER_DIR='/Applications/XCode.app/Contents/Developer'"
|
103
|
-
|
104
|
-
|
105
|
-
if !File.directory?(
|
106
|
-
Dir.mkdir(
|
80
|
+
output_log_dir = logs_dir_path + "/crash_logs"
|
81
|
+
percent_count = 0
|
82
|
+
if !File.directory?(output_log_dir)
|
83
|
+
Dir.mkdir(output_log_dir)
|
107
84
|
end
|
108
85
|
|
109
|
-
for
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
86
|
+
for file in crash_files
|
87
|
+
running_thread = Thread.new do
|
88
|
+
short_file_name = file.split("/").last
|
89
|
+
|
90
|
+
output_file = output_log_dir + "/" + short_file_name
|
91
|
+
current_log_file = logs_dir_path + "/" + file
|
92
|
+
system("#{evn} \n #{symbolicatecrash_path} #{current_log_file} #{@dSYM_file_name} > #{output_file}")
|
93
|
+
|
94
|
+
percent_count = percent_count + 1
|
95
|
+
precent = ((percent_count.to_f / crash_files.count.to_f) * 10000).round / 10000.0
|
116
96
|
str = (precent * 100).to_s
|
117
|
-
|
97
|
+
puts "#{str[0,4]}% || analyzing file: #{file}"
|
118
98
|
Thread.main.wakeup
|
119
99
|
end
|
120
100
|
# Maximum run for 10 seconds
|
121
101
|
sleep 10
|
122
|
-
Thread.kill(
|
102
|
+
Thread.kill(running_thread)
|
123
103
|
end
|
124
104
|
puts "\n Done."
|
125
105
|
end
|
106
|
+
|
126
107
|
end
|
108
|
+
|
127
109
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crash_analysis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- HongliYu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|