Skip to content

Conversation

@efectn
Copy link
Member

@efectn efectn commented Oct 28, 2025

Description

This PR is successor of previous #3802 PR of @gaby to improve UX. Different than old PR, it gives ability to add messages with more user-friendly API like:

func main() {
	app := fiber.New(fiber.Config{
		//MsgPackEncoder: msgpack.Marshal,
		//MsgPackDecoder: msgpack.Unmarshal,
	})

	app.Get("/", func(c fiber.Ctx) error {
		return c.SendString("Hello, World!")
	})

	app.Hooks().OnPreStartupMessage(func(sm *fiber.PreStartupMessageData) error {
		sm.AddInfo("custom_info", "Custom Info", "\tThis is a custom pre-startup message.")
		sm.AddWarning("custom_warning", "Custom Warning", "\tThis is a custom pre-startup warning.")
		sm.AddError("custom_error", "Custom Error", "\tThis is a custom pre-startup error.", 4)
		return nil
	})

	log.Fatal(app.Listen(":3000", fiber.ListenConfig{
		EnablePrefork: true,
	}))
}
image

Fixes #3800

Changes introduced

  • Documentation Update: Detail the updates made to the documentation and links to the changed files.
  • Changelog/What's New: Include a summary of the additions for the upcoming release notes.
  • Migration Guide: If necessary, provide a guide or steps for users to migrate their existing code to accommodate these changes.

Type of change

  • Enhancement (improvement to existing features and functionality)

Checklist

Before you submit your pull request, please make sure you meet these requirements:

  • Followed the inspiration of the Express.js framework for new functionalities, making them similar in usage.
  • Conducted a self-review of the code and provided comments for complex or critical parts.
  • Updated the documentation in the /docs/ directory for Fiber's documentation.
  • Added or updated unit tests to validate the effectiveness of the changes or new features.
  • Ensured that new and existing unit tests pass locally with the changes.
  • Verified that any new dependencies are essential and have been agreed upon by the maintainers/community.
  • Aimed for optimal performance with minimal allocations in the new code.
  • Provided benchmarks for the new code to analyze and improve upon.

Commit formatting

Please use emojis in commit messages for an easy way to identify the purpose or intention of a commit. Check out the emoji cheatsheet here: CONTRIBUTING.md

Copilot AI review requested due to automatic review settings October 28, 2025 19:36
@efectn efectn requested a review from a team as a code owner October 28, 2025 19:36
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @efectn, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the Fiber framework by providing robust customization options for the application's startup message. It moves beyond a static banner, allowing developers to dynamically inject relevant information, warnings, or errors directly into the console output before and after the server starts listening. This improves the developer experience by making the startup process more informative and adaptable to specific application needs.

Highlights

  • Customizable Startup Messages: Introduced OnPreStartupMessage and OnPostStartupMessage hooks, allowing developers to fully customize the application's startup banner. This includes modifying the header, adding custom informational, warning, or error messages, and even preventing the default banner from being displayed.
  • Expanded ListenData: The ListenData struct has been significantly expanded to provide more comprehensive runtime metadata, such as the Fiber version, application name, handler count, process count, PID, child PIDs (for prefork mode), and the active color scheme.
  • Structured Message Entries: The PreStartupMessageData struct now includes methods like AddInfo, AddWarning, and AddError to programmatically add structured entries to the startup message, offering fine-grained control over the displayed information.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 28, 2025

Walkthrough

Implements startup message customization through two new hooks (OnPreStartupMessage, OnPostStartupMessage) that operate on enriched ListenData metadata (version, app name, handler count, process info). Refactors the startup flow from string concatenation to a data-driven approach using centralized ListenData structures.

Changes

Cohort / File(s) Summary
Hook Registration & Data Structures
hooks.go
Introduces OnPreStartupMessageHandler and OnPostStartupMessageHandler types; adds PreStartupMessageData and PostStartupMessageData structs with helper methods (AddInfo, AddWarning, AddError, etc.); defines StartupMessageLevel enum; extends ListenData with metadata fields (ColorScheme, Version, AppName, ChildPIDs, HandlerCount, ProcessCount, PID, Prefork); implements hook execution paths executeOnPreStartupMessageHooks and executeOnPostStartupMessageHooks.
Startup Flow Refactoring
listen.go, prefork.go, app.go
Refactors prepareListenData to accept childPIDs parameter and return enriched ListenData; updates startupMessage signature to accept ListenData instead of individual parameters; changes printMessages to delegate to startupMessage with ListenData; removes return value from startupProcess; replaces string-based PID tracking with integer slice in startup sequence.
Test Coverage
hooks_test.go, listen_test.go, prefork_test.go
Adds Test_ListenDataMetadata to validate enriched metadata; introduces Test_StartupMessageCustomization, Test_StartupMessageDisabledPostHook, and Test_StartupMessagePreventedByHook for new hook behaviors; updates existing tests to use new prepareListenData/ListenData flow.
Documentation
docs/api/hooks.md, docs/whats_new.md
Documents new ListenData fields and startup message customization hooks; provides usage examples for OnPreStartupMessage and OnPostStartupMessage to customize startup banner and log post-startup events.

Sequence Diagram(s)

sequenceDiagram
    participant App as App
    participant PreHook as OnPreStartupMessage
    participant Startup as Startup Flow
    participant PostHook as OnPostStartupMessage

    rect rgb(200, 220, 255)
        Note over App,PostHook: New Startup Message Flow
    end

    App->>App: prepareListenData() → ListenData<br/>(enriched metadata)
    App->>PreHook: executeOnPreStartupMessageHooks(data)
    alt PreventDefault Set
        PreHook-->>App: Prevent default banner
    else Default Behavior
        PreHook-->>App: Allow/customize banner
    end
    
    rect rgb(240, 255, 240)
        App->>Startup: printMessages(listenData)<br/>renders startup banner
    end

    App->>PostHook: executeOnPostStartupMessageHooks(data)
    alt DisableStartupMessage or Prevented
        PostHook-->>App: Post-hook data (disabled=true)
    else Normal Completion
        PostHook-->>App: Post-hook data with status
    end

    rect rgb(255, 240, 240)
        App->>App: startupProcess() completes<br/>(return removed)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • hooks.go: Multiple new public API surfaces (handler types, data structures, helper methods on PreStartupMessageData, hook execution logic) with interconnected relationships
  • listen.go & prefork.go: Significant refactoring of core startup sequence and data flow; signature changes across multiple methods create downstream impact
  • Test coverage: Substantial new tests exercising hook execution paths, hook interaction with message suppression/prevention, and metadata validation
  • Interconnectedness: Changes span multiple files with tightly coupled startup flow modifications; requires tracing control flow across layers

Areas requiring extra attention:

  • Hook execution order and error handling in executeOnPreStartupMessageHooks and executeOnPostStartupMessageHooks
  • Data cloning logic in newPreStartupMessageData and newPostStartupMessageData to ensure state integrity
  • Interaction between PreventDefault flag and startup message rendering in printMessages
  • Integration of childPIDs parameter propagation through prepareListenData call sites in prefork scenarios

Suggested labels

v3, 📒 Documentation

Suggested reviewers

  • gaby
  • sixcolors
  • ReneWerner87

Poem

🐰 Hop, hop! The startup bells now ring,
PreStartup, PostStartup—hear them sing!
Data enriched, no strings to mend,
Hooks customize from end to end! 🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.41% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "feat: expose startup message customization hooks" clearly and concisely summarizes the main change. It uses conventional commit formatting with a "feat:" prefix, indicating a new feature. The title directly relates to the core objective of the PR—exposing hooks for customizing startup messages—and provides enough specificity for developers scanning the history to understand the primary contribution without being verbose or vague.
Linked Issues Check ✅ Passed The PR comprehensively addresses all primary coding requirements from issue #3800. The implementation introduces OnPreStartupMessage and OnPostStartupMessage hooks enabling users to customize startup messages, adds PreStartupMessageData and PostStartupMessageData structures with methods like AddInfo, AddWarning, and AddError, and extends ListenData with metadata fields (handler count, PID, child PIDs, process count, version, app name, etc.). The changes support preventing default startup message output and allow logging after startup, directly fulfilling the proposed API goals. Tests have been added in hooks_test.go and listen_test.go to validate the new functionality.
Out of Scope Changes Check ✅ Passed All code changes are directly aligned with implementing the startup message customization API described in issue #3800. The modifications to app.go (removing the return value from startupProcess), listen.go, prefork.go, and related files represent necessary supporting refactorings to enable the ListenData-based startup message flow. The documentation updates to docs/api/hooks.md and docs/whats_new.md are appropriate for exposing the new public API. No changes appear to be introducing unrelated functionality or scope creep outside the core objective of exposing startup message customization hooks.
Description Check ✅ Passed The PR description includes the core required elements: a clear explanation of the purpose (successor to PR #3802 with improved UX), a specific issue reference (Fixes #3800), a practical code example demonstrating the feature, and the type of change marked as "Enhancement." While several template checklist items remain unchecked (Documentation Update, Changelog/What's New, Migration Guide, and others), the main descriptive sections are substantially complete with sufficient detail about the feature's intent and usage. The description adequately conveys what the PR does and why, which satisfies the primary requirements for description quality.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch add-startup-message-hooks-to-fiber-2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Oct 28, 2025

Codecov Report

❌ Patch coverage is 70.55556% with 53 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.77%. Comparing base (697f199) to head (a22dcdb).
⚠️ Report is 20 commits behind head on main.

Files with missing lines Patch % Lines
hooks.go 49.41% 40 Missing and 3 partials ⚠️
listen.go 88.88% 8 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3824      +/-   ##
==========================================
+ Coverage   91.73%   91.77%   +0.04%     
==========================================
  Files         113      115       +2     
  Lines       11966     9781    -2185     
==========================================
- Hits        10977     8977    -2000     
+ Misses        727      529     -198     
- Partials      262      275      +13     
Flag Coverage Δ
unittests 91.77% <70.55%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the startup message system by introducing customizable startup message hooks and expanding listener metadata. The changes improve extensibility by allowing users to customize the startup banner through OnPreStartupMessage and OnPostStartupMessage hooks, while also enriching the ListenData structure with comprehensive runtime metadata.

  • Introduced OnPreStartupMessage and OnPostStartupMessage hooks for startup banner customization
  • Expanded ListenData with version, handler count, process count, PID, and child PID metadata
  • Refactored startupMessage() to use ListenData instead of individual parameters and process startup entries dynamically

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
hooks.go Added new hook types and data structures for startup message customization with entry management methods
listen.go Refactored startupMessage() to use ListenData and support customizable startup entries, removed trailing whitespace from ASCII art
prefork.go Updated to use childPIDs slice instead of string concatenation, integrated with new startup message flow
app.go Changed startupProcess() return type from *App to void
hooks_test.go Added comprehensive tests for startup message customization and ListenData metadata verification
listen_test.go Updated test calls to use new startupMessage() signature with prepareListenData()
prefork_test.go Updated test to use new startupMessage() signature
docs/whats_new.md Documented new startup message customization features
docs/api/hooks.md Added documentation for ListenData fields and startup message customization API

Comment on lines +305 to +306
sm.PrimaryInfo = fiber.Map{"Git hash": os.Getenv("GIT_HASH")}
sm.SecondaryInfo = fiber.Map{"Process count": sm.ProcessCount}
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation references PrimaryInfo and SecondaryInfo fields that do not exist in the PreStartupMessageData struct. According to the actual implementation in hooks.go, users should call methods like AddInfo(), AddWarning(), AddError(), ResetEntries(), and DeleteEntry() to customize the startup entries. Update the example to use the correct API: sm.AddInfo(key, title, value, priority).

Suggested change
sm.PrimaryInfo = fiber.Map{"Git hash": os.Getenv("GIT_HASH")}
sm.SecondaryInfo = fiber.Map{"Process count": sm.ProcessCount}
sm.AddInfo("git_hash", "Git hash", os.Getenv("GIT_HASH"), fiber.PriorityHigh)
sm.AddInfo("process_count", "Process count", sm.ProcessCount, fiber.PriorityLow)

Copilot uses AI. Check for mistakes.
Use `OnPreStartupMessage` to tweak the banner before Fiber prints it, and `OnPostStartupMessage` to run logic after the banner is printed (or skipped):

- Assign `sm.Header` to override the ASCII art banner. Leave it empty to use the default.
- Provide `sm.PrimaryInfo` and/or `sm.SecondaryInfo` maps to replace the primary (server URL, handler counts, etc.) and secondary (prefork status, PID, process count) sections.
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation incorrectly describes PrimaryInfo and SecondaryInfo fields that don't exist. The actual API uses methods AddInfo(), AddWarning(), AddError(), ResetEntries(), and DeleteEntry() to manage startup entries. Update this documentation to reflect the actual implementation.

Copilot uses AI. Check for mistakes.
Comment on lines +213 to +214
sm.PrimaryInfo = fiber.Map{"Git hash": os.Getenv("GIT_HASH")}
sm.SecondaryInfo = fiber.Map{"Prefork": sm.Prefork}
Copy link

Copilot AI Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example code references non-existent fields. Replace with the actual API methods: sm.AddInfo(\"git_hash\", \"Git hash\", os.Getenv(\"GIT_HASH\"), priority) and similar calls for other entries.

Suggested change
sm.PrimaryInfo = fiber.Map{"Git hash": os.Getenv("GIT_HASH")}
sm.SecondaryInfo = fiber.Map{"Prefork": sm.Prefork}
sm.AddInfo("git_hash", "Git hash", os.Getenv("GIT_HASH"), fiber.InfoPrimary)
sm.AddInfo("prefork", "Prefork", sm.Prefork, fiber.InfoSecondary)

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a great feature for customizing the startup message in Fiber, providing more flexibility for developers. The implementation with OnPreStartupMessage and OnPostStartupMessage hooks and the associated data structures is well-designed. The refactoring in listen.go and prefork.go to support this is clean.

However, there are some critical issues with the documentation. The examples in docs/api/hooks.md and docs/whats_new.md are based on an outdated implementation and will not work with the code in this PR. I've provided suggestions to fix them. I also found some dead code in hooks.go that should be removed.

Once these issues are addressed, this will be a solid contribution to Fiber.

Comment on lines +193 to +227
- Assign `sm.Header` to override the ASCII art banner. Leave it empty to use the default.
- Provide `sm.PrimaryInfo` and/or `sm.SecondaryInfo` maps to replace the primary (server URL, handler counts, etc.) and secondary (prefork status, PID, process count) sections.
- Set `sm.PreventDefault = true` to suppress the built-in banner without affecting other hooks.
- `PostStartupMessageData` reports whether the banner was skipped via the `Disabled`, `IsChild`, and `Prevented` flags.

```go title="Customize the startup message"
package main

import (
"fmt"
"os"

"github.com/gofiber/fiber/v3"
)

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

app.Hooks().OnPreStartupMessage(func(sm *fiber.PreStartupMessageData) error {
sm.Header = "FOOBER " + sm.Version + "\n-------"
sm.PrimaryInfo = fiber.Map{"Git hash": os.Getenv("GIT_HASH")}
sm.SecondaryInfo = fiber.Map{"Prefork": sm.Prefork}
return nil
})

app.Hooks().OnPostStartupMessage(func(sm fiber.PostStartupMessageData) error {
if !sm.Disabled && !sm.IsChild && !sm.Prevented {
fmt.Println("startup completed")
}
return nil
})

app.Listen(":5000")
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The documentation for startup message customization is outdated. The description mentions sm.PrimaryInfo and sm.SecondaryInfo, and the example code uses them, but these fields do not exist on the PreStartupMessageData struct. The new API uses methods like AddInfo, AddWarning, and AddError. The documentation and example should be updated to reflect the correct API usage, as shown in the pull request description.

- Use `sm.AddInfo()`, `sm.AddWarning()`, and `sm.AddError()` to add, update, or remove startup message entries.
- Assign `sm.Header` to override the ASCII art banner. Leave it empty to use the default.
- Set `sm.PreventDefault = true` to suppress the built-in banner without affecting other hooks.
- `PostStartupMessageData` reports whether the banner was skipped via the `Disabled`, `IsChild`, and `Prevented` flags.

```go title="Customize the startup message"
package main

import (
	"fmt"

	"github.com/gofiber/fiber/v3"
)

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

	app.Hooks().OnPreStartupMessage(func(sm *fiber.PreStartupMessageData) error {
		sm.Header = "My Awesome App v" + sm.Version + "\n----------------------"
		// You can add custom info, warnings, or errors to the startup message.
		sm.AddInfo("custom_info", "Custom Info", "This is a custom message.")
		sm.AddWarning("custom_warning", "Custom Warning", "This is a custom warning.")
		// Entries can be prioritized. Higher priority entries are shown first.
		sm.AddError("custom_error", "Custom Error", "This is a custom error.", 10)
		return nil
	})

	app.Hooks().OnPostStartupMessage(func(sm fiber.PostStartupMessageData) error {
		if !sm.Disabled && !sm.IsChild && !sm.Prevented {
			fmt.Println("startup completed")
		}
		return nil
	})

	app.Listen(":5000")
}

Comment on lines +303 to +309
app.Hooks().OnPreStartupMessage(func(sm *fiber.PreStartupMessageData) error {
sm.Header = "FOOBER " + sm.Version + "\n-------"
sm.PrimaryInfo = fiber.Map{"Git hash": os.Getenv("GIT_HASH")}
sm.SecondaryInfo = fiber.Map{"Process count": sm.ProcessCount}
// Set sm.PreventDefault = true to suppress the default banner entirely.
return nil
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The example code for the new startup message hooks uses sm.PrimaryInfo and sm.SecondaryInfo, which are from an older implementation and no longer exist on PreStartupMessageData. The new API uses methods like AddInfo. This example should be updated to reflect the correct usage.

Suggested change
app.Hooks().OnPreStartupMessage(func(sm *fiber.PreStartupMessageData) error {
sm.Header = "FOOBER " + sm.Version + "\n-------"
sm.PrimaryInfo = fiber.Map{"Git hash": os.Getenv("GIT_HASH")}
sm.SecondaryInfo = fiber.Map{"Process count": sm.ProcessCount}
// Set sm.PreventDefault = true to suppress the default banner entirely.
return nil
})
app.Hooks().OnPreStartupMessage(func(sm *fiber.PreStartupMessageData) error {
sm.Header = "FOOBER " + sm.Version + "\n-------"
sm.AddInfo("git_hash", "Git hash", os.Getenv("GIT_HASH"))
sm.AddInfo("process_count", "Process count", fmt.Sprintf("%d", sm.ProcessCount))
// Set sm.PreventDefault = true to suppress the default banner entirely.
return nil
})

Comment on lines +205 to 223
func mapToEntries(values Map) ([]startupMessageEntry, bool) {
if len(values) == 0 {
return nil, false
}

keys := make([]string, 0, len(values))
for key := range values {
keys = append(keys, key)
}

sort.Strings(keys)

entries := make([]startupMessageEntry, 0, len(values))
for _, key := range keys {
entries = append(entries, startupMessageEntry{key: key, value: fmt.Sprint(values[key])})
}

return entries, true
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The function mapToEntries appears to be dead code. It's not called anywhere in the codebase. It seems like a leftover from a previous implementation that used PrimaryInfo and SecondaryInfo maps. It should be removed to keep the code clean.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
listen.go (1)

53-56: Docstring nit: field name mismatch

Comment says “ListenerFunc” but the field is ListenerAddrFunc. Update the comment to match the field name to avoid confusion.

-// ListenerFunc allows accessing and customizing net.Listener.
+// ListenerAddrFunc allows accessing and customizing net.Listener address.
🧹 Nitpick comments (4)
hooks_test.go (1)

292-352: Harden assertions and avoid unexported fields in tests

  • Prefer public API: use app.Config().ColorScheme instead of app.config.ColorScheme.
  • Guard slice access before indexing pre.entries.

Apply:

-        require.Equal(t, app.config.ColorScheme, data.ColorScheme)
+        require.Equal(t, app.Config().ColorScheme, data.ColorScheme)
@@
-        require.Equal(t, app.config.ColorScheme, data.ColorScheme)
+        require.Equal(t, app.Config().ColorScheme, data.ColorScheme)
@@
-    require.Equal(t, "value", pre.entries[0].value)
+    require.Len(t, pre.entries, 2)
+    require.Equal(t, "value", pre.entries[0].value)
prefork_test.go (1)

86-91: Unify stdout capture with captureOutput for consistency

Reuse the existing captureOutput helper to simplify and ensure log output is captured identically across tests.

Example:

out := captureOutput(func() {
    app.startupProcess()
    listenData := app.prepareListenData(":0", false, cfg, nil)
    app.startupMessage(listenData, cfg)
})
require.Empty(t, out)
listen.go (2)

451-459: Avoid builtin min() for wider Go compatibility

If the repo targets <1.21, builtin min won’t exist. Use explicit bounds check.

-        end := min(i+rowTotalPidCount, totalPIDs)
+        end := i + rowTotalPidCount
+        if end > totalPIDs {
+            end = totalPIDs
+        }

[Suggest running the same go.mod/version script shared above to confirm target Go version.]


111-125: Housekeeping: run format/align/modernize

Please run the repo’s formatting targets to align with project standards:

  • make format (gofumpt)
  • make betteralign
  • make modernize (gopls)

As per coding guidelines.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 83cc132 and a22dcdb.

📒 Files selected for processing (9)
  • app.go (1 hunks)
  • docs/api/hooks.md (1 hunks)
  • docs/whats_new.md (1 hunks)
  • hooks.go (6 hunks)
  • hooks_test.go (2 hunks)
  • listen.go (6 hunks)
  • listen_test.go (5 hunks)
  • prefork.go (3 hunks)
  • prefork_test.go (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
docs/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Review and update the contents of the docs folder if necessary when modifying code

Files:

  • docs/api/hooks.md
  • docs/whats_new.md
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

**/*.go: Apply formatting using gofumpt (Make target: format)
Optimize struct field alignment using betteralign (Make target: betteralign)
Modernize code using gopls modernize (Make target: modernize)

Files:

  • app.go
  • hooks_test.go
  • listen_test.go
  • prefork_test.go
  • hooks.go
  • listen.go
  • prefork.go
🧠 Learnings (1)
📚 Learning: 2025-10-16T07:15:26.529Z
Learnt from: grivera64
PR: gofiber/fiber#3807
File: adapter_test.go:118-144
Timestamp: 2025-10-16T07:15:26.529Z
Learning: In Fiber v3, net/http handlers (http.Handler, http.HandlerFunc, or raw func(http.ResponseWriter, *http.Request)) can be passed directly to routing methods like app.Get(), app.Post(), etc. The framework automatically detects and wraps them internally via toFiberHandler/collectHandlers. The github.com/gofiber/fiber/v3/middleware/adaptor package is legacy and should not be suggested for tests or code using native net/http handler support.

Applied to files:

  • docs/whats_new.md
🧬 Code graph analysis (5)
hooks_test.go (3)
app.go (2)
  • Config (113-418)
  • Version (37-37)
listen.go (1)
  • ListenConfig (42-125)
hooks.go (3)
  • Hooks (36-52)
  • ListenData (75-90)
  • PreStartupMessageData (93-101)
listen_test.go (3)
app.go (1)
  • New (515-628)
listen.go (1)
  • ListenConfig (42-125)
hooks.go (3)
  • Hooks (36-52)
  • PreStartupMessageData (93-101)
  • PostStartupMessageData (183-189)
prefork_test.go (1)
app.go (1)
  • New (515-628)
hooks.go (3)
color.go (1)
  • Colors (8-53)
app.go (2)
  • Version (37-37)
  • Map (43-43)
prefork.go (1)
  • IsChild (31-33)
listen.go (4)
app.go (2)
  • App (68-110)
  • Version (37-37)
hooks.go (1)
  • ListenData (75-90)
prefork.go (1)
  • IsChild (31-33)
color.go (1)
  • Colors (8-53)
🪛 GitHub Actions: golangci-lint
hooks.go

[error] 93-93: golangci-lint (go vet) error: fieldalignment: struct with 40 pointer bytes could be 32 (govet)

🪛 GitHub Check: lint
hooks.go

[failure] 205-205:
func mapToEntries is unused (unused)


[failure] 93-93:
fieldalignment: struct with 40 pointer bytes could be 32 (govet)

listen.go

[failure] 475-475:
identical-switch-branches: "switch" with identical branches (lines 476 and 482) (revive)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Compare
  • GitHub Check: unit (1.25.x, windows-latest)
  • GitHub Check: repeated
🔇 Additional comments (11)
prefork.go (2)

92-121: LGTM: child PIDs propagation and hook ordering

Collecting childPIDs and feeding them into prepareListenData, then running OnListen before startupMessage is correct and preserves master/child separation.

Also applies to: 136-143


96-104: No issues found—Go version supports for range over int

The project's go.mod specifies go 1.25.0, which fully supports the for range intValue syntax introduced in Go 1.22. The code at prefork.go:96 is valid and requires no changes.

hooks.go (1)

54-63: LGTM: startup message hook surface and executors

Exported levels, extended ListenData, and pre/post executors look coherent and minimal.

Also applies to: 74-91, 401-419

app.go (1)

1328-1336: Verified: All call sites correctly updated

The signature change is complete and consistent. Zero usages attempt to assign the return value from startupProcess(). All 10 call sites treat it as a void function, confirming the refactoring is correct.

listen_test.go (4)

627-663: Nice coverage of header and custom entries

Covers header override, entry reset, ordering, and post-hook flags. LGTM.


664-685: Disabled startup message + post-hook state — solid

Asserts both no output and Disabled=true. LGTM.


686-713: Prevented-by-prehook path — good verification

Validates suppression and PostStartupMessage.Prevented. LGTM.


526-534: ****

The repository is pinned to Go 1.25.0, making the for range <int> syntax fully supported and idiomatic. The pattern used at line 528 (and elsewhere throughout the codebase) is appropriate and requires no changes. The original concern about Go 1.22-only syntax is not applicable.

listen.go (3)

327-333: printMessages signature change — good separation

Delegating to startupMessage(listenData, cfg) keeps concerns clean; routes printing remains gated. LGTM.


335-369: prepareListenData clones child PIDs and fills metadata correctly

Nicely avoids aliasing and captures PID, handler/process counts, TLS/prefork flags. LGTM.


371-466: Startup message flow with pre/post hooks looks solid

  • Honors DisableStartupMessage, IsChild, and PreventDefault.
  • Always fires post-hook via defer.

One suggestion: compute disabled/isChild/prevented after pre-hook (as you do) and return early; already correct. LGTM.

Comment on lines +171 to +227
### ListenData

`ListenData` exposes runtime metadata about the listener:

| Field | Type | Description |
| --- | --- | --- |
| `Host` | `string` | Resolved hostname or IP address. |
| `Port` | `string` | The bound port. |
| `TLS` | `bool` | Indicates whether TLS is enabled. |
| `Version` | `string` | Fiber version reported in the startup banner. |
| `AppName` | `string` | Application name from the configuration. |
| `HandlerCount` | `int` | Total registered handler count. |
| `ProcessCount` | `int` | Number of processes Fiber will use. |
| `PID` | `int` | Current process identifier. |
| `Prefork` | `bool` | Whether prefork is enabled. |
| `ChildPIDs` | `[]int` | Child process identifiers when preforking. |
| `ColorScheme` | [`Colors`](https://github.com/gofiber/fiber/blob/main/color.go) | Active color scheme for the startup message. |

### Startup message customization

Use `OnPreStartupMessage` to tweak the banner before Fiber prints it, and `OnPostStartupMessage` to run logic after the banner is printed (or skipped):

- Assign `sm.Header` to override the ASCII art banner. Leave it empty to use the default.
- Provide `sm.PrimaryInfo` and/or `sm.SecondaryInfo` maps to replace the primary (server URL, handler counts, etc.) and secondary (prefork status, PID, process count) sections.
- Set `sm.PreventDefault = true` to suppress the built-in banner without affecting other hooks.
- `PostStartupMessageData` reports whether the banner was skipped via the `Disabled`, `IsChild`, and `Prevented` flags.

```go title="Customize the startup message"
package main

import (
"fmt"
"os"

"github.com/gofiber/fiber/v3"
)

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

app.Hooks().OnPreStartupMessage(func(sm *fiber.PreStartupMessageData) error {
sm.Header = "FOOBER " + sm.Version + "\n-------"
sm.PrimaryInfo = fiber.Map{"Git hash": os.Getenv("GIT_HASH")}
sm.SecondaryInfo = fiber.Map{"Prefork": sm.Prefork}
return nil
})

app.Hooks().OnPostStartupMessage(func(sm fiber.PostStartupMessageData) error {
if !sm.Disabled && !sm.IsChild && !sm.Prevented {
fmt.Println("startup completed")
}
return nil
})

app.Listen(":5000")
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Docs: correct startup customization API usage

Replace references to PrimaryInfo/SecondaryInfo with the provided entry APIs and adjust the example.

-Use `OnPreStartupMessage` to tweak the banner before Fiber prints it, and `OnPostStartupMessage` to run logic after the banner is printed (or skipped):
-
-- Assign `sm.Header` to override the ASCII art banner. Leave it empty to use the default.
-- Provide `sm.PrimaryInfo` and/or `sm.SecondaryInfo` maps to replace the primary (server URL, handler counts, etc.) and secondary (prefork status, PID, process count) sections.
-- Set `sm.PreventDefault = true` to suppress the built-in banner without affecting other hooks.
-- `PostStartupMessageData` reports whether the banner was skipped via the `Disabled`, `IsChild`, and `Prevented` flags.
+Use `OnPreStartupMessage` to tweak the banner before Fiber prints it, and `OnPostStartupMessage` to run logic after the banner is printed (or skipped):
+
+- Set `sm.Header` to override the ASCII art/banner. Leave empty to keep the default.
+- Add lines with `sm.AddInfo`, `sm.AddWarning`, or `sm.AddError`. Use the optional `priority` arg to influence ordering (higher priority first).
+- Set `sm.PreventDefault = true` to suppress the built‑in banner.
+- `PostStartupMessageData` reports if the banner was disabled, printed by a child, or prevented via `Disabled`, `IsChild`, and `Prevented`.
@@
-    app.Hooks().OnPreStartupMessage(func(sm *fiber.PreStartupMessageData) error {
-        sm.Header = "FOOBER " + sm.Version + "\n-------"
-        sm.PrimaryInfo = fiber.Map{"Git hash": os.Getenv("GIT_HASH")}
-        sm.SecondaryInfo = fiber.Map{"Prefork": sm.Prefork}
-        return nil
-    })
+    app.Hooks().OnPreStartupMessage(func(sm *fiber.PreStartupMessageData) error {
+        sm.Header = "FOOBER " + sm.Version + "\n-------"
+        sm.AddInfo("git_hash", "Git hash", os.Getenv("GIT_HASH"))
+        sm.AddInfo("prefork", "Prefork", fmt.Sprint(sm.Prefork))
+        return nil
+    })
@@
-        if !sm.Disabled && !sm.IsChild && !sm.Prevented {
-            fmt.Println("startup completed")
-        }
+        if !sm.Disabled && !sm.IsChild && !sm.Prevented {
+            fmt.Println("startup completed")
+        }
         return nil
     })

Optionally document entry ordering/priority briefly.

🤖 Prompt for AI Agents
In docs/api/hooks.md around lines 171–227, the startup customization example and
description still reference sm.PrimaryInfo and sm.SecondaryInfo which are
incorrect; update the prose and code sample to use the hook's provided entry
APIs (e.g. call the API methods to add primary and secondary entries instead of
assigning maps), adjust the example to show calling those entry methods to set a
"Git hash" primary entry and a "Prefork" secondary entry, and optionally add one
short sentence noting that entries are rendered in the order they are added
(earlier entries have higher display priority).

Comment on lines +298 to +319
- Expanded `ListenData` with versioning, handler, process, and PID metadata, plus dedicated startup message hooks for customization.

```go
app := fiber.New()

app.Hooks().OnPreStartupMessage(func(sm *fiber.PreStartupMessageData) error {
sm.Header = "FOOBER " + sm.Version + "\n-------"
sm.PrimaryInfo = fiber.Map{"Git hash": os.Getenv("GIT_HASH")}
sm.SecondaryInfo = fiber.Map{"Process count": sm.ProcessCount}
// Set sm.PreventDefault = true to suppress the default banner entirely.
return nil
})

app.Hooks().OnPostStartupMessage(func(sm fiber.PostStartupMessageData) error {
if !sm.Disabled && !sm.IsChild && !sm.Prevented {
log.Println("startup completed")
}
return nil
})

go app.Listen(":3000")
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Align example with actual API (no PrimaryInfo/SecondaryInfo fields)

PreStartupMessageData exposes AddInfo/AddWarning/AddError and Header/PreventDefault, not PrimaryInfo/SecondaryInfo. Update the snippet to compile and reflect the API.

 app := fiber.New()
 
 app.Hooks().OnPreStartupMessage(func(sm *fiber.PreStartupMessageData) error {
-    sm.Header = "FOOBER " + sm.Version + "\n-------"
-    sm.PrimaryInfo = fiber.Map{"Git hash": os.Getenv("GIT_HASH")}
-    sm.SecondaryInfo = fiber.Map{"Process count": sm.ProcessCount}
+    sm.Header = "FOOBER " + sm.Version + "\n-------"
+    sm.AddInfo("git_hash", "Git hash", os.Getenv("GIT_HASH"))
+    sm.AddInfo("proc_count", "Process count", fmt.Sprint(sm.ProcessCount))
     // Set sm.PreventDefault = true to suppress the default banner entirely.
     return nil
 })
 
 app.Hooks().OnPostStartupMessage(func(sm fiber.PostStartupMessageData) error {
     if !sm.Disabled && !sm.IsChild && !sm.Prevented {
-        log.Println("startup completed")
+        fmt.Println("startup completed")
     }
     return nil
 })
 
 go app.Listen(":3000")
🤖 Prompt for AI Agents
In docs/whats_new.md around lines 298 to 319, the PreStartupMessageData example
uses nonexistent PrimaryInfo/SecondaryInfo fields and will not compile; replace
those with calls to AddInfo/AddWarning/AddError and set Header/PreventDefault as
shown by the API, e.g. populate the metadata using sm.AddInfo(key, value) (or
AddWarning/AddError) and remove PrimaryInfo/SecondaryInfo assignments, and
ensure the PostStartupMessageData checks use the actual fields
(Disabled/IsChild/Prevented) as in the snippet so the example matches the real
API.

Comment on lines +93 to +101
type PreStartupMessageData struct {
*ListenData

entries []startupMessageEntry

Header string

PreventDefault bool
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix struct field alignment for PreStartupMessageData

Govet/betteralign flags padding waste. Reorder fields to reduce padding and satisfy the pipeline.

-type PreStartupMessageData struct {
-	*ListenData
-	entries []startupMessageEntry
-	Header string
-	PreventDefault bool
-}
+type PreStartupMessageData struct {
+	*ListenData
+	Header        string
+	entries       []startupMessageEntry
+	PreventDefault bool
+}

As per coding guidelines (betteralign).

📝 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.

Suggested change
type PreStartupMessageData struct {
*ListenData
entries []startupMessageEntry
Header string
PreventDefault bool
}
type PreStartupMessageData struct {
*ListenData
Header string
entries []startupMessageEntry
PreventDefault bool
}
🧰 Tools
🪛 GitHub Actions: golangci-lint

[error] 93-93: golangci-lint (go vet) error: fieldalignment: struct with 40 pointer bytes could be 32 (govet)

🪛 GitHub Check: lint

[failure] 93-93:
fieldalignment: struct with 40 pointer bytes could be 32 (govet)

🤖 Prompt for AI Agents
In hooks.go around lines 93 to 101, reorder the PreStartupMessageData struct
fields to eliminate padding waste: place the largest-aligned fields first
(entries slice), then Header (string), then the *ListenData pointer, and finally
PreventDefault (bool). Update the struct field order to: entries, Header,
*ListenData, PreventDefault and run go vet/go test to verify alignment fixes.

Comment on lines +205 to 223
func mapToEntries(values Map) ([]startupMessageEntry, bool) {
if len(values) == 0 {
return nil, false
}

keys := make([]string, 0, len(values))
for key := range values {
keys = append(keys, key)
}

sort.Strings(keys)

entries := make([]startupMessageEntry, 0, len(values))
for _, key := range keys {
entries = append(entries, startupMessageEntry{key: key, value: fmt.Sprint(values[key])})
}

return entries, true
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Remove or silence unused mapToEntries to fix lint failure

mapToEntries is unused and breaks CI. Either remove it now or add a targeted nolint with rationale.

Option A (remove):

-func mapToEntries(values Map) ([]startupMessageEntry, bool) {
-	if len(values) == 0 {
-		return nil, false
-	}
-	keys := make([]string, 0, len(values))
-	for key := range values {
-		keys = append(keys, key)
-	}
-	sort.Strings(keys)
-	entries := make([]startupMessageEntry, 0, len(values))
-	for _, key := range keys {
-		entries = append(entries, startupMessageEntry{key: key, value: fmt.Sprint(values[key])})
-	}
-	return entries, true
-}

Option B (silence temporarily):

- func mapToEntries(values Map) ([]startupMessageEntry, bool) {
+ // mapToEntries converts a map to sorted entries.
+ // nolint:unused // Will be wired by listen.go banner mapping follow-up.
+ func mapToEntries(values Map) ([]startupMessageEntry, bool) {

Choose A if no immediate use is planned. As per coding guidelines.

📝 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.

Suggested change
func mapToEntries(values Map) ([]startupMessageEntry, bool) {
if len(values) == 0 {
return nil, false
}
keys := make([]string, 0, len(values))
for key := range values {
keys = append(keys, key)
}
sort.Strings(keys)
entries := make([]startupMessageEntry, 0, len(values))
for _, key := range keys {
entries = append(entries, startupMessageEntry{key: key, value: fmt.Sprint(values[key])})
}
return entries, true
}
🧰 Tools
🪛 GitHub Check: lint

[failure] 205-205:
func mapToEntries is unused (unused)

🤖 Prompt for AI Agents
In hooks.go around lines 205 to 223, the helper function mapToEntries is
currently unused and causing CI lint failures; either delete the entire function
if it is not needed, or if you expect to use it imminently add a targeted nolint
(e.g., //nolint:unused // keep for upcoming startupMessage refactor) immediately
above the function and include a one‑sentence rationale, then run linters to
confirm the failure is resolved.

Comment on lines +560 to +564
childTemplate := []int{11111, 22222, 33333, 44444, 55555, 60000}
childPIDs := make([]int, 0, len(childTemplate)*10)
for range 10 {
childPIDs = append(childPIDs, childTemplate...)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Same here: replace Go 1.22-only for range 10

- for range 10 {
-     childPIDs = append(childPIDs, childTemplate...)
- }
+ for i := 0; i < 10; i++ {
+     childPIDs = append(childPIDs, childTemplate...)
+ }
🤖 Prompt for AI Agents
In listen_test.go around lines 560 to 564, the loop uses the Go 1.22-only
construct `for range 10`; replace it with a standard indexed loop such as `for i
:= 0; i < 10; i++ { childPIDs = append(childPIDs, childTemplate...) }` so the
code compiles on older Go versions and preserves the existing behavior and
preallocated capacity.

Comment on lines +468 to +486
func printStartupEntries(out io.Writer, colors Colors, entries []startupMessageEntry) {
// Sort entries by priority (higher priority first)
sort.Slice(entries, func(i, j int) bool {
return entries[i].priority > entries[j].priority
})

for _, entry := range entries {
switch entry.level {
case StartupMessageLevelInfo:
fmt.Fprintf(out, "%sINFO%s %s: \t%s%s%s\n", colors.Green, colors.Reset, entry.title, colors.Blue, entry.value, colors.Reset)
case StartupMessageLevelWarning:
fmt.Fprintf(out, "%sWARN%s %s: \t%s%s%s\n", colors.Yellow, colors.Reset, entry.title, colors.Blue, entry.value, colors.Reset)
case StartupMessageLevelError:
fmt.Fprintf(out, "%sERROR%s %s: \t%s%s%s\n", colors.Red, colors.Reset, entry.title, colors.Blue, entry.value, colors.Reset)
default:
fmt.Fprintf(out, "%sINFO%s %s: \t%s%s%s\n", colors.Green, colors.Reset, entry.title, colors.Blue, entry.value, colors.Reset)
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Fix identical switch branches; compute label/color once

Revive flags identical branches (info/default). Refactor to remove duplication.

-func printStartupEntries(out io.Writer, colors Colors, entries []startupMessageEntry) {
+func printStartupEntries(out io.Writer, colors Colors, entries []startupMessageEntry) {
   // Sort entries by priority (higher priority first)
   sort.Slice(entries, func(i, j int) bool {
     return entries[i].priority > entries[j].priority
   })
 
   for _, entry := range entries {
-    switch entry.level {
-    case StartupMessageLevelInfo:
-      fmt.Fprintf(out, "%sINFO%s %s: \t%s%s%s\n", colors.Green, colors.Reset, entry.title, colors.Blue, entry.value, colors.Reset)
-    case StartupMessageLevelWarning:
-      fmt.Fprintf(out, "%sWARN%s %s: \t%s%s%s\n", colors.Yellow, colors.Reset, entry.title, colors.Blue, entry.value, colors.Reset)
-    case StartupMessageLevelError:
-      fmt.Fprintf(out, "%sERROR%s %s: \t%s%s%s\n", colors.Red, colors.Reset, entry.title, colors.Blue, entry.value, colors.Reset)
-    default:
-      fmt.Fprintf(out, "%sINFO%s %s: \t%s%s%s\n", colors.Green, colors.Reset, entry.title, colors.Blue, entry.value, colors.Reset)
-    }
+    label := "INFO"
+    color := colors.Green
+    switch entry.level {
+    case StartupMessageLevelWarning:
+      label, color = "WARN", colors.Yellow
+    case StartupMessageLevelError:
+      label, color = "ERROR", colors.Red
+    }
+    fmt.Fprintf(out, "%s%s%s %s: \t%s%s%s\n", color, label, colors.Reset, entry.title, colors.Blue, entry.value, colors.Reset)
   }
 }
🧰 Tools
🪛 GitHub Check: lint

[failure] 475-475:
identical-switch-branches: "switch" with identical branches (lines 476 and 482) (revive)

🤖 Prompt for AI Agents
In listen.go around lines 468 to 486, the switch has duplicated branches (info
and default) printing identical output; refactor by having the switch only
assign the label string and its color (e.g., label="INFO"/"WARN"/"ERROR" and
labelColor=colors.Green/Yellow/Red) then after the switch perform a single
fmt.Fprintf that uses labelColor, colors.Reset, label, entry.title and
entry.value; ensure the default case maps to the info label/color and preserve
the Blue color for the value.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.

Benchmark suite Current: a22dcdb Previous: 83cc132 Ratio
Benchmark_Ctx_Write 27.27 ns/op 79 B/op 0 allocs/op 18.15 ns/op 69 B/op 0 allocs/op 1.50
Benchmark_Ctx_Write - ns/op 27.27 ns/op 18.15 ns/op 1.50
Benchmark_Ctx_SendString_B 19.72 ns/op 0 B/op 0 allocs/op 9.977 ns/op 0 B/op 0 allocs/op 1.98
Benchmark_Ctx_SendString_B - ns/op 19.72 ns/op 9.977 ns/op 1.98

This comment was automatically generated by workflow using github-action-benchmark.

@gaby gaby added the v3 label Oct 29, 2025
@ReneWerner87
Copy link
Member

@efectn can you check the AI hints and golang lint

@ReneWerner87 ReneWerner87 added this to v3 Oct 29, 2025
@ReneWerner87 ReneWerner87 added this to the v3 milestone Oct 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

📝 [Proposal]: Create API around app.startupMessage

4 participants