Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
軽量デバッグツール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
710
やってみる!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
AI が書く Go コードの品質を劇的に向上させる Linter: “declscope”
mpyw
0
360
setup-vp GitLab対応の裏側
naokihaba
0
110
フロントエンドUIフレームワークのこれまでとこれから
ssssota
5
2.8k
アクセシビリティから考える情報設計
high_g_engineer
0
380
Heart of Swift Concurrency
koher
0
890
巨大モノリシックアプリ モダン化大作戦
ktcryomm
1
1k
Building an Out-of-Order CPU
latte72
1
790
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
420
Streamlitで実現する自然言語データアプリ開発
ayumu_yamaguchi
1
290
AIは賢い。でも実行環境は? CLIおじさんがAI時代に伝えたいこと ~ CLIおじさんがAI時代に伝えたいこと ~
curekoshimizu
1
240
動作中のプログラムの中身をリアルタイムに覗く / Realtime Debugger for CSharp with Roslyn
prota
1
320
App Intentsのビルドプロセスを支える技術
kntkymt
0
390
Featured
See All Featured
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Speed Design
sergeychernyshev
33
2.1k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
530
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
830
Documentation Writing (for coders)
carmenintech
77
5.5k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Product Roadmaps are Hard
iamctodd
55
13k
SEO for Brand Visibility & Recognition
aleyda
0
4.7k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
510
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
2
2.9k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
280
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