1// Copyright 2015 Keybase, Inc. All rights reserved. Use of 2// this source code is governed by the included BSD license. 3 4package libkb 5 6import ( 7 "fmt" 8 "strings" 9 "sync" 10 11 "github.com/keybase/client/go/logger" 12 "golang.org/x/net/context" 13) 14 15// VDebugLog is a "Verbose" debug logger; enable it if you really 16// want spam and/or minutiae 17type VDebugLog struct { 18 log logger.Logger 19 dumpSiteLoadUser bool 20 dumpPayload bool 21 22 lock sync.RWMutex 23 lev VDebugLevel 24} 25 26type VDebugLevel int 27 28func NewVDebugLog(l logger.Logger) *VDebugLog { 29 return &VDebugLog{log: l} 30} 31 32const ( 33 VLogNone VDebugLevel = iota - 1 34 VLog0 35 VLog1 36 VLog2 37 VLog3 38 39 VLogNoneString = "mobile" 40 VLog0String = "vlog0" 41 VLog1String = "vlog1" 42 VLog2String = "vlog2" 43 VLog3String = "vlog3" 44 VLogDumpSiteLoadUser = "dump-site-load-user" 45 VLogDumpPayload = "dump-payload" 46) 47 48func (v VDebugLevel) String() string { 49 switch v { 50 case VLogNone: 51 return VLogNoneString 52 case VLog0: 53 return VLog0String 54 case VLog1: 55 return VLog1String 56 case VLog2: 57 return VLog2String 58 case VLog3: 59 return VLog3String 60 default: 61 return "unknown" 62 } 63} 64 65func (v *VDebugLog) getLev() VDebugLevel { 66 v.lock.RLock() 67 defer v.lock.RUnlock() 68 return v.lev 69} 70 71func (v *VDebugLog) Log(lev VDebugLevel, fs string, args ...interface{}) { 72 if lev <= v.getLev() { 73 prfx := fmt.Sprintf("{VDL:%d} ", int(lev)) 74 fs = prfx + fs 75 v.log.CloneWithAddedDepth(1).Debug(fs, args...) 76 } 77} 78 79func (v *VDebugLog) CLogf(ctx context.Context, lev VDebugLevel, fs string, args ...interface{}) { 80 if lev <= v.getLev() { 81 prfx := fmt.Sprintf("{VDL:%d} ", int(lev)) 82 fs = prfx + fs 83 v.log.CloneWithAddedDepth(1).CDebugf(ctx, fs, args...) 84 } 85} 86 87func (v *VDebugLog) CLogfWithAddedDepth(ctx context.Context, lev VDebugLevel, d int, fs string, args ...interface{}) { 88 if lev <= v.getLev() { 89 prfx := fmt.Sprintf("{VDL:%d} ", int(lev)) 90 fs = prfx + fs 91 v.log.CloneWithAddedDepth(1+d).CDebugf(ctx, fs, args...) 92 } 93} 94 95func (v *VDebugLog) DumpSiteLoadUser() bool { 96 return v.dumpSiteLoadUser 97} 98 99func (v *VDebugLog) DumpPayload() bool { 100 return v.dumpPayload 101} 102 103func (v *VDebugLog) Configure(s string) { 104 v.lock.Lock() 105 defer v.lock.Unlock() 106 107 v.lev = VLog0 108 if len(s) == 0 { 109 return 110 } 111 v.log.Debug("Setting Vdebug to %q", s) 112 parts := strings.Split(s, ",") 113 for _, s := range parts { 114 switch s { 115 case VLogNoneString: 116 v.lev = VLogNone 117 case VLog0String: 118 v.lev = VLog0 119 case VLog1String: 120 v.lev = VLog1 121 case VLog2String: 122 v.lev = VLog2 123 case VLog3String: 124 v.lev = VLog3 125 case VLogDumpSiteLoadUser: 126 v.dumpSiteLoadUser = true 127 case VLogDumpPayload: 128 v.dumpPayload = true 129 default: 130 v.log.Warning("Ignoring Vdebug log directive: %q", s) 131 } 132 } 133} 134