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
Gunosy.go #3 ~ expvar.go ~ #gunosygo
Search
zoncoen
June 25, 2014
Programming
770
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Gunosy.go #3 ~ expvar.go ~ #gunosygo
Gunosy.go #3 の発表資料です。
zoncoen
June 25, 2014
More Decks by zoncoen
See All by zoncoen
About Merpay Engineering Productivity Team
zoncoen
0
1.9k
Perl の HTTP/2 事情 / HTTP2 in Perl
zoncoen
0
500
Perl でも React.js の server-side rendering がしたい! / perl meets javascript with reactjs
zoncoen
0
2.2k
YAPC::Asia 2014
zoncoen
0
2.7k
同期的にプレゼンテーションするツールをつくった話
zoncoen
1
1k
Gunosy.go #4 ~ flag.go ~ #gunosygo
zoncoen
0
250
初心者がGoでpercol実装してみた話 / Golang + Reveal.js + Websocket で同期的にプレゼンテーションしたい #hikarie_go
zoncoen
0
2.6k
Other Decks in Programming
See All in Programming
Javaの型とAI時代に型が大事な理由 / java types and type in AI era
kishida
2
140
並列実装の現場、2ヶ月間実務でAIを使い倒したAIもPCも私も限界が近い
ming_ayami
0
130
Strategic Design in the Frontend: Moduliths & Micro Frontends @DDDEurope
manfredsteyer
PRO
0
110
Dataformのリポジトリを立ち上げるときにまずやること / dataform-day0-2026
snhryt
0
170
依存関係から依存物へ―Dependencyという言葉の歴史をひも解く
j_lee
0
120
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.6k
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
contour_gara
0
550
3Dシーンの圧縮
fadis
1
780
Lessons from Spec-Driven Development
simas
PRO
0
210
TAKTでAI駆動開発の品質を設計する
j5ik2o
7
1.3k
AIだと陥りがちなJakarta EE最新技術への移行時の落とし穴と解決策
tnagao7
0
110
RTSPクライアントを自作してみた話
simotin13
0
610
Featured
See All Featured
Writing Fast Ruby
sferik
630
63k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
360
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
210
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.5k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
3.5k
How to Talk to Developers About Accessibility
jct
2
240
The #1 spot is gone: here's how to win anyway
tamaranovitovic
2
1.1k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
750
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
530
Transcript
Gunosy.go #3 ~ expvar.go ~ Kenta Mori (@zoncoen)
Contents 1. expvar package ͱʁ 2. expvar ͷجຊతͳಈ࡞֬ೝ 3. ࣮ફɿΞΫηεΛެ։͢Δ
4. ·ͱΊ
ࣗݾհ • ݈ଠ (@zoncoen) - ໋ཱؗ (ੜ໋Պֶ) → ಸྑઌ (ใ)
- ৽ଔݚमத@DeNA - Baby Gopher
What is the expvar pkg? • αʔό্ͷύϒϦοΫมͷඪ४Խ͞Ε ͨΠϯλϑΣʔεΛఏڙ • ม
HTTP αʔό্ͷ /debug/vars ʹ JSON ϑΥʔϚοτͰެ։͞ΕΔ ?
ͻͱ·ͣͬͯΈΔ
ҎԼͷίʔυΛ࣮ߦͯ͠ɺ http://localhost:8080/debug/vars ʹΞΫηε import ( _ “expvar" "net/http" ) !
func main() { http.ListenAndServe(":8080", nil) }
ͳΜ͔ग़ͯ͘Δ { "cmdline": ["/var/folders/c3/vwntnjg517v2pxzd6072hrnjhggkq_/T/go- build578951979/command-line-arguments/_obj/exe/demo"], "memstats": {“Alloc”:278640,"TotalAlloc":364488,"Sys": 4069608,"Lookups":29,"Mallocs":972,"Frees":450,"HeapAlloc": 278640,"HeapSys":1048576,"HeapIdle":630784,"HeapInuse": 417792,"HeapReleased":593920,"HeapObjects":522,"StackInuse":
! … snip … ! {"Size":12288,"Mallocs":0,"Frees":0},{"Size":14080,"Mallocs": 0,"Frees":0},{"Size":16384,"Mallocs":0,"Frees":0},{"Size": 17664,"Mallocs":0,"Frees":0},{"Size":20480,"Mallocs":0,"Frees":0}, {"Size":21248,"Mallocs":0,"Frees":0},{"Size":24576,"Mallocs": 0,"Frees":0},{"Size":24832,"Mallocs":0,"Frees":0},{"Size": 28672,"Mallocs":0,"Frees":0},{"Size":32768,"Mallocs":4,"Frees":0}]} }
import expvar ͷಈ࡞ 1. HTTPαʔόͷ /debug/vars ʹϋϯυϥΛ ొ 2. os.Args
Λ ม cmdline ͱͯ͠ొ 3. runtime.Memstats Λ ม memstats ͱ͠ ͯొ
͖ͬ͞ͷΞϨ { "cmdline": ["/var/folders/c3/vwntnjg517v2pxzd6072hrnjhggkq_/T/go- build578951979/command-line-arguments/_obj/exe/expvar"], "memstats": {“Alloc”:278640,"TotalAlloc":364488,"Sys": 4069608,"Lookups":29,"Mallocs":972,"Frees":450,"HeapAlloc": 278640,"HeapSys":1048576,"HeapIdle":630784,"HeapInuse": 417792,"HeapReleased":593920,"HeapObjects":522,"StackInuse":
! … snip … ! {"Size":12288,"Mallocs":0,"Frees":0},{"Size":14080,"Mallocs": 0,"Frees":0},{"Size":16384,"Mallocs":0,"Frees":0},{"Size": 17664,"Mallocs":0,"Frees":0},{"Size":20480,"Mallocs":0,"Frees":0}, {"Size":21248,"Mallocs":0,"Frees":0},{"Size":24576,"Mallocs": 0,"Frees":0},{"Size":24832,"Mallocs":0,"Frees":0},{"Size": 28672,"Mallocs":0,"Frees":0},{"Size":32768,"Mallocs":4,"Frees":0}]} }
1. HTTPαʔόͷ /debug/vars ʹϋϯυϥΛ ొ // expvar.go L332-336 func init()
{ http.HandleFunc("/debug/vars", expvarHandler) Publish("cmdline", Func(cmdline)) Publish("memstats", Func(memstats)) }
2. os.Args Λ ม cmdline ͱͯ͠ొ // expvar.go L322-324 func
cmdline() interface{} { return os.Args } ! // expvar.go L332-336 func init() { http.HandleFunc("/debug/vars", expvarHandler) Publish("cmdline", Func(cmdline)) Publish("memstats", Func(memstats)) }
3. runtime.Memstats Λ ม memstats ͱ ͯ͠ొ // expvar.go L326-330
func memstats() interface{} { stats := new(runtime.MemStats) runtime.ReadMemStats(stats) return *stats } ! // expvar.go L332-336 func init() { http.HandleFunc("/debug/vars", expvarHandler) Publish("cmdline", Func(cmdline)) Publish("memstats", Func(memstats)) }
جຊ͜Ε͚ͩ
// expvar.go L332-336 func init() { http.HandleFunc("/debug/vars", expvarHandler) Publish("cmdline", Func(cmdline))
Publish("memstats", Func(memstats)) } Publish() ͱ
// expvar.go L244-248 var ( mutex sync.RWMutex vars = make(map[string]Var)
varKeys []string // sorted ) ! // expvar.go L253-262 func Publish(name string, v Var) { mutex.Lock() defer mutex.Unlock() if _, existing := vars[name]; existing { log.Panicln("Reuse of exported var name:", name) } vars[name] = v varKeys = append(varKeys, name) sort.Strings(varKeys) } ม name Λ export (name͕͢Ͱʹొ͞Ε͍ͯΔͱ log.Panic ) varKeys: sort ࡁΈ key vars: key ͱ value ͷ Map
// expvar.go L308-320 func expvarHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type",
"application/json; charset=utf-8") fmt.Fprintf(w, "{\n") first := true Do(func(kv KeyValue) { if !first { fmt.Fprintf(w, ",\n") } first = false fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value) }) fmt.Fprintf(w, "\n}\n") } export ͞Εͨม expvarHandler ʹΑͬͯ JSON Ͱެ։͞ΕΔ
// expvar.go L300-306 func Do(f func(KeyValue)) { mutex.RLock() defer mutex.RUnlock()
for _, k := range varKeys { f(KeyValue{k, vars[k]}) } } Do() Ҿͷ func ʹ KeyValue Λ࣮ͯ͠ߦ
࣮ફɿࣗͰมΛొ͢Δ
ΞΫηεΧϯλ num_calls Λ export import ( "expvar" "net/http" ) !
var numCalls = expvar.NewInt("num_calls") ! func helloHandler(w http.ResponseWriter, req *http.Request) { numCalls.Add(1) io.WriteString(w, "Hello Gopher!\n”) } ! func main() { http.HandleFunc("/", helloHandler) http.ListenAndServe(":8080", nil) }
/debug/vars ʹ ΞΫηε͢Δͱ export ͨ͠ num_calls ͕औಘͰ͖Δ { "cmdline": ["/var/folders/c3/vwntnjg517v2pxzd6072hrnjhggkq_/T/go-
build507427005/command-line-arguments/_obj/exe/demo"], "memstats": {“Alloc”:336232,"TotalAlloc":336240,"Sys": 4069608,"Lookups":13,"Mallocs":839,"Frees":1,"HeapAlloc": 336232,"HeapSys": ! … snip … ! 21248,"Mallocs":0,"Frees":0},{"Size":24576,"Mallocs":0,"Frees":0}, {"Size":24832,"Mallocs":0,"Frees":0},{"Size":28672,"Mallocs": 0,"Frees":0},{"Size":32768,"Mallocs":4,"Frees":0}]}, "num_calls": 1 }
Debug ʹศར (?)
มͷܕ Int, Float, String RWMutex ͰΞτϛοΫʹมߋ͞ΕΔ // expvar.go L43-46 type
Int struct { mu sync.RWMutex i int64 } ! // expvar.go L67-70 type Float struct { mu sync.RWMutex f float64 } ! // expvar.go L217-220 type String struct { mu sync.RWMutex s string }
มͷܕ Int, Float, String RWMutex ͰΞτϛοΫʹมߋ͞ΕΔ // expvar.go L48-64 func
(v *Int) String() string { v.mu.RLock() defer v.mu.RUnlock() return strconv.FormatInt(v.i, 10) } ! func (v *Int) Add(delta int64) { v.mu.Lock() defer v.mu.Unlock() v.i += delta } ! func (v *Int) Set(value int64) { v.mu.Lock() defer v.mu.Unlock() v.i = value }
·ͱΊ • expvar Λ͏ͱ Server ্ͷมΛ JSON ϑΥʔϚοτͰ؆୯ʹऔಘͰ͖Δ • Debug
ʹศར (?) • ศརͳར༻ํ๏ͱ͔ࢥ͍ͭ͘ਓڭ͑ͯԼ͍͞