Code Monkey home page Code Monkey logo

stackimpact / stackimpact-go Goto Github PK

View Code? Open in Web Editor NEW
290.0 19.0 36.0 299 KB

DEPRECATED StackImpact Go Profiler - Production-Grade Performance Profiler: CPU, memory allocations, blocking calls, errors, metrics, and more

Home Page: https://stackimpact.com

License: Other

Go 100.00%
golang profiler agent monitoring performance-tuning performance-analysis performance-metrics profiling-library monitor-performance memory-leak-detection cpu-profiling memory-profiler hot-spot-profiles tracing go pprof

stackimpact-go's Introduction

StackImpact Go Profiler

Overview

StackImpact is a production-grade performance profiler built for both production and development environments. It gives developers continuous and historical code-level view of application performance that is essential for locating CPU, memory allocation and I/O hot spots as well as latency bottlenecks. Included runtime metrics and error monitoring complement profiles for extensive performance analysis. Learn more at stackimpact.com.

dashboard

Features

  • Continuous hot spot profiling of CPU usage, memory allocation and blocking calls.
  • Continuous latency bottleneck tracing.
  • Error and panic monitoring.
  • Health monitoring including CPU, memory, garbage collection and other runtime metrics.
  • Alerts on profile anomalies.
  • Team access.

Learn more on the features page (with screenshots).

How it works

The StackImpact profiler agent is imported into a program and used as a normal package. When the program runs, various sampling profilers are started and stopped automatically by the agent and/or programmatically using the agent methods. The agent periodically reports recorded profiles and metrics to the StackImpact Dashboard. The agent can also operate in manual mode, which should be used in development only.

Documentation

See full documentation for reference.

Requirements

Linux, OS X or Windows. Go version 1.5+.

Getting started

Create StackImpact account

Sign up for a free trial account at stackimpact.com (also with GitHub login).

Installing the agent

Install the Go agent by running

go get github.com/stackimpact/stackimpact-go

And import the package github.com/stackimpact/stackimpact-go in your application.

Configuring the agent

Start the agent by specifying the agent key and application name. The agent key can be found in your account's Configuration section.

agent := stackimpact.Start(stackimpact.Options{
	AgentKey: "agent key here",
	AppName: "MyGoApp",
})

All initialization options:

  • AgentKey (Required) The access key for communication with the StackImpact servers.
  • AppName (Required) A name to identify and group application data. Typically, a single codebase, deployable unit or executable module corresponds to one application. Sometimes also referred as a service.
  • AppVersion (Optional) Sets application version, which can be used to associate profiling information with the source code release.
  • 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.
  • HTTPClient (Optional) An http.Client instance to be used instead of the default client for reporting data to Dashboard servers.
  • DisableAutoProfiling (Optional) If set to true, disables the default automatic profiling and reporting. Focused or manual profiling should be used instead. Useful for environments without support for timers or background tasks.
  • Debug (Optional) Enables debug logging.
  • Logger (Optional) A log.Logger instance to be used instead of default STDOUT logger.

Basic example

package main

import (
	"fmt"
	"net/http"

	"github.com/stackimpact/stackimpact-go"
)

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello world!")
}

func main() {
	agent := stackimpact.Start(stackimpact.Options{
		AgentKey: "agent key here",
		AppName: "Basic Go Server",
		AppVersion: "1.0.0",
		AppEnvironment: "production",
	})

	http.HandleFunc(agent.ProfileHandlerFunc("/", handler)) 
	http.ListenAndServe(":8080", nil)
}

Focused profiling

Focused 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 following methods can be used. In addition to more precise profiling, timing information will also be reported for the profiled spans.

// 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();
// This method is similar to the Profile() method. It additionally
// allows to specify a span name to group span timing measurements.
span := agent.ProfileWithName(name);
defer span.Stop();
// 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)
// 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)

Error reporting

To monitor exceptions and panics with stack traces, the error recording API can be used.

Recording handled errors:

// Aggregates and reports errors with regular intervals.
agent.RecordError(someError)

Recording panics without recovering:

// Aggregates and reports panics with regular intervals.
defer agent.RecordPanic()

Recording and recovering from panics:

// Aggregates and reports panics with regular intervals. This function also
// recovers from panics.
defer agent.RecordAndRecoverPanic()

Manual profiling

Manual profiling should not be used in production!

By default, the agent starts and stops profiling automatically. Manual profiling allows to start and stop profilers directly. It is suitable for profiling short-lived programs and should not be used for long-running production applications. Automatic profiling should be disabled with DisableAutoProfiling: true.

// Start CPU profiler.
agent.StartCPUProfiler();
// Stop CPU profiler and report the recorded profile to the Dashboard.
// Automatic profiling should be disabled.
agent.StopCPUProfiler();
// Start blocking call profiler.
agent.StartBlockProfiler();
// Stop blocking call profiler and report the recorded profile to the Dashboard.
agent.StopBlockProfiler();
// Report current allocation profile to the Dashboard.
agent.ReportAllocationProfile();

Analyzing performance data in the Dashboard

Once your application is restarted, you can start observing continuously recorded CPU, memory, I/O, and other hot spot profiles, execution bottlenecks as well as process metrics in the Dashboard.

Troubleshooting

To enable debug logging, add Debug: true to startup options. If the debug log doesn't give you any hints on how to fix a problem, please report it to our support team in your account's Support section.

Overhead

The agent overhead is measured to be less than 1% for applications under high load.

stackimpact-go's People

Contributors

dmelikyan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stackimpact-go's Issues

Replacement

Was there a decent alternative to this at all?

The StackImpact dashboard was totally perfect and I've not seen anything match it for Go applications anywhere else.

Anyone find anything?

App Engine support

Hey guys,
I was looking into this and noticed that doesn’t seem to be App Engine compatible. On App Engine:

  1. the syscall library isn’t available.
  2. the standard HTTP client isn’t available, but requests can create and provide one while active using their context. — See here, for example: https://github.com/stripe/stripe-go#google-appengine

Is it possible that support could be added? There are a lot of Go applications running on App Engine.

what do you mean "DEPRECATED" ?

DEPRECATED StackImpact Go Profiler - Production-Grade Performance Profiler: CPU, memory allocations, blocking calls, errors, metrics, and more

Memory leaks

I had added stackimpact to my program just to find where I have memory leaks
but unfortunately I experienced more memory leaks as before adding stackimpact.

There is only one of leak that I have screenshoted (I have watched few different points):

ROUTINE ======================== github.com/stackimpact/stackimpact-go/internal.(*APIRequest).post in /home/go/.gvm/pkgsets/go1.7/global/src/git
hub.com/stackimpact/stackimpact-go/internal/api_request.go
  512.14kB   478.35MB (flat, cum) 13.72% of Total
         .          .     24:   return ar
         .          .     25:}
         .          .     26:
         .          .     27:func (ar *APIRequest) post(endpoint string, payload map[string]interface{}) (map[string]interface{}, error) {
         .          .     28:   reqBody := map[string]interface{}{
  512.14kB   512.14kB     29:           "runtime_type":    "go",
         .          .     30:           "runtime_version": runtime.Version(),
         .          .     31:           "agent_version":   AgentVersion,
         .          .     32:           "app_name":        ar.agent.AppName,
         .          .     33:           "app_version":     ar.agent.AppVersion,
         .          .     34:           "app_environment": ar.agent.AppEnvironment,
         .          .     35:           "host_name":       ar.agent.HostName,
         .          .     36:           "build_id":        ar.agent.buildId,
         .          .     37:           "run_id":          ar.agent.runId,
         .          .     38:           "run_ts":          ar.agent.runTs,
         .          .     39:           "sent_at":         time.Now().Unix(),
         .     8.02MB     40:           "payload":         payload,
         .          .     41:   }
         .          .     42:
         .          .     43:   reqBodyJson, _ := json.Marshal(reqBody)
         .          .     44:
         .   469.83MB     45:   var buf bytes.Buffer
         .          .     46:   w := gzip.NewWriter(&buf)
         .          .     47:   w.Write(reqBodyJson)
         .          .     48:   w.Close()
         .          .     49:
         .          .     50:   url := ar.agent.DashboardAddress + "/agent/v1/" + endpoint

So I have removed stackimpact and memory leaks decreased significally

Don't see stackimpact.Options() and

I am using one agent and I can see the updates in the dashboard. I can use the following APIs:

agent := stackimpact.NewAgent()
agent.Configure("key", "MyGoApp")

But I am not able to use other APIs as mentioned in the examples such as:

stackimpact.Options() or agent.Start()

segment := agent.MeasureSegment("Segment1")
defer segment.Stop()

subsegment := agent.MeasureSubsegment("Segment1", "Subsegment1")
defer subsegment.Stop()

agent not working inside a container

I have a simple application using stackimpact agent for testing, but it can't work when I run this app inside a container.
I found that the api address is agent-api.stackimpact.com and I usetcpdump to capture the packets but they are all encrypted, but I did see the traffic.

That's the simple program:

package main

import (
	"fmt"
	"net/http"

	"github.com/stackimpact/stackimpact-go"
)

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello world!")
}

func main() {
	go func() {
		agent := stackimpact.Start(stackimpact.Options{
			AgentKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
			AppName:  "hello-world-00",
		})
		span := agent.Profile()
		defer span.Stop()
	}()

	http.HandleFunc("/", handler)
	http.ListenAndServe(":8077", nil)
}

Is there anything I missed?

image

Race in stackimpact

Running 2.0.1.

==================
==================
WARNING: DATA RACE
Read at 0x00c420694000 by goroutine 199:
  math/rand.(*rngSource).Int63()
      /usr/local/Cellar/go/1.8.3/libexec/src/math/rand/rng.go:231 +0x3f
  math/rand.(*Rand).Int63()
      /usr/local/Cellar/go/1.8.3/libexec/src/math/rand/rand.go:81 +0x51
  math/rand.(*Rand).Int31()
      /usr/local/Cellar/go/1.8.3/libexec/src/math/rand/rand.go:95 +0x38
  math/rand.(*Rand).Int31n()
      /usr/local/Cellar/go/1.8.3/libexec/src/math/rand/rand.go:130 +0x62
  math/rand.(*Rand).Intn()
      /usr/local/Cellar/go/1.8.3/libexec/src/math/rand/rand.go:144 +0x52
  <company>/vendor/github.com/stackimpact/stackimpact-go/internal.(*Agent).uuid()
      <company>/vendor/github.com/stackimpact/stackimpact-go/internal/agent.go:247 +0xd9
  <company>/vendor/github.com/stackimpact/stackimpact-go/internal.(*Metric).createMeasurement()
      <company>/vendor/github.com/stackimpact/stackimpact-go/internal/metric.go:388 +0xbb
  <company>/vendor/github.com/stackimpact/stackimpact-go/internal.(*CPUReporter).report()
      <company>/vendor/github.com/stackimpact/stackimpact-go/internal/cpu_reporter.go:209 +0x3bf
  <company>/vendor/github.com/stackimpact/stackimpact-go/internal.(*CPUReporter).start.func2()
      <company>/vendor/github.com/stackimpact/stackimpact-go/internal/cpu_reporter.go:88 +0x41
  <company>/vendor/github.com/stackimpact/stackimpact-go/internal.NewTimer.func1.1()
      <company>/vendor/github.com/stackimpact/stackimpact-go/internal/agent.go:308 +0x150

Previous write at 0x00c420694000 by goroutine 79:
  math/rand.(*rngSource).Int63()
      /usr/local/Cellar/go/1.8.3/libexec/src/math/rand/rng.go:231 +0x58
  math/rand.(*Rand).Int63()
      /usr/local/Cellar/go/1.8.3/libexec/src/math/rand/rand.go:81 +0x51
  math/rand.(*Rand).Int31()
      /usr/local/Cellar/go/1.8.3/libexec/src/math/rand/rand.go:95 +0x38
  math/rand.(*Rand).Int31n()
      /usr/local/Cellar/go/1.8.3/libexec/src/math/rand/rand.go:130 +0x62
  math/rand.(*Rand).Intn()
      /usr/local/Cellar/go/1.8.3/libexec/src/math/rand/rand.go:144 +0x52
  <company>/vendor/github.com/stackimpact/stackimpact-go/internal.(*Agent).uuid()
      <company>/vendor/github.com/stackimpact/stackimpact-go/internal/agent.go:247 +0xd9
  <company>/vendor/github.com/stackimpact/stackimpact-go/internal.(*Metric).createMeasurement()
      <company>/vendor/github.com/stackimpact/stackimpact-go/internal/metric.go:388 +0xbb
  <company>/vendor/github.com/stackimpact/stackimpact-go/internal.(*ProcessReporter).reportMetric()
      <company>/vendor/github.com/stackimpact/stackimpact-go/internal/process_reporter.go:72 +0x181
  <company>/vendor/github.com/stackimpact/stackimpact-go/internal.(*ProcessReporter).report()
      <company>/vendor/github.com/stackimpact/stackimpact-go/internal/process_reporter.go:136 +0x98d
  <company>/vendor/github.com/stackimpact/stackimpact-go/internal.(*ProcessReporter).start.func1()
      <company>/vendor/github.com/stackimpact/stackimpact-go/internal/process_reporter.go:48 +0x41
  <company>/vendor/github.com/stackimpact/stackimpact-go/internal.NewTimer.func1.1()
      <company>/vendor/github.com/stackimpact/stackimpact-go/internal/agent.go:308 +0x150

Goroutine 199 (running) created at:
  <company>/vendor/github.com/stackimpact/stackimpact-go/internal.NewTimer.func1()
      <company>/vendor/github.com/stackimpact/stackimpact-go/internal/agent.go:313 +0x267

Goroutine 79 (running) created at:
  <company>/vendor/github.com/stackimpact/stackimpact-go/internal.NewTimer.func1()
      <company>/vendor/github.com/stackimpact/stackimpact-go/internal/agent.go:313 +0x267
==================```

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.