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
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
260
初心者がGoでpercol実装してみた話 / Golang + Reveal.js + Websocket で同期的にプレゼンテーションしたい #hikarie_go
zoncoen
0
2.6k
Other Decks in Programming
See All in Programming
見えないものを探る要求要件定義に必要な基本的思考 / invisible-requirement-thinking
minodriven
13
6.6k
KiroのSpecで「五目並べ」を作ってみる
satoshi256kbyte
1
350
AI が書く Go コードの品質を劇的に向上させる Linter: “declscope”
mpyw
0
480
Everything will be SERVERLESS — 信じて運用した10年の経験値 / Everything Will be Serverless — Lessons Learned from 10 Years of Operational Experience
seike460
PRO
1
740
大喜利で理解するLLM as a Judge / Understanding LLM-as-a-Judge through Ogiri
rockname
0
190
phperだってパンチカードでコーディングしたい
o0h
PRO
0
200
スマートフォンでモールス信号を送受信する 〜スマートフォンのLEDとカメラで作る光通信の設計と実装〜
atsuki_seo
0
230
RAG の “R” を Swift で覗いてみる 〜「意味から探す」検索の仕組み〜
nao_randd
0
120
すこし踏み込む CancellationToken
htkym
2
1.6k
FreeBSDでZabbixを動かす
kenkino
0
360
[2026-09-26]空論ジェネリックプロセス~テスト資産とAIで紡ぐ、再現可能なパフォーマンスチューニングの話~
tosite
0
250
Findy - エンジニア向け会社紹介/Findy Company Deck
findyinc
6
400k
Featured
See All Featured
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
270
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
310
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
590
The SEO identity crisis: Don't let AI make you average
varn
0
580
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.4k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
540
Faster Mobile Websites
deanohume
310
32k
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
Code Reviewing Like a Champion
maltzj
528
40k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
470
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
710
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
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
ʹศར (?) • ศརͳར༻ํ๏ͱ͔ࢥ͍ͭ͘ਓڭ͑ͯԼ͍͞