Upgrade to Pro — share decks privately, control downloads, hide ads and more …

軽量デバッグツールPostmortemの紹介.pdf

Avatar for OHTA Shogo OHTA Shogo
September 26, 2019

 軽量デバッグツールPostmortemの紹介.pdf

Avatar for OHTA Shogo

OHTA Shogo

September 26, 2019
Tweet

More Decks by OHTA Shogo

Other Decks in Programming

Transcript

  1. طଘͷओͳσόοάख๏ ‣ QSJOUσόοά  QSO΍QSJOUMOΛૠೖ͠ɺͦͷ࣌఺ͷ஋Λ֬ೝͨ͠Γͦͷίʔυ͕࣮ߦ͞Εͨ ͜ͱΛ֬ೝ͢Δ  ૉ๿͕ͩखܰͳख๏ͰɺσόοΨ͕࢖͑ͳ͍৔߹ʹ༗ޮͳ͜ͱ΋ଟ͍ ‣ τϨʔεػೳ

     ؔ਺ݺͼग़͠ͷҾ਺΍໭Γ஋ɺݺͼग़͠ͷਂ͞౳Λग़ྗ͢Δ  UPPMTUSBDF΍$*%&3ͷτϨʔεػೳ౳ͱͯ͠ఏڙ͞ΕΔ ‣ σόοΨ  ϒϨʔΫϙΠϯτΛઃఆͯ͠ϓϩάϥϜͷ࣮ߦΛఀࢭ͠ɺεςοϓ࣮ߦ΍ ϩʔΧϧ؀ڥͷΠϯεϖΫτ౳͕Ͱ͖Δ  ৚͖݅ͭͷϒϨʔΫϙΠϯτΛઃఆͯ͠৚݅Λຬͨ͢৔߹͚࣮ͩߦΛࢭΊΔ
  2. طଘख๏͕ద༻ͮ͠Β͍έʔε ‣ ಉ͡ॲཧ͕ ϧʔϓ΍࠶ؼͰ Կ౓΋܁Γฦ࣮͠ߦ͞ΕΔ  QSJOUσόοά΍τϨʔεػೳͷग़ྗ͕ଟ͘ͳΓɺॏཁͳग़ྗͷಛఆ͕೉͘͠ͳΔ  ৚͖݅ͭϒϨʔΫϙΠϯτΛ͏·͘ઃఆ͠ͳ͍ͱԿ౓΋໰୊ͱ௚઀ؔ܎ͳ͍ճͷ܁Γ ฦ͠Ͱ࣮ߦ͕ࢭ·Δ

    ‣ ܁Γฦ͠ͷ݁Ռ͕ޙͷ܁Γฦ͠ʹӨڹΛ༩͑Δ  ໰୊͕ى͖ΔԿճ͔લͷ܁Γฦ͕͠໰୊ͷݪҼʹͳΓ͏Δ  ໰୊͕͋Δͱ෼͔Δ࣌఺Ͱ࣮ߦΛϒϨʔΫͯ͠΋ͦ͜ʹ໰୊ͷݪҼ͕ͳ͘ɺͦͷԿճ ͔લͷ܁Γฦ͠ͷঢ়ଶΛͲ͏ʹ͔ಛఆ͢Δඞཁ͕͋Δ ‣ ϚϧνεϨουͷॲཧ͕བྷΉͱ͞Βʹ໽հ ‣ ྫ  ࣌ؒܦաʹ͕͍ͨ͠ϦΞϧλΠϜʹঢ়ଶ͕มԽ͢Δ΋ͷ ήʔϜɺΞχϝʔγϣϯ   ݴޠॲཧܥ  ͱʹ͔͘ೖྗͷαΠζ͕େ͖͍ू໿ॲཧ FUD
  3. 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}]
  4. 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]}
  5. 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]}
  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}]
  7. τϥϯεσϡʔαͱͷ࿈ܞ  ‣ 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}]
  8. τϥϯεσϡʔαͱͷ࿈ܞ  ‣ 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}]
  9. τϥϯεσϡʔαͱͷ࿈ܞ  ‣ 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}]
  10. 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))))) ॳظԽॲཧ ׬ྃॲཧ εςοϓॲཧ
  11. τϥϯεσϡʔαͷ׬ྃॲཧ͸͍ͭݺ͹ΕΔͷ͔ʁ (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}]}
  12. ηογϣϯʹΑΔϩάͷ෼཭ ‣ ηογϣϯ͸Ұ࿈ͷϩάͷอଘઌ ‣ ৽͍͠ηογϣϯΛ࡞Δ͜ͱͰଞͷϩάͱͷ෼཭͕Ͱ͖Δ (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}]}
  13. ݱࡏͷηογϣϯ ‣ 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}]
  14. ηογϣϯͱτϥϯεσϡʔα ‣ ηογϣϯʹτϥϯεσϡʔαΛ࣋ͨͤΔ͜ͱ͕Ͱ͖ɺͦͷ ηογϣϯΛ࢖͏͢΂ͯͷ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
  15. ಉظతηογϣϯ ‣ 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}]