alibaba / sentinel-golang

Sentinel Go enables reliability and resiliency for Go microservices
https://sentinelguard.io/
Apache License 2.0
2.78k stars 439 forks source link

[BUG] Metric exporter's init func leads to http nil handler error #558

Open flearc opened 9 months ago

flearc commented 9 months ago

Issue Description

Type: bug report

Describe what happened

When attempting to enable the metric exporter, a "http nil handler" error is reported. Additionally, the app name is not correctly set when the exporter works fine (Similar to issue 453).

These issues come from that the exporter module's init function being executed before the main function.

During the exporter initialization, the HttpAddr and HttpPath in MetricExporterConfig remain empty. As a result, the exporter variable will always be newEmptyExporter, and app variable is always assigned the default value unknown_go_service' leading to incorrect label values.

func init() {
    if config.MetricExportHTTPAddr() != "" {
        exporter = newPrometheusExporter()
    } else {
        exporter = newEmptyExporter()
    }

    host, _ = os.Hostname()
    if host == "" {
        host = "unknown"
    }
    app = config.AppName()
    pid = strconv.Itoa(os.Getpid())
    namespace = "sentinel_go"
}

I recommend to add init steps in initCoreComponents. Just let the two variable to be correctly set when the initCoreComponents executes.

Describe what you expected to happen

Metric exporter works correctly.

How to reproduce it (as minimally and precisely as possible)

  1. In example/flow/qps/qps_limit_example.go, add the following exporter config:
index ee726a7..f662e3f 100644
--- a/example/flow/qps/qps_limit_example.go
+++ b/example/flow/qps/qps_limit_example.go
@@ -33,6 +33,8 @@ func main() {
        conf := config.NewDefaultConfig()
        // for testing, logging output to console
        conf.Sentinel.Log.Logger = logging.NewConsoleLogger()
+       conf.Sentinel.Exporter.Metric.HttpAddr = ":8080"
+       conf.Sentinel.Exporter.Metric.HttpPath = "/metrics"
        err := sentinel.InitWithConfig(conf)
        if err != nil {
                log.Fatal(err)
  1. Run the example with go run example/flow/qps/qps_limit_example.go
  1. Add the same config as above in example/flow/qps/qps_limit_example.go.

  2. Modify exporter/metric/exporter.go as follows to prevent the nil http handler error:

    diff --git a/exporter/metric/exporter.go b/exporter/metric/exporter.go
    index 801ee0c..4983f67 100644
    --- a/exporter/metric/exporter.go
    +++ b/exporter/metric/exporter.go
    @@ -33,11 +33,7 @@ var (
    )
    
    func init() {
    -       if config.MetricExportHTTPAddr() != "" {
    -               exporter = newPrometheusExporter()
    -       } else {
    -               exporter = newEmptyExporter()
    -       }
    +       exporter = newPrometheusExporter()
    
        host, _ = os.Hostname()
        if host == "" {
  3. Run the example with go run example/flow/qps/qps_limit_example.go

Tell us your environment

macos

Anything else we need to know?