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
380
Other Decks in Programming
See All in Programming
AI時代に学ぶ 好きなルール 嫌いなルール Linter編
shorty5121
0
190
ドリフトを絶対に許さない(?)CDK運用 / CDK Ops with Zero Tolerance for Drifts (?)
akihisaikeda
1
240
freeeにおけるEvalsの実践例の紹介
freee
PRO
0
160
バグを直したら useEffect が消えた
colorful12
3
750
片田舎のおっさん、 Swift Buildのダイアモンド問題解決の不具合修正PRを出すが、解決方法がキャッシュをしないようにすることであり、ビルド時間が伸びると言われてマージされないので高速化もする/swiftbuild
yimajo
0
300
Webエンジニアなのにブラウザの仕組みがわからないので、Pythonで自作してみた
tatsuki12
4
1.1k
T3DD26: From RAGs to Riches
martinhelmich
0
110
Jindong: Introducing Declarative Haptics in Compose Multiplatform
l2hyunwoo
0
130
AWS DevOps AgentのAzure接続機能を検証して見えた活用法/Use Cases Verified for the AWS DevOps Agent's Azure Connectivity Feature
masakiokuda
1
270
「人を評価する AI」の設計と実装
ryoyanara
0
250
言葉の格闘技のススメ~紙とペンと言葉から始める、キャリアの描き方~
progresscicada
2
180
わからない話を追いかけたら、プログラミング言語を作る側にいた
ydah
3
560
Featured
See All Featured
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
67
57k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
180
Color Theory Basics | Prateek | Gurzu
gurzu
0
440
Prompt Engineering for Job Search
mfonobong
0
420
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
880
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
290
How to train your dragon (web standard)
notwaldorf
97
6.8k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.6k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
410
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
1
380
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