Skip to content
This repository has been archived by the owner on May 27, 2021. It is now read-only.

Commit

Permalink
Updated packages
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielOaks committed Oct 29, 2017
1 parent 8cfb512 commit efe484a
Show file tree
Hide file tree
Showing 174 changed files with 2,908 additions and 1,076 deletions.
43 changes: 38 additions & 5 deletions github.com/stackimpact/stackimpact-go/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ All initialization options:
* `AppEnvironment` (Optional) Used to differentiate applications in different environments.
* `HostName` (Optional) By default, host name will be the OS hostname.
* `ProxyAddress` (Optional) Proxy server URL to use when connecting to the Dashboard servers.
* `DisableAutoProfiling` (Optional) If set to `true`, disables the default automatic profiling and reporting. `agent.Profile()` should be used instead. Useful for environments without support for timers or background tasks.
* `Debug` (Optional) Enables debug logging.


Expand Down Expand Up @@ -94,12 +95,43 @@ func main() {
AppEnvironment: "production",
})

// use MeasureHandlerFunc or MeasureHandler to additionally measure HTTP request execution time.
http.HandleFunc(agent.MeasureHandlerFunc("/", handler))
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
```

#### Manual profiling

*The use of manual profiling is optional.*

Manual profiling is suitable for repeating code, such as request or event handlers. By default, the agent starts and stops profiling automatically. In order to make sure the agent profiles the most relevant execution intervals, the `agent.Profile()` method can be used.

```go
// Use this method to instruct the agent to start and stop
// profiling. It does not guarantee that any profiler will be
// started. The decision is made by the agent based on the
// overhead constraints. The method returns Span object, on
// which the Stop() method should be called.

span := agent.Profile();
defer span.Stop();
```

```go
// A helper function to profile HTTP handler execution by wrapping
// http.Handle method parameters.
// Usage example:
// http.Handle(agent.ProfileHandler("/some-path", someHandler))
pattern, wrappedHandler := agent.ProfileHandler(pattern, handler)
```

```go
// A helper function to profile HTTP handler function execution
// by wrapping http.HandleFunc method parameters.
// Usage example:
// http.HandleFunc(agent.ProfileHandlerFunc("/some-path", someHandlerFunc))
pattern, wrappedHandlerFunc := agent.ProfileHandlerFunc(pattern, handlerFunc)
```

#### Measuring code segments

Expand All @@ -117,15 +149,16 @@ defer segment.Stop()
```

```go
// A helper function to measure HTTP handler execution by wrapping http.Handle method parameters.
// A helper function to measure HTTP handler execution by wrapping
// http.Handle method parameters.
// Usage example:
// http.Handle(agent.MeasureHandler("/some-path", someHandler))
pattern, wrappedHandler := agent.MeasureHandler(pattern, handler)
```


```go
// A helper function to measure HTTP handler function execution by wrapping http.HandleFunc method parameters.
// A helper function to measure HTTP handler function execution
// by wrapping http.HandleFunc method parameters.
// Usage example:
// http.HandleFunc(agent.MeasureHandlerFunc("/some-path", someHandlerFunc))
pattern, wrappedHandlerFunc := agent.MeasureHandlerFunc(pattern, handlerFunc)
Expand Down
70 changes: 59 additions & 11 deletions github.com/stackimpact/stackimpact-go/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,24 @@ const ErrorGroupUnrecoveredPanics string = "Unrecovered panics"
const ErrorGroupHandledExceptions string = "Handled exceptions"

type Options struct {
DashboardAddress string
ProxyAddress string
AgentKey string
AppName string
AppVersion string
AppEnvironment string
HostName string
Debug bool
ProfileAgent bool
DashboardAddress string
ProxyAddress string
AgentKey string
AppName string
AppVersion string
AppEnvironment string
HostName string
DisableAutoProfiling bool
Standalone bool
Debug bool
ProfileAgent bool
}

type Agent struct {
internalAgent *internal.Agent

spanStarted int32

// compatibility < 1.2.0
DashboardAddress string
AgentKey string
Expand All @@ -38,6 +42,7 @@ type Agent struct {
func NewAgent() *Agent {
a := &Agent{
internalAgent: internal.NewAgent(),
spanStarted: 0,
}

return a
Expand Down Expand Up @@ -78,6 +83,10 @@ func (a *Agent) Start(options Options) {
a.internalAgent.HostName = options.HostName
}

if options.DisableAutoProfiling {
a.internalAgent.AutoProfiling = false
}

if options.DashboardAddress != "" {
a.internalAgent.DashboardAddress = options.DashboardAddress
}
Expand All @@ -87,11 +96,11 @@ func (a *Agent) Start(options Options) {
}

if options.Debug {
a.internalAgent.Debug = options.Debug
a.internalAgent.Debug = true
}

if options.ProfileAgent {
a.internalAgent.ProfileAgent = options.ProfileAgent
a.internalAgent.ProfileAgent = true
}

a.internalAgent.Start()
Expand All @@ -108,6 +117,40 @@ func (a *Agent) Configure(agentKey string, appName string) {
})
}

// Use this method to instruct the agent to start and stop
// profiling. It does not guarantee that any profiler will be
// started. The decision is made by the agent based on the
// overhead constraints. The method returns Span object, on
// which the Stop() method should be called.
func (a *Agent) Profile() *Span {
s := newSpan(a)
s.start()

return s
}

// A helper function to profile HTTP handler function execution
// by wrapping http.HandleFunc method parameters.
func (a *Agent) ProfileHandlerFunc(pattern string, handlerFunc func(http.ResponseWriter, *http.Request)) (string, func(http.ResponseWriter, *http.Request)) {
return pattern, func(w http.ResponseWriter, r *http.Request) {
span := a.Profile()
defer span.Stop()

handlerFunc(w, r)
}
}

// A helper function to profile HTTP handler execution
// by wrapping http.Handle method parameters.
func (a *Agent) ProfileHandler(pattern string, handler http.Handler) (string, http.Handler) {
return pattern, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
span := a.Profile()
defer span.Stop()

handler.ServeHTTP(w, r)
})
}

// Starts measurement of execution time of a code segment.
// To stop measurement call Stop on returned Segment object.
// After calling Stop the segment is recorded, aggregated and
Expand Down Expand Up @@ -162,3 +205,8 @@ func (a *Agent) RecordAndRecoverPanic() {
a.internalAgent.RecordError(ErrorGroupRecoveredPanics, err, 1)
}
}

// Returns reported metrics in standalone mode.
func (a *Agent) ReadMetrics() []interface{} {
return a.internalAgent.ReadMetrics()
}
22 changes: 22 additions & 0 deletions github.com/stackimpact/stackimpact-go/examples/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,26 @@ func simulateLockWait() {
}
}

func simulateManualProfiling() {
for {
span := agent.Profile()
fmt.Println("Manual profile started")

// wait
time.Sleep(time.Duration(10+rand.Intn(10)) * time.Millisecond)

// cpu
for i := 0; i < 1000; i++ {
rand.Intn(1000)
}

span.Stop()
fmt.Println("Manual profile stopped")

time.Sleep(20 * time.Second)
}
}

func simulateSegments() {
for {
done1 := make(chan bool)
Expand All @@ -195,6 +215,7 @@ func simulateSegments() {
}
}


func simulateHandlerSegments() {
// start HTTP server
go func() {
Expand Down Expand Up @@ -295,6 +316,7 @@ func main() {
go simulateNetworkWait()
go simulateSyscallWait()
go simulateLockWait()
go simulateManualProfiling()
go simulateSegments()
go simulateHandlerSegments()
go simulateErrors()
Expand Down
Loading

0 comments on commit efe484a

Please sign in to comment.