Conversation
| func serve(ctx context.Context, c *cli.Command) (err error) { | ||
| var srv *server.Server | ||
| if srv, err = server.New(nil); err != nil { | ||
| if srv, err = server.New(); err != nil { |
There was a problem hiding this comment.
The new pattern here is that we don't pass a config to New -- if we want to modify the config, we have to modify it globally.
| func (c Config) Validate() (err error) { | ||
| if c.Mode != gin.ReleaseMode && c.Mode != gin.DebugMode && c.Mode != gin.TestMode { | ||
| return confire.Invalid("", "mode", "gin mode must be one of: release, debug, test") | ||
| } | ||
| return nil | ||
| } |
There was a problem hiding this comment.
I have made confire updates to make sure that this Validation function is in fact run by confire.
| "go.rtnl.ai/x/rlog" | ||
| ) | ||
|
|
||
| var testEnv = contest.Env{ |
There was a problem hiding this comment.
Note the use of the new confire testing tools.
| // Load the configuration from the environment if not provided. | ||
| if s.conf, err = config.Get(); err != nil { | ||
| return nil, fmt.Errorf("could not load configuration: %w", err) |
There was a problem hiding this comment.
Configuration is loaded rather than passed in to the service. This really only affects tests; I plan to use a Debug method for testing.
| rlog.InfoAttrs( | ||
| context.Background(), | ||
| "uptime server started", |
There was a problem hiding this comment.
A bit of an adaptation to what you have in Endeavor.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Scope of changes
@chris-okuda this is my new service implementation pattern using
rlogandotelsemantics we've created in our various other libraries. I'll slowly work on getting Endeavor and Quarterdeck to more closely match this spec.The most notable thing is the difference in how config is being used -- I'm pushing that to be more of a global variable instead of calling
Newand passing the config around.Estimated PR Size:
Acceptance criteria
This PR will be merged without review.
Author checklist
Note
Medium Risk
Introduces new OpenTelemetry initialization and request middleware plus switches configuration to a package-level singleton, which can affect startup behavior and observability/logging in production if misconfigured.
Overview
Adds a new
pkg/telemetrymodule that initializes OpenTelemetry (traces/metrics/logs) via env-driven autoexport/autoprop, provides a Gin middleware hook (telemetry.Middleware()), and configuresrlogto emit JSON/console logs with optional fan-out to OTEL logs.Refactors configuration to include new runtime settings (
ConsoleLog,AllowedOrigins, stricterModevalidation) and introduces a global config singleton (config.Get/MustGet/Set/Reset) used by the server and telemetry, with new unit tests. The server startup is updated to useserver.New()(no config parameter), installs the observability middleware first, and switches startup/shutdown logging torlog.Updates developer ergonomics/docs via a new
.env.template, README badge/content, and refreshes dependencies (Gin, Confire, Gimlet, OTEL, plus CORS and testing libs).Written by Cursor Bugbot for commit 0b92ee3. Configure here.