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
220
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
430
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
600
clojure.specの話
athos
3
2.4k
clojure.specの話(仮)
athos
2
380
Other Decks in Programming
See All in Programming
Webの地図
yosuke_furukawa
PRO
1
380
thread_parallel_with_free-threaded_Python_and_NumPy.pdf
riku_sakamoto
0
140
アクセシビリティから考える情報設計
high_g_engineer
0
300
Snowflakeで業務アプリを作ろう。 Snowflakeのアプリ機能解説&実践ガイド
ayumu_yamaguchi
1
150
MIZARU@SPAJAM2026 第二回予選
1901drama
0
110
週末にAI-DLCを本気で回したら$1,600溶けた
hbashimizu
0
130
個人開発基盤をまるごとCloudflareに引っ越して爆速で総合的体験を向上させた話
tinykitten
0
130
GKE アップグレード前に知っておきたい Blue/Green と PDB の関係
stkk
0
160
{ Android | Kotlin } Gradle Plugin in 2026
ryunen344
1
290
Foundry Localでエージェント開発
seosoft
0
150
Oxlintはいいぞ(続)
yug1224
1
560
AIエージェント時代のコードレビューを設計する
nogu66
6
2.5k
Featured
See All Featured
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
680
Automating Front-end Workflow
addyosmani
1369
210k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
970
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
490
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
230
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
690
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1k
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
GraphQLとの向き合い方2022年版
quramy
50
15k
Speed Design
sergeychernyshev
33
2.1k
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