Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
軽量デバッグツールPostmortemの紹介.pdf
Search
OHTA Shogo
September 26, 2019
Programming
210
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
軽量デバッグツールPostmortemの紹介.pdf
OHTA Shogo
September 26, 2019
More Decks by OHTA Shogo
See All by OHTA Shogo
テンクーでのClojure活用事例
athos
0
420
Clojure 1.10 概要紹介
athos
3
700
やってみる!clojure.spec
athos
4
1.1k
kitchen-async: a promising (?) Promise library, or a poor man's core.async
athos
3
510
Clojure 1.9 概要紹介
athos
4
1.5k
ここ最近のClojureScript
athos
5
1.8k
(= ? (+ nREPL Docker))
athos
0
590
clojure.specの話
athos
3
2.4k
clojure.specの話(仮)
athos
2
370
Other Decks in Programming
See All in Programming
壊れたパーサから始める関数型設計と構成的なパーサ #fp_matsuri
raiga0310
2
170
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
360
Hunting Vulnerabilities in Symfony with LLMs
vinceamstoutz
0
570
分散システム、なんですぐ死んでしまうん?耐障害性を高めたいあなたのためのレジリエンスパターン入門
mshibuya
7
3.8k
IBM Bobを活用したレガシーアプリの最新化
oniak3ibm
PRO
1
240
初めてのKubernetes 本番運用でハマった話
oku053
0
110
そのテスト、説明できますか?~LWテスト戦略FW~のご紹介
nakahara
0
200
技術記事、 専門家としてのプログラマ、 言語化
mizchi
14
7.3k
【SRE NEXT 2026 Lunch Session】一人目専任SREの立ち上げを加速する ― AIと進めたオンボーディングで2分を0.04秒にした話
pkshadeck
PRO
0
810
自作OSでスライド発表する
uyuki234
1
3.6k
1B+ /day規模のログを管理する技術
broadleaf
0
130
Haskell/Servantを通してWebミドルウェアを捉え直す
pizzacat83
0
400
Featured
See All Featured
RailsConf 2023
tenderlove
30
1.5k
AI: The stuff that nobody shows you
jnunemaker
PRO
8
770
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
270
エンジニアに許された特別な時間の終わり
watany
107
250k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
330
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
How GitHub (no longer) Works
holman
316
150k
Typedesign – Prime Four
hannesfritz
42
3.1k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
220
How to make the Groovebox
asonas
2
2.3k
Music & Morning Musume
bryan
47
7.3k
A Soul's Torment
seathinner
6
3k
Transcript
ܰྔσόοάπʔϧ 1PTUNPSUFNͷհ -JTQNFFUVQ !BUIPT
طଘͷओͳσόοάख๏ ‣ QSJOUσόοά QSOQSJOUMOΛૠೖ͠ɺͦͷ࣌ͷΛ֬ೝͨ͠Γͦͷίʔυ͕࣮ߦ͞Εͨ ͜ͱΛ֬ೝ͢Δ ૉ͕ͩखܰͳख๏ͰɺσόοΨ͕͑ͳ͍߹ʹ༗ޮͳ͜ͱଟ͍ ‣ τϨʔεػೳ
ؔݺͼग़͠ͷҾΓɺݺͼग़͠ͷਂ͞Λग़ྗ͢Δ UPPMTUSBDF$*%&3ͷτϨʔεػೳͱͯ͠ఏڙ͞ΕΔ ‣ σόοΨ ϒϨʔΫϙΠϯτΛઃఆͯ͠ϓϩάϥϜͷ࣮ߦΛఀࢭ͠ɺεςοϓ࣮ߦ ϩʔΧϧڥͷΠϯεϖΫτ͕Ͱ͖Δ ͖݅ͭͷϒϨʔΫϙΠϯτΛઃఆͯ݅͠Λຬͨ͢߹͚࣮ͩߦΛࢭΊΔ
طଘख๏͕ద༻ͮ͠Β͍έʔε ‣ ಉ͡ॲཧ͕ ϧʔϓ࠶ؼͰ Կ܁Γฦ࣮͠ߦ͞ΕΔ QSJOUσόοάτϨʔεػೳͷग़ྗ͕ଟ͘ͳΓɺॏཁͳग़ྗͷಛఆ͕͘͠ͳΔ ͖݅ͭϒϨʔΫϙΠϯτΛ͏·͘ઃఆ͠ͳ͍ͱԿͱؔͳ͍ճͷ܁Γ ฦ͠Ͱ࣮ߦ͕ࢭ·Δ
‣ ܁Γฦ͠ͷ݁Ռ͕ޙͷ܁Γฦ͠ʹӨڹΛ༩͑Δ ͕ى͖ΔԿճ͔લͷ܁Γฦ͕͠ͷݪҼʹͳΓ͏Δ ͕͋Δͱ͔Δ࣌Ͱ࣮ߦΛϒϨʔΫͯͦ͜͠ʹͷݪҼ͕ͳ͘ɺͦͷԿճ ͔લͷ܁Γฦ͠ͷঢ়ଶΛͲ͏ʹ͔ಛఆ͢Δඞཁ͕͋Δ ‣ ϚϧνεϨουͷॲཧ͕བྷΉͱ͞Βʹհ ‣ ྫ ࣌ؒܦաʹ͕͍ͨ͠ϦΞϧλΠϜʹঢ়ଶ͕มԽ͢Δͷ ήʔϜɺΞχϝʔγϣϯ ݴޠॲཧܥ ͱʹ͔͘ೖྗͷαΠζ͕େ͖͍ूॲཧ FUD
1PTUNPSUFN ‣ খ͞ͳσόοάࢧԉπʔϧ ‣ ࣮ߦதͷΛه͠ɺࣄޙݕূ͢ΔͨΊͷ༻్Ͱ͏ ‣ ϩάʹͲ͏͍͏ΛͲ͏ه͢Δ͔Λτϥϯεσϡʔαʹ ΑͬͯॊೈʹΧελϚΠζͰ͖Δ ‣ ݸผͷηογϣϯΛ࡞Δ͜ͱʹΑΓɺଞͷϩά͔Β
͞ΕͨϩάΛͱΔ͜ͱ͕Ͱ͖Δ
1PTUNPSUFNͷجຊతͳ͍ํ ‣ pm/saveݺͼग़͠ຖͷϩʔΧϧڥΛϚοϓͱͯ͠ه͢Δ ‣ pm/log-forࢦఆͨ͠ΩʔͰه͞ΕͨϩάΛฦ͢ (require '[postmortem.core :as pm])
(defn sum [n] (loop [n n sum 0] (pm/save :sum) (if (= n 0) sum (recur (dec n) (+ sum n))))) (sum 5) ;=> 15 (pm/log-for :sum) ;=> [{:n 5 :sum 0} {:n 4 :sum 5} {:n 3 :sum 9} {:n 2 :sum 12} {:n 1 :sum 14} {:n 0 :sum 15}]
1PTUNPSUFNͷجຊతͳ͍ํ ‣ pm/spy>>ݺͼग़͠ຖʹҾʹͨ͠Λه͢Δ ‣ pm/logsه͞Εͨͯ͢ͷϩάΛฦ͢ (require '[postmortem.core :as pm])
(defn sum [n] (loop [n n sum 0] (if (= n 0) sum (recur (dec n) (pm/spy>> :sum-val (+ sum n))))) (sum 5) ;=> 15 (pm/log-for :sum-val) ;=> [5 9 12 14 15] (pm/logs) ;=> {:sum [{:n 5 :sum 0} {:n 4 :sum 5} …] :sum-val [5 9 12 14 15]}
1PTUNPSUFNͷجຊతͳ͍ํ ‣ pm/log-for pm/logs ͰऔΓग़ͨ͠ϩάͷ݁Ռ pm/reset! ͰϦηοτ͢Δ·Ͱ্ॻ͖͞Εͳ͍ (require '[postmortem.core
:as pm]) (sum 100) ;=> 5050 (pm/log-for :sum-val) ;=> [5 9 12 14 15] (pm/logs) ;=> {:sum [{:n 5 :sum 0} {:n 4 :sum 5} …] :sum-val [5 9 12 14 15]} (pm/reset!) (pm/logs) ;=> {} (sum 3) ;=> 6 (pm/logs) ;=> {:sum [{:n 3 :sum 0} {:n 2 :sum 1} …] :sum-val [3 5 6]}
τϥϯεσϡʔαͱͷ࿈ܞ ‣ pm/save pm/spy>> τϥϯεσϡʔαΛΦϓγϣφϧ Ҿͱͯ͠औΕɺϩάΛͲ͏ه͢Δ͔ΛΧελϚΠζͰ͖Δ (require '[postmortem.core :as
pm]) (defn sum [n] (loop [n n sum 0] (pm/save :sum (filter #(even? (:n %)))) (if (= n 0) sum (recur (dec n) (+ sum n))))) (sum 5) ;=> 15 (pm/log-for :sum) ;=> [{:n 4 :sum 5} {:n 2 :sum 12} {:n 0 :sum 15}]
τϥϯεσϡʔαͱͷ࿈ܞ ‣ map-indexed Ͱ࿈൪ΛৼͬͨΓɺrandom-sample Ͱ ϥϯμϜαϯϓϦϯάΛͨ͠ΓͰ͖Δ (require '[postmortem.core :as
pm]) (defn sum [n] (loop [n n sum 0] (pm/save :sum (comp (map-indexed #(assoc %2 :id %1)) (random-sample 0.5)) (if (= n 0) sum (recur (dec n) (+ sum n))))) (sum 5) ;=> 15 (pm/log-for :sum) ;=> [{:n 5 :sum 0 :id 0} {:n 4 :sum 5 :id 1} {:n 1 :sum 14 :id 4}]
τϥϯεσϡʔαͱͷ࿈ܞ ‣ System/nanoTimeͰݺͼग़࣌͠ࠁΛ͚͓͍ͭͯͯɺxf/ debounceͰҰఆִؒͷ࣌ؒͷϩάΛؒҾ͘͜ͱͰ͖Δ (require '[postmortem.core :as pm] '[postmortem.xforms
:as xf]) (defn sum [n] (loop [n n sum 0] (pm/save :sum (comp (map #(assoc % :t (System/nanoTime))) (xf/debounce :t 10000)) (if (= n 0) sum (recur (dec n) (+ sum n))))) (sum 10) ;=> 55 (pm/log-for :sum) ;=> [{:n 10 :sum 0 :t 105365222743711} {:n 9 :sum 10 :t 105365222775129} {:n 7 :sum 27 :t 105365222789449} {:n 4 :sum 45 :t 105365222802184} {:n 1 :sum 54 :t 105365222813741}]
τϥϯεσϡʔαͱͷ࿈ܞ ‣ take-whileͰ݅Λຬͨؒ͢ͷϩά͚ͩΛͨ͠Γɺ xf/take-lastͰ࠷ޙͷ/ݸͷϩά͚ͩΛͨ͠ΓͰ͖Δ (require '[postmortem.core :as pm] '[postmortem.xforms
:as xf]) (defn sum [n] (loop [n n sum 0] (pm/save :sum (comp (take-while #(< (:sum %) 1000)) (xf/take-last 3)) (if (= n 0) sum (recur (dec n) (+ sum n))))) (sum 100) ;=> 5050 (pm/log-for :sum) ;=> [{:n 92 :sum 772} {:n 91 :sum 864} {:n 90 :sum 955}]
xf/take-lastͷ࣮ ‣ τϥϯεσϡʔαͭͷॲཧ͔ΒͳΔ ॳظԽॲཧεςοϓॲཧྃॲཧ ‣ xf/take-last εςοϓॲཧͰೖྗΛϦϯάόοϑΝʹ٧Ίͯɺ ྃॲཧͰόοϑΝʹ͍ͬͯΔཁૉΛʮ࠷ޙͷ/ݸʯͱͯ֬͠ఆ͢Δ (defn
take-last [^long n] (fn [rf] (let [idx (volatile! 0), vals (object-array n)] (fn ([] (rf)) ([result] (let [offset (if (>= @idx n) (long @idx) 0)] (transduce (map #(aget vals (rem (+ % offset) n))) rf result (range n)))) ([acc input] (aset vals (rem @idx n) input) (vswap! idx inc) acc))))) ॳظԽॲཧ ྃॲཧ εςοϓॲཧ
τϥϯεσϡʔαͷྃॲཧ͍ͭݺΕΔͷ͔ʁ (defn add [x y] (pm/save :add (comp (map (fn
[x] (prn [:pre x]) x)) (xf/take-last 3) (map (fn [x] (prn [:post x]) x)))) (+ x y)) (redue add 0 (range 5)) ;; [:pre {:x 0, :y 0}] ;; [:pre {:x 0, :y 1}] ;; [:pre {:x 1, :y 2}] ;; [:pre {:x 3, :y 3}] ;; [:pre {:x 6, :y 4}] ;=> 10 (pm/logs) ;; [:post {:x 1, :y 2}] ;; [:post {:x 3, :y 3}] ;; [:post {:x 6, :y 4}] ;=> {:add [{:x 1, :y 2} {:x 3, :y 3} {:x 6, :y 4}]} (pm/logs) ;=> {:add [{:x 1, :y 2} {:x 3, :y 3} {:x 6, :y 4}]}
τϥϯεσϡʔαͷྃॲཧ͍ͭݺΕΔͷ͔ʁ ‣ ϩάΛࢀরͱͨ͠લʹճ͚ͩྃॲཧ͕࣮ߦ͞ΕΔΑ ͏ʹͳ͍ͬͯΔ ‣ Ұ୴ྃॲཧΛͨ͠ϩάΛ͞Βʹߋ৽Ͱ͖ͯ͠·͏ͱΑ ͔͘Βͳ͍ڍಈʹͳΓ͏ΔͷͰɺpm/logsͰϩάΛ ࢀরͨ͠Βpm/reset!ͰϦηοτ͢Δ·Ͱߋ৽Ͱ͖ ͳ͍༷ʹͳ͍ͬͯΔ
ηογϣϯʹΑΔϩάͷ ‣ ηογϣϯҰ࿈ͷϩάͷอଘઌ ‣ ৽͍͠ηογϣϯΛ࡞Δ͜ͱͰଞͷϩάͱͷ͕Ͱ͖Δ (require '[postmortem.core :as pm]) (def
sess1 (pm/make-session)) (def sess2 (pm/make-session)) (let [f0 (fn [n] (pm/save :f)) f1 (fn [n] (pm/save sess1 :f identity)) f2 (fn [n] (pm/save sess2 :f identity))] (f0 1) (f1 10) (f2 100) (f0 2) (f1 20) (f2 200)) (pm/logs) ;=> {:f [{:n 1} {:n 2}]} ;; ↑ (pm/logs (pm/current-session)) ͱಉ͡ (pm/logs sess1) ;=> {:f [{:n 10} {:n 20}]} (pm/logs sess2) ;=> {:f [{:n 100} {:n 200}]}
ݱࡏͷηογϣϯ ‣ pm/set-current-session!ݱࡏͷηογϣϯΛมߋ ‣ pm/with-sessionϚΫϩຊମͷΈݱࡏͷηογϣϯΛมߋ (require '[postmortem.core :as pm]) (defn
add [x y] (pm/save :add) (+ x y)) (def sess1 (pm/make-session)) (pm/set-current-session! sess1) (add 1 2) ;=> 3 (def sess2 (pm/make-session)) (pm/with-session sess2 (add 3 4)) ;=> 7 (pm/log-for sess1 :add) ;=> [{:x 1 :y 2}] (pm/log-for sess2 :add) ;=> [{:x 3 :y 4}]
ηογϣϯͱτϥϯεσϡʔα ‣ ηογϣϯʹτϥϯεσϡʔαΛ࣋ͨͤΔ͜ͱ͕Ͱ͖ɺͦͷ ηογϣϯΛ͏ͯ͢ͷpm/saveʹͦΕ͕ద༻͞ΕΔ (require '[postmortem.core :as pm]) (defn add
[x y] (pm/save :add) (+ x y)) (def sess (pm/make-session (map (fn [x] (prn 'Logging x) x)))) (pm/set-current-session! sess) (add 1 2) ;; Logging {:x 1 :y 2} ;=> 3 (add 3 4) ;; Logging {:x 3 :y 4} ;=> 7
ಉظతηογϣϯ ‣ pm/make-sessionͰ࡞ΒΕΔηογϣϯεϨουηʔϑͰͳ͍ ‣ pm/make-synchronized-sessionͰ࡞ΒΕΔηογϣϯͷมߋಉظ͞ΕΔ (require '[postmortem.core :as pm]) (defn
f [x] (pm/save :f (comp (map-indexed #(assoc %2 :i %1)) (xf/take-last)))) (defn test [] (run! deref [(future (dotimes [i 10000] (f i))) (future (dotimes [i 10000] (f i)))])) (test) (pm/log-for :f) ;=> [{:n 9999, :i 19982}] (pm/set-current-session! (pm/make-synchronized-session)) (test) (pm/log-for :f) ;=> [{:n 9999, :i 19999}]
·ͱΊ ‣ ैདྷͷσόοάख๏Ͱσόοάͮ͠Β͍έʔεʹରԠͨ͠ 1PTUNPSUFNͱ͍͏σόοάπʔϧΛ։ൃͨ͠ ‣ τϥϯεσϡʔαͱͷ࿈ܞʹΑΓɺϩάʹͲ͏͍͏ΛͲ ͏ه͢Δ͔ΛॊೈʹΧελϚΠζͰ͖ΔΑ͏ʹͳͬͨ ‣ ηογϣϯͷ֓೦Λಋೖͨ͜͠ͱͰɺϚϧνεϨουͰͷ σόοάͰ͑ΔΑ͏ʹͳͬͨ
IUUQTHJUIVCDPNBUIPTQPTUNPSUFN