-
-
Notifications
You must be signed in to change notification settings - Fork 161
🔥 feat: Prometheus middleware #1834
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
base: main
Are you sure you want to change the base?
Changes from all commits
cc25e5d
ea47098
81f2d3f
217ce8e
841584b
cdf6431
b35b379
e210b03
02fbddc
7fe5a88
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| name: "Test Prometheus" | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
| - main | ||
| paths: | ||
| - 'v3/prometheus/**/*.go' | ||
| - 'v3/prometheus/go.mod' | ||
| pull_request: | ||
| paths: | ||
| - 'v3/prometheus/**/*.go' | ||
| - 'v3/prometheus/go.mod' | ||
|
|
||
| jobs: | ||
| Tests: | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| matrix: | ||
| go-version: | ||
| - 1.25.x | ||
| - 1.26.x | ||
| steps: | ||
| - name: Fetch Repository | ||
| uses: actions/checkout@v6 | ||
| - name: Install Go | ||
| uses: actions/setup-go@v6 | ||
| with: | ||
| go-version: '${{ matrix.go-version }}' | ||
| - name: Run Test | ||
| working-directory: ./v3/prometheus | ||
| run: go test -v -race ./... | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,7 @@ use ( | |
| ./v3/opa | ||
| ./v3/otel | ||
| ./v3/paseto | ||
| ./v3/prometheus | ||
| ./v3/sentry | ||
| ./v3/socketio | ||
| ./v3/swaggerui | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,106 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Prometheus | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Prometheus middleware for [Fiber v3](https://github.com/gofiber/fiber) based on [ansrivas/fiberprometheus](https://github.com/ansrivas/fiberprometheus). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|  | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [](https://gofiber.io/discord) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Following metrics are available by default: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```text | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| http_requests_total | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| http_requests_status_class_total | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| http_request_duration_seconds | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| http_requests_in_progress | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| http_request_size_bytes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| http_response_size_bytes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| `http_requests_in_progress` exposes both the HTTP method and normalized | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| route path so you can pinpoint which handlers are currently running. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > [!NOTE] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > The middleware requires Go 1.25 or newer and Fiber v3 (currently RC). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
gaby marked this conversation as resolved.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## 🚀 Installation | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| go get github.com/gofiber/contrib/v3/prometheus | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ## 📄 Example | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ```go | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package main | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fiberprometheus "github.com/gofiber/contrib/v3/prometheus" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/gofiber/fiber/v3" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func main() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| app := fiber.New() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| app.Use("/metrics", fiberprometheus.New(fiberprometheus.Config{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Service: "my-service-name", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SkipURIs: []string{"/ping"}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| IgnoreStatusCodes: []int{401, 403, 404}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+44
to
+49
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| app.Use("/metrics", fiberprometheus.New(fiberprometheus.Config{ | |
| Service: "my-service-name", | |
| SkipURIs: []string{"/ping"}, | |
| IgnoreStatusCodes: []int{401, 403, 404}, | |
| })) | |
| prometheus := fiberprometheus.New(fiberprometheus.Config{ | |
| Service: "my-service-name", | |
| SkipURIs: []string{"/ping"}, | |
| IgnoreStatusCodes: []int{401, 403, 404}, | |
| }) | |
| app.Use(prometheus) | |
| app.Use("/metrics", prometheus) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
In Fiber v3, does app.Use("/prefix", handler) execute the handler for requests outside that prefix?
💡 Result:
No, in Fiber v3, app.Use("/prefix", handler) does not execute the handler for requests outside that prefix. The prefix limits the middleware/handler to paths that begin with the specified prefix, with stricter matching requiring an exact match or slash boundary (e.g., "/api" matches "/api" and "/api/users" but not "/apiv2").
Citations:
- 1: https://docs.gofiber.io/guide/routing/
- 2: https://docs.gofiber.io/whats_new/
- 3: https://docs.gofiber.io/next/guide/routing
- 4: https://docs.gofiber.io/blog/fiber-v3-adapter-pattern/
- 5: https://docs.gofiber.io/next/api/app/
🏁 Script executed:
# Find the Prometheus test files to verify the double-mount pattern claim
find . -path "*/prometheus/*" -name "*.go" -o -name "*.md" | head -20Repository: gofiber/contrib
Length of output: 522
🏁 Script executed:
# Also check the README.md file location and content
find . -path "*/prometheus/README.md"Repository: gofiber/contrib
Length of output: 85
🏁 Script executed:
# Search for newAppWithMiddleware to verify the double-mount pattern
rg "newAppWithMiddleware" --type goRepository: gofiber/contrib
Length of output: 2137
🏁 Script executed:
# Extract the newAppWithMiddleware function implementation
sed -n '/^func newAppWithMiddleware/,/^}/p' v3/prometheus/prometheus_test.goRepository: gofiber/contrib
Length of output: 315
🏁 Script executed:
# Now check the README.md file around line 91 and the example code
cat -n v3/prometheus/README.md | sed -n '85,100p'Repository: gofiber/contrib
Length of output: 1053
🏁 Script executed:
# Check the indentation of the README example (lines 41-64)
cat -n v3/prometheus/README.md | sed -n '41,65p'Repository: gofiber/contrib
Length of output: 836
Example only mounts at /metrics — other routes won't be instrumented.
The example uses app.Use("/metrics", handler) which, in Fiber v3, limits the middleware to requests under the /metrics prefix only. Requests to /, /ping, and /some never reach the middleware, so:
- No counters/histograms/in-flight metrics are recorded for any application route.
Service,SkipURIs, andIgnoreStatusCodesin the example are effectively dead options./metricswould expose only the Go/process collectors.
The test suite's newAppWithMiddleware (prometheus_test.go) registers the handler twice: app.Use(handler) for global instrumentation, then app.Use(metricsPath, handler) for the metrics endpoint. The README must follow the same pattern.
Additionally, lines 93–96 claim the middleware "continues to instrument all routed traffic," which is false given the single prefix-mount behavior. Line 91 also incorrectly states "All of the options default to false" when RequestDurationBuckets, RequestSizeBuckets, and ResponseSizeBuckets have explicit numeric array defaults (lines 86–89).
📝 Suggested example fix
func main() {
app := fiber.New()
- app.Use("/metrics", fiberprometheus.New(fiberprometheus.Config{
+ prom := fiberprometheus.New(fiberprometheus.Config{
Service: "my-service-name",
SkipURIs: []string{"/ping"},
IgnoreStatusCodes: []int{401, 403, 404},
- }))
+ })
+
+ // Instrument every request.
+ app.Use(prom)
+ // Expose the metrics endpoint at /metrics.
+ app.Use("/metrics", prom)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| func main() { | |
| app := fiber.New() | |
| app.Use("/metrics", fiberprometheus.New(fiberprometheus.Config{ | |
| Service: "my-service-name", | |
| SkipURIs: []string{"/ping"}, | |
| IgnoreStatusCodes: []int{401, 403, 404}, | |
| })) | |
| app.Get("/", func(c fiber.Ctx) error { | |
| return c.SendString("Hello World") | |
| }) | |
| app.Get("/ping", func(c fiber.Ctx) error { | |
| return c.SendString("pong") | |
| }) | |
| app.Post("/some", func(c fiber.Ctx) error { | |
| return c.SendString("Welcome!") | |
| }) | |
| app.Listen(":3000") | |
| } | |
| ``` | |
| func main() { | |
| app := fiber.New() | |
| prom := fiberprometheus.New(fiberprometheus.Config{ | |
| Service: "my-service-name", | |
| SkipURIs: []string{"/ping"}, | |
| IgnoreStatusCodes: []int{401, 403, 404}, | |
| }) | |
| // Instrument every request. | |
| app.Use(prom) | |
| // Expose the metrics endpoint at /metrics. | |
| app.Use("/metrics", prom) | |
| app.Get("/", func(c fiber.Ctx) error { | |
| return c.SendString("Hello World") | |
| }) | |
| app.Get("/ping", func(c fiber.Ctx) error { | |
| return c.SendString("pong") | |
| }) | |
| app.Post("/some", func(c fiber.Ctx) error { | |
| return c.SendString("Welcome!") | |
| }) | |
| app.Listen(":3000") | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@v3/prometheus/README.md` around lines 41 - 64, The README example mounts the
Prometheus middleware only at "/metrics" using app.Use("/metrics", ...), which
prevents instrumentation of other routes; change the example to register the
middleware globally (call app.Use(handler) with the fiberprometheus middleware
returned by fiberprometheus.New(...)) and then separately mount the metrics
endpoint (app.Use("/metrics", handler) or similar) so application routes ("/",
"/ping", "/some") are instrumented and metrics are exposed; also update the
prose that currently claims the middleware "continues to instrument all routed
traffic" to reflect that instrumentation only occurs when the middleware is
registered globally and correct the statement that "All of the options default
to `false`" to list the actual numeric defaults for RequestDurationBuckets,
RequestSizeBuckets, and ResponseSizeBuckets as shown in the config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inaccurate defaults statement.
The bullets immediately above this line include UnmatchedRouteLabel (defaults to /__unmatched__), RequestDurationBuckets, RequestSizeBuckets, and ResponseSizeBuckets (all non-false defaults), so "All of the options default to false" is incorrect and contradicts the surrounding text.
📝 Proposed wording
-All of the options default to `false` and can be enabled or disabled individually as needed.
+All boolean toggles default to `false` and can be enabled individually as needed.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@v3/prometheus/README.md` at line 91, The sentence "All of the options default
to `false`" is incorrect — update the README text to accurately state that some
options default to false while others have non-false defaults; explicitly
mention the exceptions by name (UnmatchedRouteLabel defaults to
`/__unmatched__`, and RequestDurationBuckets, RequestSizeBuckets,
ResponseSizeBuckets have non-false default bucket values) or reword to "Most
options default to `false`; the following have non-false defaults:
UnmatchedRouteLabel, RequestDurationBuckets, RequestSizeBuckets,
ResponseSizeBuckets" so the statement no longer contradicts the bullets.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,187 @@ | ||
| package prometheus | ||
|
|
||
| import ( | ||
| "strings" | ||
|
|
||
| "github.com/gofiber/fiber/v3" | ||
| "github.com/prometheus/client_golang/prometheus" | ||
| ) | ||
|
|
||
| // Config defines the middleware configuration. | ||
| type Config struct { | ||
| // Service is added as the `service` const label on every metric. | ||
| // | ||
| // Optional. Default: "" (label omitted). | ||
| Service string | ||
|
|
||
| // Namespace prefixes every metric name. | ||
| // | ||
| // Optional. Default: "http". | ||
| Namespace string | ||
|
|
||
| // Subsystem prefixes every metric name after Namespace. | ||
| // | ||
| // Optional. Default: "". | ||
| Subsystem string | ||
|
|
||
| // Labels are attached to every metric. | ||
| // | ||
| // Optional. Default: no labels. | ||
| Labels prometheus.Labels | ||
|
|
||
| // Registerer is used to register metrics. | ||
| // | ||
| // Optional. Default: a private registry. | ||
| Registerer prometheus.Registerer | ||
|
|
||
| // Gatherer provides metrics to the HTTP handler. | ||
| // | ||
| // Optional. Default: a private registry/gatherer pair created when neither | ||
| // Registerer nor Gatherer is supplied. If only one is provided, it must also | ||
| // implement the other interface or the middleware will panic to prevent | ||
| // silently omitting metrics. | ||
| Gatherer prometheus.Gatherer | ||
|
|
||
| // DisableGoCollector disables the Go runtime metrics collector registration. | ||
| // | ||
| // Optional. Default: false (collector enabled). | ||
| DisableGoCollector bool | ||
|
|
||
| // DisableProcessCollector disables the process metrics collector registration. | ||
| // | ||
| // Optional. Default: false (collector enabled). | ||
| DisableProcessCollector bool | ||
|
|
||
| // RequestDurationBuckets configures the histogram buckets used for request | ||
| // latency metrics. Provide nil to use the defaults. | ||
| // | ||
| // Optional. Default: []float64{0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 10, 15, 30, 60}. | ||
| RequestDurationBuckets []float64 | ||
|
|
||
| // RequestSizeBuckets configures the histogram buckets used for request | ||
| // payload size metrics. Provide nil to use the defaults. | ||
| // | ||
| // Optional. Default: []float64{256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 5242880}. | ||
| RequestSizeBuckets []float64 | ||
|
|
||
| // ResponseSizeBuckets configures the histogram buckets used for response | ||
| // payload size metrics. Provide nil to use the defaults. | ||
| // | ||
| // Optional. Default: []float64{256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 5242880}. | ||
| ResponseSizeBuckets []float64 | ||
|
|
||
| // TrackUnmatchedRequests toggles metrics for requests that do not resolve to a | ||
| // registered Fiber route. | ||
| // | ||
| // Optional. Default: false. | ||
| TrackUnmatchedRequests bool | ||
|
|
||
| // UnmatchedRouteLabel is the path label used when TrackUnmatchedRequests is | ||
| // enabled and a request does not match a registered route. | ||
| // | ||
| // Optional. Default: "/__unmatched__". | ||
| UnmatchedRouteLabel string | ||
|
|
||
| // EnableOpenMetrics exposes the experimental OpenMetrics encoding. | ||
| // | ||
| // Optional. Default: false. | ||
| EnableOpenMetrics bool | ||
|
|
||
| // EnableOpenMetricsTextCreatedSamples adds synthetic `_created` samples to | ||
| // OpenMetrics responses. | ||
| // | ||
| // Optional. Default: false. | ||
| EnableOpenMetricsTextCreatedSamples bool | ||
|
|
||
| // DisableCompression prevents gzip compression of metrics responses, even when | ||
| // requested by the client (both gzip and zstd). | ||
| // | ||
| // Optional. Default: false. | ||
| DisableCompression bool | ||
|
|
||
| // SkipURIs excludes matching routes from instrumentation. | ||
| // | ||
| // Optional. Default: none. | ||
| SkipURIs []string | ||
|
|
||
| // IgnoreStatusCodes excludes matching response status codes from metrics. | ||
| // | ||
| // Optional. Default: none. | ||
| IgnoreStatusCodes []int | ||
|
|
||
| // Next skips the middleware when it returns true. | ||
| // | ||
| // Optional. Default: nil. | ||
| Next func(fiber.Ctx) bool | ||
| } | ||
|
|
||
| var ( | ||
| defaultRequestDurationBuckets = []float64{0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5, 10, 15, 30, 60} | ||
| defaultRequestSizeBuckets = []float64{256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 5242880} | ||
| defaultResponseSizeBuckets = []float64{256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 5242880} | ||
| ) | ||
|
|
||
| // ConfigDefault holds the default middleware configuration. | ||
| var ConfigDefault = Config{ | ||
| Namespace: "http", | ||
| UnmatchedRouteLabel: "/__unmatched__", | ||
| RequestDurationBuckets: defaultRequestDurationBuckets, | ||
| RequestSizeBuckets: defaultRequestSizeBuckets, | ||
| ResponseSizeBuckets: defaultResponseSizeBuckets, | ||
| } | ||
|
|
||
| func configDefault(config ...Config) Config { | ||
| if len(config) == 0 { | ||
| cfg := ConfigDefault | ||
| cfg.Labels = make(prometheus.Labels) | ||
| cfg.RequestDurationBuckets = append([]float64(nil), ConfigDefault.RequestDurationBuckets...) | ||
| cfg.RequestSizeBuckets = append([]float64(nil), ConfigDefault.RequestSizeBuckets...) | ||
| cfg.ResponseSizeBuckets = append([]float64(nil), ConfigDefault.ResponseSizeBuckets...) | ||
| return cfg | ||
| } | ||
|
|
||
| cfg := config[0] | ||
|
|
||
| if cfg.Namespace == "" { | ||
| cfg.Namespace = ConfigDefault.Namespace | ||
| } | ||
|
|
||
| if cfg.UnmatchedRouteLabel == "" { | ||
| cfg.UnmatchedRouteLabel = ConfigDefault.UnmatchedRouteLabel | ||
| } else { | ||
| cfg.UnmatchedRouteLabel = strings.Clone(cfg.UnmatchedRouteLabel) | ||
| } | ||
|
|
||
| if cfg.RequestDurationBuckets == nil { | ||
| cfg.RequestDurationBuckets = append([]float64(nil), ConfigDefault.RequestDurationBuckets...) | ||
| } else { | ||
| cfg.RequestDurationBuckets = append([]float64(nil), cfg.RequestDurationBuckets...) | ||
| } | ||
|
|
||
| if cfg.RequestSizeBuckets == nil { | ||
| cfg.RequestSizeBuckets = append([]float64(nil), ConfigDefault.RequestSizeBuckets...) | ||
| } else { | ||
| cfg.RequestSizeBuckets = append([]float64(nil), cfg.RequestSizeBuckets...) | ||
| } | ||
|
|
||
| if cfg.ResponseSizeBuckets == nil { | ||
| cfg.ResponseSizeBuckets = append([]float64(nil), ConfigDefault.ResponseSizeBuckets...) | ||
| } else { | ||
| cfg.ResponseSizeBuckets = append([]float64(nil), cfg.ResponseSizeBuckets...) | ||
| } | ||
|
|
||
| if cfg.Labels == nil { | ||
| cfg.Labels = make(prometheus.Labels) | ||
| } else { | ||
| labels := make(prometheus.Labels, len(cfg.Labels)) | ||
| for key, value := range cfg.Labels { | ||
| labels[key] = value | ||
| } | ||
| cfg.Labels = labels | ||
| } | ||
|
|
||
| cfg.SkipURIs = append([]string(nil), cfg.SkipURIs...) | ||
| cfg.IgnoreStatusCodes = append([]int(nil), cfg.IgnoreStatusCodes...) | ||
|
|
||
| return cfg | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| module github.com/gofiber/contrib/v3/prometheus | ||
|
|
||
| go 1.25.0 | ||
|
gaby marked this conversation as resolved.
|
||
|
|
||
| require ( | ||
| github.com/gofiber/fiber/v3 v3.0.0-rc.3 | ||
| github.com/gofiber/utils/v2 v2.0.0-rc.3 | ||
| github.com/prometheus/client_golang v1.23.2 | ||
| go.opentelemetry.io/otel v1.38.0 | ||
| go.opentelemetry.io/otel/sdk v1.38.0 | ||
| go.opentelemetry.io/otel/trace v1.38.0 | ||
| ) | ||
|
|
||
| require ( | ||
| github.com/andybalholm/brotli v1.2.0 // indirect | ||
| github.com/beorn7/perks v1.0.1 // indirect | ||
| github.com/cespare/xxhash/v2 v2.3.0 // indirect | ||
| github.com/go-logr/logr v1.4.3 // indirect | ||
| github.com/go-logr/stdr v1.2.2 // indirect | ||
| github.com/gofiber/schema v1.6.0 // indirect | ||
| github.com/google/uuid v1.6.0 // indirect | ||
| github.com/klauspost/compress v1.18.1 // indirect | ||
| github.com/mattn/go-colorable v0.1.14 // indirect | ||
| github.com/mattn/go-isatty v0.0.20 // indirect | ||
| github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect | ||
| github.com/philhofer/fwd v1.2.0 // indirect | ||
| github.com/prometheus/client_model v0.6.2 // indirect | ||
| github.com/prometheus/common v0.66.1 // indirect | ||
| github.com/prometheus/procfs v0.16.1 // indirect | ||
| github.com/tinylib/msgp v1.5.0 // indirect | ||
| github.com/valyala/bytebufferpool v1.0.0 // indirect | ||
| github.com/valyala/fasthttp v1.68.0 // indirect | ||
| go.opentelemetry.io/auto/sdk v1.2.1 // indirect | ||
| go.opentelemetry.io/otel/metric v1.38.0 // indirect | ||
| go.yaml.in/yaml/v2 v2.4.2 // indirect | ||
| golang.org/x/crypto v0.44.0 // indirect | ||
| golang.org/x/net v0.47.0 // indirect | ||
| golang.org/x/sys v0.38.0 // indirect | ||
| golang.org/x/text v0.31.0 // indirect | ||
| google.golang.org/protobuf v1.36.8 // indirect | ||
| ) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The workflow only triggers on changes to Go files and go.mod, but dependency-only updates can be done by modifying go.sum. Consider including
v3/prometheus/go.sumin the workflowpathsfilters so CI still runs when module dependencies change.