My
previous blog post showed how to use R to perform Java GC log analysis. Ajit Joglekar asked that I post
the Clojure script. Here's the Clojure script that I used to convert GC log to CSV format.
I have not tested this with a wide variety of GC logs but I do know that this script will not work for CMS or G1GC gc logs.
Modify minor-gc-pattern and full-gc-pattern to match the gc log output as needed.
(use '[clojure.string :only (join)])
; Match for pause time "0.1566980 secs]"
(def ^:constant pause-time "([\\d\\.]+) secs\\]")
; Match for Java heap space stat "524288K->32124K(2009792K)"
(def ^:constant space "(\\d+)K->(\\d+)K\\((\\d+)K\\)")
; Match for Execution stat "[Times: user=0.24 sys=0.06, real=0.16 secs]"
(def ^:constant exec-stat " \\[Times: user=([\\d\\.]+) sys=([\\d\\.]+), real=([\\d\\.]+) secs\\]")
; Example Minor GC entry
; 212.785: [GC [PSYoungGen: 524288K->32124K(611648K)] 524288K->32124K(2009792K), 0.1566980 secs] [Times: user=0.24 sys=0.06, real=0.16 secs]
; Define regex pattern to parse young gen GC event
(defn minor-gc-pattern []
(let [timestamp "([\\d\\.]+): \\[GC .*\\[PS.*: "
young-gen (str space "] ")
heap (str space ", ")]
(re-pattern (str timestamp young-gen heap pause-time exec-stat))))
; Example Full GC entry
;"43587.513: [Full GC (System) [PSYoungGen: 964K->0K(598912K)] [PSOldGen: 142673K->120674K(1398144K)] 143637K->120674K(1997056K) [PSPermGen: 82179K->82179K(147520K)], 0.7556570 secs] [Times: user=0.76 sys=0.00, real=0.77 secs]"
; Define the regex pattern to parse each line in gc log
(defn full-gc-pattern []
(let [timestamp "([\\d\\.]+): \\[Full.*"
young-gen (str ": " space "]")
old-gen (str " \\[\\w+: " space "\\] ")
perm-gen (str " \\[\\w+: "space "\\], ")
heap space]
(re-pattern (str timestamp
young-gen
old-gen
heap
perm-gen
pause-time
exec-stat))))
; Variable definitions (for both process-full-gc & process-minor-gc
; ts - timestamp (in seconds)
; ys - YoungGen space starting heap size (in KB)
; ye - YoungGen space ending heap size (in KB)
; ym - YoungGen space max heap size (in KB)
; os - OldGen space starting heap size (in KB)
; oe - OldGen space ending heap size (in KB)
; om - OldGen space max heap size (in KB)
; hs - Total heap space starting heap size (in KB)
; he - Total heap space ending heap size (in KB)
; hm - Total heap space max heap size (in KB)
; pt - GC Pause Time (in seconds)
; ps - PermGen space starting heap size (in KB)
; pe - PermGen space ending heap size (in KB)
; pm - PermGen space max heap size (in KB)
; ut - User Time (in seconds)
; kt - Kernel Time (in seconds)
; rt - Real Time (in seconds)
(defn process-full-gc [entry]
(let [[a ts ys ye ym os oe om hs he hm ps pe pm pt ut kt rt & e] entry]
(join \, [ts "full" pt
ys ye ym
hs he hm
ut kt rt
os oe om
ps pe pm])))
(defn process-minor-gc [entry]
(let [[a ts ys ye ym hs he hm pt ut kt rt & e] entry]
(join \, [ts "minor" pt
ys ye ym
hs he hm
ut kt rt])))
(def headers (join \, ["timestamp" "gc.type" "pause.time"
"young.start" "young.end" "young.max"
"heap.start" "heap.end" "heap.max"
"time.user" "time.sys" "time.real"
"old.start" "old.end" "old.max"
"perm.start" "perm.end" "perm.max"]))
(defn process-gc-file [infile outfile]
(let [gcdata (line-seq (clojure.java.io/reader (clojure.java.io/file infile)))]
(with-open [w (clojure.java.io/writer outfile)]
(let [writeln (fn [x] (.write w (str x "\n")))]
(writeln headers)
(doseq [line gcdata]
(let [minor-gc (re-seq (minor-gc-pattern) line)
full-gc (re-seq (full-gc-pattern) line)]
(when-not (nil? full-gc)
(writeln (process-full-gc (first full-gc))))
(when-not (nil? minor-gc)
(writeln (process-minor-gc (first minor-gc))))))))))
;-----------------------------------------------------------------------
; Convert Java GC log csv format
;-----------------------------------------------------------------------
(process-gc-file "gc.log" "data.csv")
You can download the script directly here : gcanalysis.clj.
3 comments:
Great info. Thank you for sharing your technique. Looking forward for more updates.
Vicky
www.gofastek.com
For free gc log analysis, send the log file to performancetestexpert@gmail.com
Great post.
Java Classes in Pune
Post a Comment