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
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
780
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
2k
Perl の HTTP/2 事情 / HTTP2 in Perl
zoncoen
0
510
Perl でも React.js の server-side rendering がしたい! / perl meets javascript with reactjs
zoncoen
0
2.3k
YAPC::Asia 2014
zoncoen
0
2.7k
同期的にプレゼンテーションするツールをつくった話
zoncoen
1
1k
Gunosy.go #4 ~ flag.go ~ #gunosygo
zoncoen
0
270
初心者がGoでpercol実装してみた話 / Golang + Reveal.js + Websocket で同期的にプレゼンテーションしたい #hikarie_go
zoncoen
0
2.6k
Other Decks in Programming
See All in Programming
Optunaを作ったときにやりたかったこと、その後 (2026/10/16, Optuna Meetup #3)
iwiwi
4
1.3k
Railsのためのパスキー実践入門 〜マルチテナントSaaSでの意思決定〜
utakaha
3
1.3k
Coding with AI: How to trust the storyteller (AWS Community Day Adria, Ljubljana 2026)
slobodan
0
120
全ての永続トークンを、生まれる前に消し去りたい!
sylph01
2
1.4k
dotNET_vulnclicker_intro.pdf
deka_morita
0
150
自作Discord音声botをLambda MicroVMsに移行した話 / Migrating My Discord Voice Bot to Lambda MicroVMs
akihisaikeda
0
150
AIで開発が速くなった先で、開発チームは何を目指すか
shihochan
1
1.8k
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
4
970
當我們開始不讀 Code - AI Agent 時代,Code Review 與 Clean Code 還剩下什麼?
jame2408
1
320
React Native에 현대적인 빌드 도구 더하기: Rollipop 구현기
leegeunhyeok
0
150
golang-bob.pdf
iwatsukayura
0
140
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Kaigi on Rails 2026, Tokyo, Japan
marcoroth
2
340
Featured
See All Featured
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1.1k
The Limits of Empathy - UXLibs8
cassininazir
2
730
Optimising Largest Contentful Paint
csswizardry
37
4k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
360
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
460
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
510
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.9k
Scaling GitHub
holman
464
140k
How GitHub (no longer) Works
holman
316
150k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
ラッコキーワード サービス紹介資料
rakko
4
5.5M
Designing for humans not robots
tammielis
254
26k
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
ʹศར (?) • ศརͳར༻ํ๏ͱ͔ࢥ͍ͭ͘ਓڭ͑ͯԼ͍͞