🚀 Deploy Code Profiling and Usage Monitoring for Go
Deploy GermainUX Go profiling by exposing an access-controlled Go pprof endpoint, importing the GermainUX Go monitoring configuration, and running the Golang wizard.
The GermainUX Engine periodically retrieves the approved profiles and sends them to GermainUX for code-performance analysis.
⚙️ Components
|
Component |
Role |
|---|---|
|
Analyzes Go CPU, heap, allocation, goroutine, mutex, blocking, and other available runtime profiles. |
|
|
Connects to the protected Go profiling endpoint and collects profiles on the configured schedule. |
📋 Prerequisites
Before deployment, confirm:
|
Requirement |
|---|
|
A GermainUX Engine is installed and running. |
|
The Engine can reach the Go application’s profiling endpoint. |
|
The application can import Go’s |
|
A private listening address and port are available. |
|
Firewall rules can restrict access to authorized Engine hosts. |
|
TLS or an authenticated proxy is available when required. |
|
The application team has approved production profiling. |
|
The profiling schedule and expected overhead have been reviewed. |
|
The GermainUX Go configuration files are available. |
🛡️ Security requirements
Go pprof endpoints expose sensitive runtime and application information. Some profiles also consume CPU while they are generated.
Do not expose /debug/pprof/ publicly.
Protect it by:
-
Binding it to a loopback or private interface.
-
Allowing connections only from the GermainUX Engine.
-
Using firewall rules.
-
Using TLS and an authenticated reverse proxy when required.
-
Avoiding public DNS exposure.
-
Limiting profile duration and frequency.
-
Restricting access to profiling results in GermainUX.
-
Reviewing application overhead before expanding deployment.
Do not bind the profiler to every network interface unless access is independently restricted and approved.
Add pprof to the Go application
Import the standard net/http/pprof package:
import (
_ "net/http/pprof"
)
The blank import registers the standard pprof handlers on Go’s default HTTP request multiplexer.
Start a dedicated profiling listener
A dedicated listener allows the profiling endpoint to be secured separately from the application’s public API.
package main
import (
"log"
"net/http"
_ "net/http/pprof"
"time"
)
func startProfiler() {
server := &http.Server{
Addr: "127.0.0.1:6060",
ReadHeaderTimeout: 5 * time.Second,
}
go func() {
if err := server.ListenAndServe(); err != nil &&
err != http.ErrServerClosed {
log.Printf("pprof listener failed: %v", err)
}
}()
}
Call the function during application startup:
func main() {
startProfiler()
// Start the application.
}
The loopback address in this example is reachable only from the same host. Use it when the GermainUX Engine runs locally or accesses the endpoint through an approved local proxy.
For a remote Engine, bind the listener to a private interface approved by the network and security teams:
Addr: "<private-ip>:6060"
Do not use a public interface without authentication, encryption, and network restrictions.
Applications using a custom HTTP router
Importing net/http/pprof registers handlers on http.DefaultServeMux.
If the application uses another router, either:
-
Run a separate listener with
http.DefaultServeMux, or -
Explicitly register the required
pprofhandlers with the application’s router.
A separate protected listener is generally easier to secure and prevents profiling routes from being exposed through the public application listener.
Validate the profiling endpoint
From the GermainUX Engine host or another authorized diagnostic host, verify the profile index:
curl http://<private-go-host>:6060/debug/pprof/
Validate specific profiles:
curl http://<private-go-host>:6060/debug/pprof/heap
curl http://<private-go-host>:6060/debug/pprof/goroutine
Validate a short CPU profile:
curl \
--output profile.out \
"http://<private-go-host>:6060/debug/pprof/profile?seconds=5"
Use the approved HTTPS URL and authentication options when the endpoint is protected by a proxy.
Do not run long CPU profiles during peak production activity without prior approval.
Available profiles
The available profiles depend on the Go version and runtime configuration.
Common profiles include:
|
Profile |
Purpose |
|---|---|
|
|
CPU activity collected over a specified period |
|
|
Current live heap allocations |
|
|
Historical memory allocations |
|
|
Current goroutine stacks |
|
|
Blocking activity when block profiling is enabled |
|
|
Mutex contention when mutex profiling is enabled |
|
|
Operating-system thread creation |
|
|
Application command-line information |
Some profiles require application runtime settings to collect useful data.
Enable optional runtime profiles
Block and mutex profiles may require explicit runtime configuration:
import "runtime"
func configureRuntimeProfiling() {
runtime.SetBlockProfileRate(1)
runtime.SetMutexProfileFraction(1)
}
These settings can add overhead. Enable them only when required, validate the impact, and use sampling values appropriate for the application.
Do not enable maximum-detail profiling across every production instance without testing.
Containerized Go applications
When the Go application runs in Docker:
-
Expose the profiler only to an internal Docker network.
-
Do not publish the profiler port to the public host interface.
-
Ensure the GermainUX Engine can reach the container or an approved internal proxy.
-
Account for container replacement and dynamic addressing.
-
Use service names, labels, or stable internal endpoints where possible.
-
Apply container and host firewall restrictions.
The profiling listener must not be included in a public ingress route.
Kubernetes applications
For Kubernetes:
-
Expose
pprofonly through an internal Service or approved proxy. -
Apply NetworkPolicy restrictions.
-
Do not route the endpoint through public ingress.
-
Use TLS and authentication where required.
-
Determine whether every pod or only selected pods should be profiled.
-
Use stable application, namespace, workload, pod, and version metadata.
-
Review the impact of profiling multiple replicas.
A separate monitor may be required for each target instance or a selected representative subset.
Import the GermainUX Go configuration
The Go monitoring seed files are available in the GermainUX service distribution:
[service-distribution]/install/configuration/golang/
Import these files:
|
File |
Purpose |
|---|---|
|
|
Go profiling component definitions |
|
|
Go profiling KPIs |
|
|
Go root-cause-analysis configuration |
Optionally import:
|
File |
Purpose |
|---|---|
|
|
Preconfigured Go dashboard |
Use the configuration import mechanism provided by the installed GermainUX version and select Merge when required to preserve existing configuration.
Back up the GermainUX configuration before importing seed data.
Run the Golang wizard
-
Sign in to Germain Workspace.
-
Open the left navigation menu.
-
Select Wizards.
-
Select Golang.
-
Select or create the monitored server.
-
Enter the protected
pprofport. -
Select the monitored application.
-
Enter the read timeout.
-
Continue to the advanced configuration.
-
Select Skip when no application-specific customization is required.
-
Enter a descriptive monitor name.
-
Select the monitoring node.
-
Select the GermainUX Engine.
-
Configure the execution schedule.
-
Review the configuration.
-
Select Finish.
The Engine must be able to reach the profiling endpoint using the exact hostname and port configured in the wizard.
Configure the read timeout
The read timeout must allow enough time for the selected profile to complete and transfer.
Consider:
-
CPU profile duration.
-
Application load.
-
Network latency.
-
Profile size.
-
Proxy timeout.
-
TLS and authentication overhead.
A timeout shorter than the CPU profile duration causes collection to fail. Avoid an unnecessarily long timeout that delays detection of an unreachable endpoint.
Configure the collection schedule
Profiling continuously at high frequency can affect the monitored application.
Choose a schedule based on:
-
Application criticality.
-
Number of monitored instances.
-
Required detection speed.
-
CPU profile duration.
-
Expected profile size.
-
GermainUX Engine capacity.
-
Application overhead.
-
Data-retention requirements.
Start with a limited schedule and representative instances. Increase coverage only after measuring production impact.
Validate the GermainUX deployment
After completing the wizard:
-
Go to Germain Workspace → Settings -> Germain → State.
-
Locate the Go profiling monitor.
-
Confirm that it is enabled.
-
Wait for the configured schedule to execute.
-
Confirm that the monitor completes successfully.
-
Open the Go profiling KPIs.
-
Verify that CPU, heap, allocation, or goroutine data appears.
-
Confirm the application, server, instance, and environment metadata.
-
Compare a selected profile with an approved Go profiling tool.
-
Measure application CPU, memory, and response-time overhead.
Troubleshooting
The profiling endpoint is unavailable
Verify:
-
The Go application imported
net/http/pprof. -
The profiling listener started.
-
The correct interface and port are configured.
-
The Engine can resolve the hostname.
-
Firewall and NetworkPolicy rules permit the Engine.
-
The endpoint is not restricted to loopback when the Engine is remote.
-
TLS and authentication are configured correctly.
-
A reverse proxy is forwarding
/debug/pprof/.
The index works but profiles are missing
Verify:
-
The Go runtime exposes the requested profile.
-
Optional block or mutex profiling is enabled when required.
-
The installed Go version supports the profile.
-
The wizard is configured for a supported profile.
-
The application has generated relevant runtime activity.
CPU-profile collection times out
Verify:
-
The read timeout exceeds the requested CPU-profile duration.
-
Proxy and load-balancer timeouts are long enough.
-
The application remains responsive.
-
The network permits the complete response.
-
The selected profile duration is appropriate.
Profiles are associated with the wrong instance
Verify:
-
Each monitor targets the intended host and port.
-
Application and environment names are correct.
-
Containers or pods use stable metadata.
-
A load balancer is not distributing profile requests among different instances.
-
Each replica is monitored directly when instance-level attribution is required.
Profiling affects application performance
Reduce:
-
CPU profile duration.
-
Collection frequency.
-
Number of profiled instances.
-
Block or mutex sampling detail.
-
Concurrent profile collection.
Disable optional profiles and confirm whether performance returns to normal.
Privacy and security
Runtime profiles can reveal:
-
Function and package names.
-
Source-code structure.
-
Stack traces.
-
Command-line information.
-
Internal service names.
-
Memory and execution behavior.
Protect this information by:
-
Restricting the endpoint.
-
Encrypting remote access.
-
Limiting GermainUX permissions.
-
Applying appropriate retention.
-
Avoiding public profile URLs.
-
Auditing profile access.
-
Reviewing the profiling configuration after application changes.
Deployment and configuration
|
For your Go environment |
|---|
|
Review Go Application Monitoring. |
|
Deploy the GermainUX Engine. |
|
Add an access-controlled Go |
|
Restrict the profiler endpoint to authorized GermainUX Engine hosts. |
|
Import the Go component, KPI, and root-cause-analysis configuration files. |
|
Run the Golang wizard. |
|
Configure the read timeout and collection schedule. |
|
Validate the monitor in Germain State. |
|
Configure File and Log Monitoring for Go errors and panics. |
|
Configure API, database, dependency, operating-system, Docker, or Kubernetes monitoring as required. |
|
Configure KPIs, SLAs, Watches, reports, and approved actions. |
|
Validate security and profiling overhead before production rollout. |
ℹ️ Get Help
The Germain Team can help you set this up. Contact GermainUX Support.
Component: Engine, JS Profiler, Mobile, RPA Bot Recorder, RUM JS, RUM Extension
Feature Availability: 2017.1 or later