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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
210
AI 時代のソフトウェア設計の学び方
masuda220
PRO
29
13k
TypeScript+Orvalで実現する型安全かつ堅牢でスケーラブルなマルチチャネル通知基盤 / TSKaigi Night talks ~after conference~
d0riven
0
350
ユニットテストの先へ:テスト技法で要求・仕様を整理するJava開発実践 / Beyond_Unit_Testing_Practical_Java_Development_Techniques_for_Organizing_Requirements_and_Specifications
shimashima35
0
410
New "Type" system on PicoRuby
pocke
1
980
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.3k
技術記事、 専門家としてのプログラマ、 言語化
mizchi
13
6.2k
Even G2とAWSで推しのエージェントを召喚しよう!
har1101
1
120
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
contour_gara
0
550
Oxlintのカスタムルールの現況
syumai
6
1.1k
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
270
ECSアプリログをFireLensでコスト削減しようとしたけど諦めた話 in Fargate×Node.js
akihisaikeda
2
4.2k
Featured
See All Featured
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
430
Balancing Empowerment & Direction
lara
6
1.2k
Automating Front-end Workflow
addyosmani
1370
210k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
600
The SEO identity crisis: Don't let AI make you average
varn
0
490
GitHub's CSS Performance
jonrohan
1033
470k
Context Engineering - Making Every Token Count
addyosmani
9
970
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
170
Ruling the World: When Life Gets Gamed
codingconduct
0
260
Making Projects Easy
brettharned
120
6.7k
We Have a Design System, Now What?
morganepeng
55
8.2k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
460
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
ʹศར (?) • ศརͳར༻ํ๏ͱ͔ࢥ͍ͭ͘ਓڭ͑ͯԼ͍͞