mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-10-23 13:33:06 +00:00
feat: add pprof profiling controlled by ENABLE_PPROF env var
Add net/http/pprof support to both Go server (default port 6060) and ingestor (default port 6061). Profiling is off by default — only starts the pprof HTTP listener when ENABLE_PPROF=true. PPROF_PORT env var overrides the default port for each binary. Enable on staging-go in docker-compose with exposed ports 6060/6061. Not enabled on prod. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
1 parent
1619f4857e
commit
6d31cb2ad6
3 files changed
+68
-2
No files matched your search
+51
-2
@@ -8,6 +8,9 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
@@ -19,6 +22,18 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
// pprof profiling — off by default, enable with ENABLE_PPROF=true
|
||||
if os.Getenv("ENABLE_PPROF") == "true" {
|
||||
pprofPort := os.Getenv("PPROF_PORT")
|
||||
if pprofPort == "" {
|
||||
pprofPort = "6061"
|
||||
}
|
||||
go func() {
|
||||
log.Printf("[pprof] ingestor profiling at http://localhost:%s/debug/pprof/", pprofPort)
|
||||
log.Fatal(http.ListenAndServe(":"+pprofPort, nil))
|
||||
}()
|
||||
}
|
||||
|
||||
configPath := flag.String("config", "config.json", "path to config file")
|
||||
flag.Parse()
|
||||
|
||||
@@ -193,7 +208,8 @@ func handleMessage(store *Store, tag string, source MQTTSource, m mqtt.Message,
|
||||
observerID := parts[2]
|
||||
name, _ := msg["origin"].(string)
|
||||
iata := parts[1]
|
||||
if err := store.UpsertObserver(observerID, name, iata); err != nil {
|
||||
meta := extractObserverMeta(msg)
|
||||
if err := store.UpsertObserver(observerID, name, iata, meta); err != nil {
|
||||
log.Printf("MQTT [%s] observer status error: %v", tag, err)
|
||||
}
|
||||
log.Printf("MQTT [%s] status: %s (%s)", tag, firstNonEmpty(name, observerID), iata)
|
||||
@@ -260,7 +276,7 @@ func handleMessage(store *Store, tag string, source MQTTSource, m mqtt.Message,
|
||||
// Upsert observer
|
||||
if observerID != "" {
|
||||
origin, _ := msg["origin"].(string)
|
||||
if err := store.UpsertObserver(observerID, origin, region); err != nil {
|
||||
if err := store.UpsertObserver(observerID, origin, region, nil); err != nil {
|
||||
log.Printf("MQTT [%s] observer upsert error: %v", tag, err)
|
||||
}
|
||||
}
|
||||
@@ -446,6 +462,39 @@ func toFloat64(v interface{}) (float64, bool) {
|
||||
}
|
||||
}
|
||||
|
||||
// extractObserverMeta extracts hardware metadata from an MQTT status message.
|
||||
// Casts battery_mv and uptime_secs to integers (they're always whole numbers).
|
||||
func extractObserverMeta(msg map[string]interface{}) *ObserverMeta {
|
||||
meta := &ObserverMeta{}
|
||||
hasData := false
|
||||
|
||||
if v, ok := msg["battery_mv"]; ok {
|
||||
if f, ok := toFloat64(v); ok {
|
||||
iv := int(math.Round(f))
|
||||
meta.BatteryMv = &iv
|
||||
hasData = true
|
||||
}
|
||||
}
|
||||
if v, ok := msg["uptime_secs"]; ok {
|
||||
if f, ok := toFloat64(v); ok {
|
||||
iv := int64(math.Round(f))
|
||||
meta.UptimeSecs = &iv
|
||||
hasData = true
|
||||
}
|
||||
}
|
||||
if v, ok := msg["noise_floor"]; ok {
|
||||
if f, ok := toFloat64(v); ok {
|
||||
meta.NoiseFloor = &f
|
||||
hasData = true
|
||||
}
|
||||
}
|
||||
|
||||
if !hasData {
|
||||
return nil
|
||||
}
|
||||
return meta
|
||||
}
|
||||
|
||||
func firstNonEmpty(vals ...string) string {
|
||||
for _, v := range vals {
|
||||
if v != "" {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
@@ -54,6 +55,18 @@ func resolveBuildTime() string {
|
||||
}
|
||||
|
||||
func main() {
|
||||
// pprof profiling — off by default, enable with ENABLE_PPROF=true
|
||||
if os.Getenv("ENABLE_PPROF") == "true" {
|
||||
pprofPort := os.Getenv("PPROF_PORT")
|
||||
if pprofPort == "" {
|
||||
pprofPort = "6060"
|
||||
}
|
||||
go func() {
|
||||
log.Printf("[pprof] profiling UI at http://localhost:%s/debug/pprof/", pprofPort)
|
||||
log.Fatal(http.ListenAndServe(":"+pprofPort, nil))
|
||||
}()
|
||||
}
|
||||
|
||||
var (
|
||||
configDir string
|
||||
port int
|
||||
|
||||
@@ -58,12 +58,16 @@ services:
|
||||
ports:
|
||||
- "${STAGING_GO_HTTP_PORT:-82}:80"
|
||||
- "${STAGING_GO_MQTT_PORT:-1885}:1883"
|
||||
- "6060:6060" # pprof server
|
||||
- "6061:6061" # pprof ingestor
|
||||
volumes:
|
||||
- ${STAGING_DATA_DIR:-~/meshcore-staging-data}/config.json:/app/config.json:ro
|
||||
- ${STAGING_DATA_DIR:-~/meshcore-staging-data}:/app/data
|
||||
- caddy-data-staging-go:/data/caddy
|
||||
environment:
|
||||
- NODE_ENV=staging
|
||||
- ENABLE_PPROF=true
|
||||
- PPROF_PORT=6060
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/stats"]
|
||||
interval: 30s
|
||||
|
||||
Reference in new issue
Block a user