Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

incorrect path when using groups #187

Closed
FedeBev opened this issue Dec 11, 2023 · 9 comments · Fixed by #197
Closed

incorrect path when using groups #187

FedeBev opened this issue Dec 11, 2023 · 9 comments · Fixed by #197

Comments

@FedeBev
Copy link

FedeBev commented Dec 11, 2023

Hi there,
thanks for this work!

When using a.Group the path is not correct.

With the following app

app := fiber.New()

prometheus := fiberprometheus.NewWithLabels(labels, strings.ReplaceAll(Component, "-", "_"), "http")
prometheus.RegisterAt(app, "/metrics")
app.Use(prometheus.Middleware)

public := app.Group("/public")

public.Get("/somepath", func(c *fiber.Ctx) error {
   ...
})

The following metrics are created when calling GET /public/somepath

lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="2e-09"} 0
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="5e-09"} 0
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="1e-08"} 0
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="2e-08"} 0
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="5e-08"} 0
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="1e-07"} 0
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="2e-07"} 0
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="5e-07"} 0
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="1e-06"} 0
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="2e-06"} 0
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="5e-06"} 0
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="1e-05"} 0
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="2e-05"} 0
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="5e-05"} 0
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.0001"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.0002"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.0005"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.001"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.002"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.005"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.01"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.02"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.05"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.1"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.2"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.5"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="1"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="2"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="5"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="10"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="15"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="20"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="30"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="+Inf"} 1
lessons_cdn_http_request_duration_seconds_sum{build="development",method="GET",path="/public",status_code="401",version="development"} 8.253e-05
lessons_cdn_http_request_duration_seconds_count{build="development",method="GET",path="/public",status_code="401",version="development"} 1

I'd expect to see /public/somepath in the path label.

Thanks!

@ansrivas
Copy link
Owner

ansrivas commented Dec 11, 2023

Hey @FedeBev, thanks for reporting this.
So, in your example I just moved the middleware mount a bit later, please try and see if this solves your issue.

	prometheus := fiberprometheus.New("my-service-name")

	public := app.Group("/public")  // Here declared the Group before calling RegisterAt and app.Use

	prometheus.RegisterAt(app, "/metrics")
	app.Use(prometheus.Middleware)

	public.Get("/somepath", func(c *fiber.Ctx) error {
		return c.SendString("Hello World from somepath")
	})

And corresponding to that, I can see the following:

http_request_duration_seconds_bucket{method="GET",path="/public/somepath",service="my-service-name",status_code="200",le="1e-09"} 0
http_request_duration_seconds_bucket{method="GET",path="/public/somepath",service="my-service-name",status_code="200",le="2e-09"} 0
http_request_duration_seconds_bucket{method="GET",path="/public/somepath",service="my-service-name",status_code="200",le="5e-09"} 0
http_request_duration_seconds_bucket{method="GET",path="/public/somepath",service="my-service-name",status_code="200",le="1e-08"} 0
http_request_duration_seconds_bucket{method="GET",path="/public/somepath",service="my-service-name",status_code="200",le="2e-08"} 0
http_request_duration_seconds_bucket{method="GET",path="/public/somepath",service="my-service-name",status_code="200",le="5e-08"} 0
http_request_duration_seconds_bucket{method="GET",path="/public/somepath",service="my-service-name",status_code="200",le="1e-07"} 0
http_request_duration_seconds_bucket{method="GET",path="/public/somepath",service="my-service-name",status_code="200",le="2e-07"} 0
http_request_duration_seconds_bucket{method="GET",path="/public/somepath",service="my-service-name",status_code="200",le="5e-07"} 0
http_request_duration_seconds_bucket{method="GET",path="/public/somepath",service="my-service-name",status_code="200",le="1e-06"} 0
http_request_duration_seconds_bucket{method="GET",path="/public/somepath",service="my-service-name",status_code="200",le="2e-06"} 0
http_request_duration_seconds_bucket{method="GET",path="/public/somepath",service="my-service-name",status_code="200",le="5e-06"} ```

@FedeBev
Copy link
Author

FedeBev commented Dec 12, 2023

Interesting, I tried your suggestion but I'm still seeing the same

app := fiber.New()

public := app.Group("/public")
admin := app.Group("/admin")

prometheus := fiberprometheus.NewWithLabels(labels, strings.ReplaceAll(Component, "-", "_"), "http")
prometheus.RegisterAt(app, "/metrics")

app.Use(prometheus.Middleware)

public.Get("/somepath", func(c *fiber.Ctx) error {
   ...
})
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.0001"} 0
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.0002"} 0
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.0005"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.001"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.002"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.005"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.01"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.02"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.05"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.1"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.2"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="0.5"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="1"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="2"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="5"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="10"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="15"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="20"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="30"} 1
lessons_cdn_http_request_duration_seconds_bucket{build="development",method="GET",path="/public",status_code="401",version="development",le="+Inf"} 1

@ansrivas
Copy link
Owner

This is certainly strange, here is the complete example, can you please try this:

package main

import (
	"github.com/ansrivas/fiberprometheus/v2"  // v2.6.1
	"github.com/gofiber/fiber/v2"    // v2.48.0
)

func main() {
	app := fiber.New()

	public := app.Group("/public")
	admin := app.Group("/admin")

	prometheus := fiberprometheus.NewWithLabels(map[string]string{
		"component": "fiberprometheus",
	}, "somesystem", "http")

	prometheus.RegisterAt(app, "/metrics")
	app.Use(prometheus.Middleware)

	public.Get("/somepath", func(c *fiber.Ctx) error {
		return c.SendString("Hello World from somepath")
	})
	admin.Get("/adminpath", func(c *fiber.Ctx) error {
		return c.SendString("Hello World from adminpath")
	})

	app.Listen(":3000")
}
somesystem_http_request_duration_seconds_bucket{component="fiberprometheus",method="GET",path="/admin/adminpath",status_code="200",le="1"} 1
somesystem_http_request_duration_seconds_bucket{component="fiberprometheus",method="GET",path="/admin/adminpath",status_code="200",le="2"} 1
somesystem_http_request_duration_seconds_bucket{component="fiberprometheus",method="GET",path="/admin/adminpath",status_code="200",le="5"} 1
somesystem_http_request_duration_seconds_bucket{component="fiberprometheus",method="GET",path="/admin/adminpath",status_code="200",le="10"} 1
somesystem_http_request_duration_seconds_bucket{component="fiberprometheus",method="GET",path="/admin/adminpath",status_code="200",le="15"} 1
somesystem_http_request_duration_seconds_bucket{component="fiberprometheus",method="GET",path="/admin/adminpath",status_code="200",le="20"} 1
somesystem_http_request_duration_seconds_bucket{component="fiberprometheus",method="GET",path="/admin/adminpath",status_code="200",le="30"} 1
somesystem_http_request_duration_seconds_bucket{component="fiberprometheus",method="GET",path="/admin/adminpath",status_code="200",le="+Inf"} 1
somesystem_http_request_duration_seconds_sum{component="fiberprometheus",method="GET",path="/admin/adminpath",status_code="200"} 2.1273e-05
somesystem_http_request_duration_seconds_count{component="fiberprometheus",method="GET",path="/admin/adminpath",status_code="200"} 1
somesystem_http_request_duration_seconds_bucket{component="fiberprometheus",method="GET",path="/public/somepath",status_code="200",le="1e-09"} 0
somesystem_http_request_duration_seconds_bucket{component="fiberprometheus",method="GET",path="/public/somepath",status_code="200",le="2e-09"} 0
somesystem_http_request_duration_seconds_bucket{component="fiberprometheus",method="GET",path="/public/somepath",status_code="200",le="5e-09"} 0
somesystem_http_request_duration_seconds_bucket{component="fiberprometheus",method="GET",path="/public/somepath",status_code="200",le="1e-08"} 0
somesystem_http_request_duration_seconds_bucket{component="fiberprometheus",method="GET",path="/public/somepath",status_code="200",le="2e-08"} 0
somesystem_http_request_duration_seconds_bucket{component="fiberprometheus",method="GET",path="/public/somepath",status_code="200",le="5e-08"} 0
somesystem_http_request_duration_seconds_bucket{component="fiberprometheus",method="GET",path="/public/somepath",status_code="200",le="1e-07"} 0

@FedeBev
Copy link
Author

FedeBev commented Dec 13, 2023

I think I got what's going on

I think I was able to identify when the path is not correct (at least some cases)

  • let's say public app has a middleware before the routes, if that middleware returns, the path is gonna be only /public
public := app.Group("/public")

prometheus := fiberprometheus.NewWithLabels(labels, strings.ReplaceAll(Component, "-", "_"), "http")
prometheus.RegisterAt(app, "/metrics")
app.Use(prometheus.Middleware)

// if this returns, the path in the metric is /public instead of /lesson/:id/:page
public.Use(auth.Middleware(datasource)) 
public.Get("/lesson/:id/:page", func(c *fiber.Ctx) error {})
  • if a default 404 is returned by fiber because a path does not exists path will be /

Copy link

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 5 days.

Copy link

This issue was closed because it has been stalled for 10 days with no activity.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Feb 23, 2024
@ansrivas ansrivas reopened this Feb 23, 2024
@Fesaa
Copy link

Fesaa commented Mar 11, 2024

Heya!

I've noticed this as well with one of my apps. The comment above was what I noticed as well, the / paths were all cache hits for me.

I've added a test here, that makes it super clear. https://github.com/Fesaa/fiberprometheus/commit/e748341c6afd9aada719e7aa50c318fc51a0aaa9

I'm looking around a bit, but am not seeing a solution without changes within fiber at the moment.

Am planning to look a bit longer as it annoys me a lot as it makes my grafana graphs wrong 😄

@gaby
Copy link
Contributor

gaby commented Mar 17, 2024

@FedeBev @Fesaa I submitted a PR that includes the new cache metrics from @Fesaa and also fixes the issues @FedeBev was running into with the path's. I also fixed a concurrency issues happening with the default global registry.

This middleware is going to be migrated to https://github.com/gofiber/contrib in the next week or so. Maintenance will be done by the GoFiber team (I'm one of the maintainers).

@gaby
Copy link
Contributor

gaby commented Mar 18, 2024

@FedeBev @Fesaa Migration has started and is being tracked here gofiber/contrib#1032

I have a TODO list of tasks before making a first release. Basically trying to make the middleware easier to use and more feature complete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants