// Snapshot calls callback function with stack-trace or error.
Snapshot calls callback function with stack-trace or error.
// Snapshot calls callback function with stack - trace or error .
func (s *GoSpy) Snapshot(cb func([]byte, uint64, error)) {
	s.resetMutex.Lock()
	defer s.resetMutex.Unlock()
	if !s.reset {
		return
	}
	s.reset = false
	if s.profileType == spy.ProfileCPU {
		pprof.StopCPUProfile()
		defer func() {
			if err := startCPUProfile(s.buf, s.sampleRate); err != nil {
				cb(nil, uint64(0), err)
			}
		}()
		r, err := gzip.NewReader(bytes.NewReader(s.buf.Bytes()))
		if err != nil {
			cb(nil, uint64(0), fmt.Errorf("new gzip reader: %v", err))
			return
		}
		profile, err := convert.ParsePprof(r)
		if err != nil {
			cb(nil, uint64(0), fmt.Errorf("parse pprof: %v", err))
			return
		}
		profile.Get("samples", func(name []byte, val int) {
			cb(name, uint64(val), nil)
		})
	} else {
		currentGCGeneration := numGC()
		if currentGCGeneration == s.lastGCGeneration && !s.disableGCRuns {
			runtime.GC()
			currentGCGeneration = numGC()
		}
		if currentGCGeneration != s.lastGCGeneration {
			getHeapProfile(s.buf).Get(string(s.profileType), func(name []byte, val int) {
				cb(name, uint64(val), nil)
			})
			s.lastGCGeneration = currentGCGeneration
		}
	}
	s.buf.Reset()
}
func ( s * GoSpy ) Snapshot ( cb func ( [ ] byte , uint64 , error ) ) { s . resetMutex . Lock ( ) defer s . resetMutex . Unlock ( ) if ! s . reset { return } s . reset = false if s . profileType == spy . ProfileCPU { pprof . StopCPUProfile ( ) defer func ( ) { if err := startCPUProfile ( s . buf , s . sampleRate ) ; err != nil { cb ( nil , uint64 ( 0 ) , err ) } } ( ) r , err := gzip . NewReader ( bytes . NewReader ( s . buf . Bytes ( ) ) ) if err != nil { cb ( nil , uint64 ( 0 ) , fmt . Errorf ( " " , err ) ) return } profile , err := convert . ParsePprof ( r ) if err != nil { cb ( nil , uint64 ( 0 ) , fmt . Errorf ( " " , err ) ) return } profile . Get ( " " , func ( name [ ] byte , val int ) { cb ( name , uint64 ( val ) , nil ) } ) } else { currentGCGeneration := numGC ( ) if currentGCGeneration == s . lastGCGeneration && ! s . disableGCRuns { runtime . GC ( ) currentGCGeneration = numGC ( ) } if currentGCGeneration != s . lastGCGeneration { getHeapProfile ( s . buf ) . Get ( string ( s . profileType ) , func ( name [ ] byte , val int ) { cb ( name , uint64 ( val ) , nil ) } ) s . lastGCGeneration = currentGCGeneration } } s . buf . Reset ( ) }
Snapshot calls callback function with stack-trace or error.
Snapshot calls callback function with stack - trace or error .
// before the upload rate is reached, no need to read the profile data // stop the previous cycle of sample collection // start a new cycle of sample collection // new gzip reader with the read data in buffer // parse the read data with pprof format // this is current GC generation // sometimes GC doesn't run within 10 seconds //   in such cases we force a GC run //   users can disable it with disableGCRuns option // if there's no GC run then the profile is gonna be the same //   in such case it does not make sense to upload the same profile twice