github.com/mier85/go-sensor@v1.30.1-0.20220920111756-9bf41b3bc7e0/example/autoprofile/demo.go (about)

     1  // (c) Copyright IBM Corp. 2021
     2  // (c) Copyright Instana Inc. 2020
     3  
     4  package main
     5  
     6  import (
     7  	"fmt"
     8  	"log"
     9  	"math"
    10  	"math/rand"
    11  	"net/http"
    12  	"os/exec"
    13  	"strconv"
    14  	"sync"
    15  	"time"
    16  
    17  	instana "github.com/mier85/go-sensor"
    18  )
    19  
    20  func useCPU(duration int, usage int) {
    21  	for j := 0; j < duration; j++ {
    22  		go func() {
    23  			for i := 0; i < usage*80000; i++ {
    24  				_ = strconv.Itoa(i)
    25  			}
    26  		}()
    27  
    28  		time.Sleep(1 * time.Second)
    29  	}
    30  }
    31  
    32  func simulateCPUUsage() {
    33  	// sumulate CPU usage anomaly - every 45 minutes
    34  	cpuAnomalyTicker := time.NewTicker(45 * time.Minute)
    35  	go func() {
    36  		for range cpuAnomalyTicker.C {
    37  			// for 60 seconds produce generate 50% CPU usage
    38  			useCPU(60, 50)
    39  		}
    40  	}()
    41  
    42  	// generate constant ~10% CPU usage
    43  	useCPU(math.MaxInt64, 10)
    44  }
    45  
    46  func leakMemory(duration int, size int) {
    47  	mem := make([]string, 0)
    48  
    49  	for j := 0; j < duration; j++ {
    50  		go func() {
    51  			for i := 0; i < size; i++ {
    52  				mem = append(mem, strconv.Itoa(i))
    53  			}
    54  		}()
    55  
    56  		time.Sleep(1 * time.Second)
    57  	}
    58  }
    59  
    60  func simulateMemoryLeak() {
    61  	// simulate memory leak - constantly
    62  	constantTicker := time.NewTicker(2 * 3600 * time.Second)
    63  	go func() {
    64  		for range constantTicker.C {
    65  			leakMemory(2*3600, 1000)
    66  		}
    67  	}()
    68  
    69  	go leakMemory(2*3600, 1000)
    70  }
    71  
    72  func simulateChannelWait() {
    73  	for {
    74  		done := make(chan bool)
    75  
    76  		go func() {
    77  			wait := make(chan bool)
    78  
    79  			go func() {
    80  				time.Sleep(500 * time.Millisecond)
    81  
    82  				wait <- true
    83  			}()
    84  
    85  			<-wait
    86  
    87  			done <- true
    88  		}()
    89  
    90  		<-done
    91  
    92  		time.Sleep(1000 * time.Millisecond)
    93  	}
    94  }
    95  
    96  func simulateNetworkWait() {
    97  	// start HTTP server
    98  	go func() {
    99  		http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
   100  			done := make(chan bool)
   101  
   102  			go func() {
   103  				time.Sleep(time.Duration(200+rand.Intn(5)) * time.Millisecond)
   104  				done <- true
   105  			}()
   106  			<-done
   107  
   108  			fmt.Fprintf(w, "OK")
   109  		})
   110  
   111  		if err := http.ListenAndServe(":5002", nil); err != nil {
   112  			log.Fatal(err)
   113  			return
   114  		}
   115  	}()
   116  
   117  	requestTicker := time.NewTicker(500 * time.Millisecond)
   118  	for range requestTicker.C {
   119  		res, err := http.Get("http://localhost:5002/test")
   120  		if err == nil {
   121  			res.Body.Close()
   122  		}
   123  	}
   124  }
   125  
   126  func simulateSyscallWait() {
   127  	for {
   128  		done := make(chan bool)
   129  
   130  		go func() {
   131  			_, err := exec.Command("sleep", "1").Output()
   132  			if err != nil {
   133  				fmt.Println(err)
   134  			}
   135  
   136  			done <- true
   137  		}()
   138  
   139  		time.Sleep(1 * time.Second)
   140  
   141  		<-done
   142  	}
   143  }
   144  
   145  func simulateLockWait() {
   146  	for {
   147  		done := make(chan bool)
   148  
   149  		lock := &sync.RWMutex{}
   150  		lock.Lock()
   151  
   152  		go func() {
   153  			lock.RLock()
   154  			defer lock.RUnlock()
   155  
   156  			done <- true
   157  		}()
   158  
   159  		go func() {
   160  			time.Sleep(200 * time.Millisecond)
   161  			lock.Unlock()
   162  		}()
   163  
   164  		<-done
   165  
   166  		time.Sleep(500 * time.Millisecond)
   167  	}
   168  }
   169  
   170  func main() {
   171  	instana.InitSensor(&instana.Options{
   172  		Service:           "autoprofile-demo",
   173  		LogLevel:          instana.Debug,
   174  		EnableAutoProfile: true})
   175  
   176  	go simulateCPUUsage()
   177  	go simulateMemoryLeak()
   178  	go simulateChannelWait()
   179  	go simulateNetworkWait()
   180  	go simulateSyscallWait()
   181  	go simulateLockWait()
   182  
   183  	select {}
   184  }