Skip to content

feat(metrics): allow setting functionName via constructor parameter and environment variable #3696

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

Conversation

steven10172
Copy link
Contributor

@steven10172 steven10172 commented Mar 4, 2025

Summary

This PR ensures that a manually set functionName is not overwritten by middy and class decorators. If functionName is not already defined a default value of context.functionName will be used with middy and class decorators.

Changes

Please provide a summary of what's being changed

  • Add hasFunctionName() to metrics class to support checking if the functionName is already defined
  • Add functionName to metric constructor to support setting the functionName used for cold starts
  • Add POWERTOOLS_METRICS_FUNCTION_NAME environment variable to support setting the functionName via IaC
  • Do not call setFunctionName with default context.functionName in middy and decorator if functionName is already defined

This PR supports setting a custom functionName to be used with cold starts, that is more stable as context.functionName will change often due to the lambda being replaced when the infrastructure is updated.

Please add the issue number below, if no issue is present the PR might get blocked and not be reviewed

Issue number: #3642


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

@boring-cyborg boring-cyborg bot added documentation Improvements or additions to documentation metrics This item relates to the Metrics Utility tests PRs that add or change tests labels Mar 4, 2025
Copy link

boring-cyborg bot commented Mar 4, 2025

Thanks a lot for your first contribution! Please check out our contributing guidelines and don't hesitate to ask whatever you need.
In the meantime, check out the #typescript channel on our Powertools for AWS Lambda Discord: Invite link

@pull-request-size pull-request-size bot added the size/L PRs between 100-499 LOC label Mar 4, 2025
@steven10172 steven10172 changed the title Improv/metrics no override function name feat(metrics): add ability to pass functionName to middy and decorator Mar 4, 2025
@steven10172
Copy link
Contributor Author

@dreamorosi it looks like one of the tests failed with a network error. Would you mind rerunning it?

@leandrodamascena
Copy link
Contributor

I'm starting the review now.

@dreamorosi dreamorosi removed the request for review from leandrodamascena March 5, 2025 15:21
@dreamorosi dreamorosi self-requested a review March 5, 2025 15:23
dreamorosi

This comment was marked as outdated.

@dreamorosi dreamorosi self-requested a review March 5, 2025 15:37
Copy link
Contributor

@dreamorosi dreamorosi left a comment

Choose a reason for hiding this comment

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

Please ignore my previous review comment.

After looking at the implementation I think we should go back to the drawing board and avoid overcomplicating things.

The function name here refers to the Lambda function resource, not the decorated/wrapped function, so there's no reason for adding a property in every place like we are doing.

I know the discussion in the linked issue went into that direction, but I still stand by my my first proposal in this comment.

With the current implementation, we're introducing some unnecessary complexity, for example what happens if we do this?

const metrics = new Metrics({});
metrics.setFunctionName('foo');

export const handler = middy().use(logMetrics(metrics, { functionName: 'bar' )).handler(async () => {})

Right now bar would silently take precedence. We could add a warning signaling that this is happening, but I think the entire issue would be bypassed by just doing this:

const metrics = new Metrics({
  functionName: 'foo'
});

and potentially deprecating the setFunctionName() method.


Apologies for the confusion and any rework caused, but I think this is the best path forward for customers.

@am29d
Copy link
Contributor

am29d commented Mar 5, 2025

I think the idea with the middy and decorator option is to have one new Metrics() objects that is consumed by many functions, so you have the same configuration for all Lambdas, which have different resource names. If we don't allow middy/decorator function configuration, every function would use the same functionName or you'd need to create 100s of new Metric().

I agree that we need strive for simplicity, and having ENV variable to control this parameter is enough, since it is 1:1 mapping between resource name and environment variable. This means we keep three additions, except the middy/decorator option?

  • .setFunctionName() remains as-is
  • functionName is a Metric constructor parameter
  • The middy handler only sets functionName if it's not defined
  • Support POWERTOOLS_FUNCTION_NAME for better CDK static definition of the value as it's likely a more stable infra value compared to function code

We can still deprecate setFunctionName() in the future in favour of constructor and ENV.

@dreamorosi
Copy link
Contributor

dreamorosi commented Mar 5, 2025

I think the idea with the middy and decorator option is to have one new Metrics() objects that is consumed by many functions

How does that work? This dimension is specifically for the ColdStart metric and there can only ever be 1 handler for each sandbox. Here we are not talking about decorating/wrapping arbitrary functions because this doesn't apply there. So in practice there's only ever a 1:1 mapping between Metrics instance and actual Lambda function handler.

With that said, if you really want to do this, you can use the setFunctionName() method I guess, but I don't think we should add yet another env variable for this. Both the constructor parameter and the method are not opinionated about where the actual runtime value comes from, and customers can easily do this:

const metrics = new Metrics({
  functionName: process.env.FOO
});

// or

metrics.functionName(process.env.FOO);

@dreamorosi
Copy link
Contributor

Hi @steven10172, just wanted to check in to see if you were still interested in completing the PR.

If not, or no longer available (it's fine, things change!), let us know so we can take over the implementation.

@steven10172
Copy link
Contributor Author

I intend to still work on this.

I have no objections to your recommendations and example code. I was not intending to deprecate the other method, but with your buy-in I'm all for it. As I was working through my implementation I recognized there was a non ideal pattern for the non decorator/middy path, thanks for the suggestion of updating the coldstart method.

@pull-request-size pull-request-size bot added size/XL PRs between 500-999 LOC, often PRs that grown with feedback and removed size/L PRs between 100-499 LOC labels Mar 19, 2025
Copy link

Please retry analysis of this Pull-Request directly on SonarQube Cloud

@steven10172 steven10172 requested a review from dreamorosi March 19, 2025 08:50
@dreamorosi
Copy link
Contributor

Thanks for updating the PR, I gave it a quick look and I don't see any major issue.

I'll pull the branch and make a final review tomorrow morning.

dreamorosi
dreamorosi previously approved these changes Mar 20, 2025
Copy link
Contributor

@dreamorosi dreamorosi left a comment

Choose a reason for hiding this comment

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

Thank you for working on this and addressing all our comments throughout the past couple weeks.

I have made a couple small commits to align the PR with the suggested branch, but the logic stays the same.

Copy link
Contributor

@leandrodamascena leandrodamascena left a comment

Choose a reason for hiding this comment

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

Hey @steven10172 and @dreamorosi! Great job you guys did here! I just left 3 comments that at least are worth checking out, so I'm going to request changes.

@dreamorosi dreamorosi merged commit 3176fa0 into aws-powertools:main Mar 20, 2025
41 checks passed
Copy link

boring-cyborg bot commented Mar 20, 2025

Awesome work, congrats on your first merged pull request and thank you for helping improve everyone's experience!

@github-actions github-actions bot added the feature PRs that introduce new features or minor changes label Mar 20, 2025
@steven10172 steven10172 deleted the improv/metrics-no-override-function-name branch March 20, 2025 17:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation feature PRs that introduce new features or minor changes metrics This item relates to the Metrics Utility size/XL PRs between 500-999 LOC, often PRs that grown with feedback tests PRs that add or change tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: Support setting functionName for cold-starts via middy
6 participants