jvm_gclog 0.0.1 → 0.0.2
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/README.md +56 -0
- data/jvm_gclog.gemspec +1 -1
- data/lib/jvm_gclog.rb +108 -23
- data/spec/jvm_gclog_spec.rb +79 -0
- 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: af1757a6f5938408f6f77480466aae937e7f913a
|
4
|
+
data.tar.gz: 63f7d8b2470e1ab70fa736fe818b624aaa3e4afe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8deb0a34991092f8edbb4a06f32c8b7f50b03ccc76fc3d8cc69f876cb66d45eeed645ca5df284133e0f18043c6fe4cb5776ceee1082992834514e1175b0f66f1
|
7
|
+
data.tar.gz: 7d0e3246ac4cbb6efe6cae18b612b37a293280b988b5afaab12d1748d52a57b167753d1c6451906782af8bcba99f7aaaa25ea3bb067747f507fe41a9d40a7606
|
data/README.md
CHANGED
@@ -19,3 +19,59 @@ record = {
|
|
19
19
|
"gctime_sys"=> 0.00,
|
20
20
|
"gctime_real" => 0.69,
|
21
21
|
}
|
22
|
+
```
|
23
|
+
|
24
|
+
## Support options
|
25
|
+
|
26
|
+
### java 1.8 G1GC
|
27
|
+
```
|
28
|
+
% java -version
|
29
|
+
java version "1.8.0_40"
|
30
|
+
Java(TM) SE Runtime Environment (build 1.8.0_40-b25)
|
31
|
+
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)
|
32
|
+
```
|
33
|
+
|
34
|
+
```
|
35
|
+
-XX:+PrintGCDetails
|
36
|
+
-XX:+PrintGCTimeStamps
|
37
|
+
-XX:+PrintTenuringDistribution
|
38
|
+
-XX:+PrintGCApplicationStoppedTime
|
39
|
+
-XX:+DisableExplicitGC
|
40
|
+
-XX:+PrintGCDetails
|
41
|
+
-XX:+PrintGCDateStamps
|
42
|
+
-XX:+UseG1GC
|
43
|
+
```
|
44
|
+
|
45
|
+
### java 1.7 CMS
|
46
|
+
```
|
47
|
+
% java -version
|
48
|
+
java version "1.7.0_65"
|
49
|
+
Java(TM) SE Runtime Environment (build 1.7.0_65-b17)
|
50
|
+
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
|
51
|
+
```
|
52
|
+
|
53
|
+
```
|
54
|
+
-XX:+UseConcMarkSweepGC
|
55
|
+
-XX:+CMSIncrementalMode
|
56
|
+
-XX:+PrintGCDetails
|
57
|
+
-XX:+PrintGCDateStamps
|
58
|
+
-XX:+UseGCLogFileRotation
|
59
|
+
-XX:NumberOfGCLogFiles=5
|
60
|
+
-XX:GCLogFileSize=10M
|
61
|
+
```
|
62
|
+
|
63
|
+
### java 1.7 default
|
64
|
+
```
|
65
|
+
% java -version
|
66
|
+
java version "1.7.0_65"
|
67
|
+
Java(TM) SE Runtime Environment (build 1.7.0_65-b17)
|
68
|
+
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
|
69
|
+
```
|
70
|
+
|
71
|
+
```
|
72
|
+
-XX:+PrintGCDetails
|
73
|
+
-XX:+PrintGCDateStamps
|
74
|
+
-XX:+UseGCLogFileRotation
|
75
|
+
-XX:NumberOfGCLogFiles=5
|
76
|
+
-XX:GCLogFileSize=10M
|
77
|
+
```
|
data/jvm_gclog.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |gem|
|
|
12
12
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
13
13
|
gem.name = "jvm_gclog"
|
14
14
|
gem.require_paths = ["lib"]
|
15
|
-
gem.version = "0.0.
|
15
|
+
gem.version = "0.0.2"
|
16
16
|
gem.add_development_dependency "rspec"
|
17
17
|
gem.add_development_dependency "rake"
|
18
18
|
end
|
data/lib/jvm_gclog.rb
CHANGED
@@ -1,59 +1,144 @@
|
|
1
1
|
require 'time'
|
2
2
|
|
3
3
|
class JVMGCLog
|
4
|
+
def initialize
|
5
|
+
@regexp_prefix = Regexp.compile('^(?<time>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d{4}): (?<uptime>\d+\.\d*): ')
|
6
|
+
end
|
7
|
+
|
4
8
|
def adjust_type(value)
|
5
9
|
if value =~ /^\d+\.\d+$/
|
6
10
|
return value.to_f
|
7
|
-
|
11
|
+
elsif value =~ /^\d+$/
|
8
12
|
return value.to_i
|
9
13
|
end
|
14
|
+
value
|
15
|
+
end
|
16
|
+
|
17
|
+
def match_fields_to_hash(m)
|
18
|
+
record = {}
|
19
|
+
if m == nil
|
20
|
+
return nil
|
21
|
+
else
|
22
|
+
m.names.each {|name|
|
23
|
+
record[name] = adjust_type(m[name])
|
24
|
+
}
|
25
|
+
end
|
26
|
+
record
|
10
27
|
end
|
11
28
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
29
|
+
def recognize_chunks(lines)
|
30
|
+
chunks = []
|
31
|
+
|
32
|
+
line = lines.shift
|
33
|
+
while line
|
34
|
+
chunk = []
|
35
|
+
|
36
|
+
if line != nil && @regexp_prefix.match(line)
|
37
|
+
chunk << line.strip
|
38
|
+
line = lines.shift
|
39
|
+
end
|
40
|
+
|
41
|
+
details = []
|
42
|
+
while line != nil && !@regexp_prefix.match(line)
|
43
|
+
chunk << line.strip
|
44
|
+
line = lines.shift
|
45
|
+
end
|
46
|
+
|
47
|
+
chunks << chunk
|
48
|
+
end
|
49
|
+
|
50
|
+
chunks
|
51
|
+
end
|
52
|
+
|
53
|
+
def parse_chunks(chunks)
|
54
|
+
res = []
|
55
|
+
while (chunk = chunks.shift) != nil
|
56
|
+
res.push parse(chunk)
|
57
|
+
end
|
58
|
+
res.compact
|
59
|
+
end
|
60
|
+
|
61
|
+
def parse(data)
|
62
|
+
if data.class == String
|
63
|
+
data = [data]
|
64
|
+
end
|
65
|
+
record = {}
|
66
|
+
m = @regexp_prefix.match(data[0])
|
67
|
+
body = $'
|
68
|
+
unless m
|
69
|
+
record["type"] = "Unknown"
|
70
|
+
record["unknown"] = data.join(" ")
|
71
|
+
return record
|
72
|
+
end
|
73
|
+
|
15
74
|
record["time"] = Time.parse(m[:time]).to_i
|
16
75
|
record["uptime"] = adjust_type(m["uptime"])
|
17
|
-
|
18
|
-
post_times = m[:body].match(/ \[Times: user=(?<gctime_user>[\d\.]+) sys=(?<gctime_sys>[\d\.]+), real=(?<gctime_real>[\d\.]+) secs\] *$/)
|
19
|
-
if post_times
|
20
|
-
post_times.names.each {|name|
|
21
|
-
record[name] = adjust_type(post_times[name])
|
22
|
-
}
|
23
|
-
end
|
24
|
-
body = $` || m[:body]
|
25
76
|
|
26
77
|
case body
|
78
|
+
when /^\[GC pause/
|
79
|
+
line = data.join(" ")
|
80
|
+
fields = [
|
81
|
+
/\[GC Worker Total \(ms\): (?<gctime_total>\d+\.\d+)/,
|
82
|
+
/\[Eden: (?<eden_before>\d+\.\d+.)\((?<eden_total_before>\d+\.\d+.)\)->(?<eden_after>\d+\.\d+.)\((?<eden_total_after>\d+\.\d+.)\) Survivors: (?<survivors_before>\d+\.\d+.)->(?<survivors_after>\d+\.\d+.) Heap: (?<heap_before>\d+\.\d+.)\((?<heap_total_before>\d+\.\d+.)\)->(?<heap_after>\d+\.\d+.)\((?<heap_total_after>\d+\.\d+.)\)\]/,
|
83
|
+
/\[Times: user=(?<gctime_user>[\d\.]+) sys=(?<gctime_sys>[\d\.]+), real=(?<gctime_real>[\d\.]+) secs\]/
|
84
|
+
]
|
85
|
+
fields.each { |f|
|
86
|
+
if fields_match = f.match(line)
|
87
|
+
fields_match.names.each {|name|
|
88
|
+
record[name] = adjust_type(fields_match[name])
|
89
|
+
}
|
90
|
+
end
|
91
|
+
}
|
92
|
+
record["type"] = "G1GC"
|
93
|
+
return record
|
94
|
+
|
95
|
+
when /^Total time for which application threads were stopped/
|
96
|
+
# ignore this kind of line.
|
97
|
+
return nil
|
98
|
+
|
27
99
|
when /^\[GC.+ParNew: (?<new_before>\d+)K-\>(?<new_after>\d+)K\((?<new_total>\d+)K\), (?<new_gctime>[\d\.]+) secs\] (?<heap_before>\d+)K\-\>(?<heap_after>\d+)K\((?<heap_total>\d+)K\)( icms_dc=(?<icms_dc>\d+) )?, (?<gctime>[\d\.]+) secs\]/
|
28
100
|
m = Regexp.last_match
|
101
|
+
record.update(match_fields_to_hash(m))
|
102
|
+
record["type"] = "YoungGC"
|
103
|
+
|
104
|
+
when /^\[GC \[PSYoungGen: (?<new_before>\d+)K-\>(?<new_after>\d+)K\((?<new_total>\d+)K\)\] (?<heap_before>\d+)K\-\>(?<heap_after>\d+)K\((?<heap_total>\d+)K\), (?<gctime>[\d\.]+) secs\]/
|
105
|
+
m = Regexp.last_match
|
106
|
+
record.update(match_fields_to_hash(m))
|
29
107
|
record["type"] = "YoungGC"
|
108
|
+
|
30
109
|
when /^\[GC \[1 CMS-initial-mark: (?<old_before>\d+)K\((?<old_threshold>\d+)K\)\] (?<heap_before>\d+)K\((?<heap_total>\d+)K\), (?<gctime>[\d\.]+) secs\]/
|
31
110
|
m = Regexp.last_match
|
111
|
+
record.update(match_fields_to_hash(m))
|
32
112
|
record["type"] = "CMS-initial-mark"
|
113
|
+
|
33
114
|
when /^\[GC\[YG occupancy: (?<new_before>\d+) K \((?<new_threshold>\d+) K\)\].+\[1 CMS-remark: (?<old_before>\d+)K\((?<old_threshold>\d+)K\)\] (?<heap_before>\d+)K\((?<heap_total>\d+)K\), (?<gctime>[\d\.]+) secs\]/
|
34
115
|
m = Regexp.last_match
|
116
|
+
record.update(match_fields_to_hash(m))
|
35
117
|
record["type"] = "CMS-parallel-remark"
|
118
|
+
|
36
119
|
when /\[Full GC.+\(concurrent mode failure\).+ (?<gctime>[\d\.]+) secs\]/
|
37
120
|
m = Regexp.last_match
|
121
|
+
record.update(match_fields_to_hash(m))
|
38
122
|
record["type"] = "FullGC-CMS-failure"
|
123
|
+
|
39
124
|
when /\[Full GC.+ (?<gctime>[\d\.]+) secs\]/
|
40
125
|
m = Regexp.last_match
|
126
|
+
record.update(match_fields_to_hash(m))
|
41
127
|
record["type"] = "FullGC"
|
128
|
+
|
42
129
|
when /^\[(?<type>[A-Za-z\-]+)(: (?<time_cpu>[\d\.]+)\/(?<time_wall>[\d\.]+) secs)?\]/
|
43
130
|
m = Regexp.last_match
|
44
|
-
|
45
|
-
|
46
|
-
if m == nil
|
47
|
-
record["unknown"] = body
|
131
|
+
record.update(match_fields_to_hash(m))
|
132
|
+
|
48
133
|
else
|
49
|
-
|
50
|
-
|
51
|
-
record[name] = m[name]
|
52
|
-
elsif m[name]
|
53
|
-
record[name] = adjust_type(m[name])
|
54
|
-
end
|
55
|
-
}
|
134
|
+
record["type"] = "Unknown"
|
135
|
+
record["unknown"] = body
|
56
136
|
end
|
137
|
+
|
138
|
+
if m = $'.match('\[Times: user=(?<gctime_user>[\d\.]+) sys=(?<gctime_sys>[\d\.]+), real=(?<gctime_real>[\d\.]+) secs\]')
|
139
|
+
record.update(match_fields_to_hash(m))
|
140
|
+
end
|
141
|
+
|
57
142
|
return record
|
58
143
|
end
|
59
144
|
end
|
data/spec/jvm_gclog_spec.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
require "spec_helper"
|
4
|
+
require "pp"
|
4
5
|
|
5
6
|
describe "JVMGCLog" do
|
6
7
|
before :each do
|
@@ -33,6 +34,28 @@ describe "JVMGCLog" do
|
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
37
|
+
describe "PSYoungGC" do
|
38
|
+
before :each do
|
39
|
+
@line = "2015-06-09T14:07:53.277+0900: 85.918: [GC [PSYoungGen: 1341440K->8288K(1363968K)] 1369721K->39174K(4160512K), 0.0181530 secs] [Times: user=0.08 sys=0.01, real=0.02 secs] "
|
40
|
+
@r = @jvmgclog.parse(@line)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should have expected values" do
|
44
|
+
expect(@r["time"]).to eq 1433826473
|
45
|
+
expect(@r["type"]).to eq "YoungGC"
|
46
|
+
expect(@r["uptime"]).to eq 85.918
|
47
|
+
expect(@r["new_before"]).to eq 1341440
|
48
|
+
expect(@r["new_after"]).to eq 8288
|
49
|
+
expect(@r["new_total"]).to eq 1363968
|
50
|
+
expect(@r["heap_before"]).to eq 1369721
|
51
|
+
expect(@r["heap_after"]).to eq 39174
|
52
|
+
expect(@r["heap_total"]).to eq 4160512
|
53
|
+
expect(@r["gctime_user"]).to eq 0.08
|
54
|
+
expect(@r["gctime_sys"]).to eq 0.01
|
55
|
+
expect(@r["gctime_real"]).to eq 0.02
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
36
59
|
describe "CMS-initial-mark" do
|
37
60
|
before :each do
|
38
61
|
@line = "2015-06-05T13:15:27.747+0900: 44.239: [GC [1 CMS-initial-mark: 0K(3086784K)] 445450K(4083584K), 0.0298540 secs] [Times: user=0.04 sys=0.00, real=0.04 secs] "
|
@@ -154,6 +177,62 @@ describe "JVMGCLog" do
|
|
154
177
|
expect(@r["gctime_real"]).to eq 0.02
|
155
178
|
end
|
156
179
|
end
|
180
|
+
|
181
|
+
describe "G1GC-gc-logs" do
|
182
|
+
before :each do
|
183
|
+
@lines = <<-EOS
|
184
|
+
2015-06-08T08:50:09.784+0900: 3836239.602: Total time for which application threads were stopped: 0.0001872 seconds, Stopping threads took: 0.0000284 seconds
|
185
|
+
2015-06-08T08:50:35.705+0900: 3836265.524: [GC pause (G1 Evacuation Pause) (young)
|
186
|
+
Desired survivor size 20447232 bytes, new threshold 15 (max 15)
|
187
|
+
- age 1: 1151320 bytes, 1151320 total
|
188
|
+
- age 2: 235344 bytes, 1386664 total
|
189
|
+
- age 3: 144 bytes, 1386808 total
|
190
|
+
- age 4: 24 bytes, 1386832 total
|
191
|
+
- age 5: 24 bytes, 1386856 total
|
192
|
+
- age 6: 24 bytes, 1386880 total
|
193
|
+
- age 9: 336 bytes, 1387216 total
|
194
|
+
- age 11: 264 bytes, 1387480 total
|
195
|
+
, 0.0042488 secs]
|
196
|
+
[Parallel Time: 3.7 ms, GC Workers: 1]
|
197
|
+
[GC Worker Start (ms): 3836265523.9]
|
198
|
+
[Ext Root Scanning (ms): 1.6]
|
199
|
+
[Update RS (ms): 0.5]
|
200
|
+
[Processed Buffers: 19]
|
201
|
+
[Scan RS (ms): 0.2]
|
202
|
+
[Code Root Scanning (ms): 0.0]
|
203
|
+
[Object Copy (ms): 1.4]
|
204
|
+
[Termination (ms): 0.0]
|
205
|
+
[GC Worker Other (ms): 0.0]
|
206
|
+
[GC Worker Total (ms): 3.7]
|
207
|
+
[GC Worker End (ms): 3836265527.6]
|
208
|
+
[Code Root Fixup: 0.0 ms]
|
209
|
+
[Code Root Purge: 0.0 ms]
|
210
|
+
[Clear CT: 0.1 ms]
|
211
|
+
[Other: 0.4 ms]
|
212
|
+
[Choose CSet: 0.0 ms]
|
213
|
+
[Ref Proc: 0.1 ms]
|
214
|
+
[Ref Enq: 0.0 ms]
|
215
|
+
[Redirty Cards: 0.0 ms]
|
216
|
+
[Humongous Reclaim: 0.0 ms]
|
217
|
+
[Free CSet: 0.1 ms]
|
218
|
+
[Eden: 305.0M(305.0M)->0.0B(304.0M) Survivors: 2048.0K->3072.0K Heap: 374.6M(512.0M)->70.6M(512.0M)]
|
219
|
+
[Times: user=0.01 sys=0.00, real=0.01 secs]
|
220
|
+
2015-06-08T08:50:35.710+0900: 3836265.528: Total time for which application threads were stopped: 0.0045965 seconds, Stopping threads took: 0.0000778 seconds
|
221
|
+
2015-06-08T08:50:39.132+0900: 3836268.951: Total time for which application threads were stopped: 0.0001548 seconds, Stopping threads took: 0.0000248 seconds
|
222
|
+
EOS
|
223
|
+
@records = @jvmgclog.recognize_chunks(@lines.split(/\n/))
|
224
|
+
@r = @jvmgclog.parse_chunks(@records)
|
225
|
+
end
|
226
|
+
|
227
|
+
it "should have expected values" do
|
228
|
+
expect(@r.length).to eq 1
|
229
|
+
expect(@r[0]["eden_before"]).to eq "305.0M"
|
230
|
+
expect(@r[0]["gctime_user"]).to eq 0.01
|
231
|
+
expect(@r[0]["gctime_sys"]).to eq 0.0
|
232
|
+
expect(@r[0]["gctime_real"]).to eq 0.01
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
157
236
|
|
158
237
|
end
|
159
238
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jvm_gclog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- stanaka
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|