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

Adding metadata/labels to a route? #1647

Open
rlipscombe opened this issue Apr 18, 2024 · 2 comments
Open

Adding metadata/labels to a route? #1647

rlipscombe opened this issue Apr 18, 2024 · 2 comments

Comments

@rlipscombe
Copy link

rlipscombe commented Apr 18, 2024

One question that occasionally arises at work is "how do we attach telemetry labels to a cowboy route?". We'd like to be able to attach arbitrary metadata to a route, and have it available in the cowboy_metrics_h callback.

Ideally, it would be an extra element in the route tuple, something like this:

    Dispatch = cowboy_router:compile([
        {'_', [
            {"/", cowboy_static, {priv_file, ?APPLICATION, "index.html"}},
            {"/users/:id", [{id, int}], the_user_h, [], #{labels => #{route => "/users"}}}
        ]}
    ]),

...and would be picked up by the cowboy_router middleware and put in the env along with handler and handler_opts.

(to avoid ambiguity, if you wanted this, you'd have to explicitly specify constraints, possibly empty -- or maybe {Handler, Opts} would need to be a tuple in this case).

Does this seem like a good idea? Is there another way to do it right now?

@rlipscombe
Copy link
Author

I've been wracking my brains for ways to wrap cowboy_router:compile or the cowboy_router middleware, or to wrap the individual handlers, but I can't come up with anything that doesn't feel like a hack.

@rlipscombe
Copy link
Author

After some thought, I've come up with the following, which doesn't require any cowboy changes:

  • Replace the current Handler with a tuple, {Handler, HandlerOpts}
  • Replace the current HandlerOpts with HandlerMetadata.

Add a middleware that goes in between cowboy_router and cowboy_handler that does this:

execute(Req, Env = #{handler := {Handler, HandlerOpts}, handler_opts := Metadata}) ->
    Env2 = Env#{handler => Handler, handler_opts => HandlerOpts, handler_metadata => Metadata},
    {ok, Req, Env2}.

Getting handler_metadata into user_data where the metrics callback can see it is left as an exercise for the reader.

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

No branches or pull requests

1 participant