- 
                Notifications
    You must be signed in to change notification settings 
- Fork 4.3k
feat(applicationsignals-alpha): introduce Application Signals SLO L2 constructs #34413
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
feat(applicationsignals-alpha): introduce Application Signals SLO L2 constructs #34413
Conversation
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 pull request linter fails with the following errors:
❌ Features must contain a change to an integration test file and the resulting snapshot.
If you believe this pull request should receive an exemption, please comment and provide a justification. A comment requesting an exemption should contain the text Exemption Request. Additionally, if clarification is needed, add Clarification Request to a comment.
23d98a0    to
    588dc02      
    Compare
  
    …enablement-daemon.js.snapshot/ApplicationSignalsIntegrationECSDaemonDefaultTestDeployAssert0A2A622F.assets.json
…enablement-daemon.js.snapshot/ApplicationSignalsIntegrationECSDaemonDefaultTestDeployAssert0A2A622F.template.json
…enablement-daemon.js.snapshot/asset.a1acfc2b5f4f6b183fd2bb9863f486bc5edef6a357b355a070d9a0e502df418c/__entrypoint__.js
…enablement-daemon.js.snapshot/asset.a1acfc2b5f4f6b183fd2bb9863f486bc5edef6a357b355a070d9a0e502df418c/index.js
…enablement-daemon.js.snapshot/ecs-enablement-integration.assets.json
…enablement-daemon.js.snapshot/ecs-enablement-integration.template.json
…enablement-sidecar.js.snapshot/ApplicationSignalsIntegrationECSSidecarDefaultTestDeployAssert7F3E5290.assets.json
…enablement-sidecar.js.snapshot/ApplicationSignalsIntegrationECSSidecarDefaultTestDeployAssert7F3E5290.template.json
…enablement-sidecar.js.snapshot/ecs-enablement-integration.assets.json
…enablement-sidecar.js.snapshot/ecs-enablement-integration.template.json
| AWS CodeBuild CI Report
 Powered by github-codebuild-logs, available on the AWS Serverless Application Repository | 
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.
Thank you for adding the Application Signals SLO L2 constructs! I've reviewed the code and found a few issues that should be addressed
| import { PeriodBasedAppSignalsMetricProps, PeriodBasedCloudWatchMetricProps, RequestBasedAppSignalsMetricProps, RequestBasedCloudWatchMetricProps } from './metric'; | ||
| import { Resource } from 'aws-cdk-lib'; | ||
| import { Construct } from 'constructs'; | ||
| import * as applicationsignals from 'aws-cdk-lib/aws-applicationsginals'; | 
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.
There's a typo in the import statement: aws-applicationsginals should be aws-applicationsignals
| constructor(props: KeyAttributesProps) { | ||
| this.validateProps(props); | ||
| this.props = props; | ||
| } | 
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.
Consider adding JSDoc comments to explain what this validation is checking for.
| @@ -0,0 +1,134 @@ | |||
| import {Interval} from '../../lib/slo/interval' | |||
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.
Consider adding spaces around the import braces for consistency: import { Interval } from '../../lib/slo/interval'
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.
Thank you for adding the Application Signals SLO L2 constructs! I've reviewed the code and found several issues that should be addressed:
- Naming conventions: Use IServiceLevelObjectivefor the interface andServiceLevelObjectiveBasefor the base class following CDK patterns
- Avoid union types: Replace union types with proper inheritance hierarchies for better JSII compatibility
- Documentation: Add JSDoc comments to all public methods and classes, especially mentioning which CFN resources they represent
- Internal methods: Add @internalannotations to methods not intended for public use
- Structure: Add an index.ts in the slo directory to better organize exports
- Type safety: Define proper return types for methods instead of using any
- Consistency: Make sure interface method names match implementation names (bind vs _bind)
Please address these issues to ensure the code follows CDK best practices and provides a good developer experience.
| export const DEFAULT_GOAL_CONFIG = { | ||
| ATTAINMENT_GOAL: 99.9, | ||
| WARNING_THRESHOLD: 30, | ||
| } as const; | 
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.
Either move these constants as static properties in some class and it is better to be the classes where these values be used, or make them private. Do we need to add these values in CDK Docs, and let the customers use them?
| export * from './enablement/ecs-cloudwatch-agent'; | ||
| export * from './enablement/ecs-sdk-instrumentation'; | ||
| export * from './slo/slo'; | ||
| export * from './slo/slo-types'; | 
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.
Add an index.ts in the slo dir, and expose whatever you want there. Here, add only the directory.
| protected constructor( | ||
| scope: Construct, | ||
| id: string, | ||
| protected readonly props: PeriodBasedSloProps | RequestBasedSloProps | 
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.
We do not recommend using union types. The Props should be of the base type of props, and in general the children classes of this abstract class will forward the concrete props classes. Also add docs.
| /** | ||
| * Base class for all SLO implementations | ||
| */ | ||
| export abstract class ServiceLevelObjective extends Resource implements ISlo { | 
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.
We usually follow the <<CFN Resource Name>>Base naming pattern. Name this as ServiceLevelObjectiveBase.
| props: RequestBasedSloProps | ||
| ): ServiceLevelObjective { | ||
| return new RequestBasedSlo(scope, id, props); | ||
| } | 
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.
Add documentation, these are public functions and we should tell customers what are these functions for.
| * @default - Based on metric type | ||
| */ | ||
| readonly comparisonOperator?: ComparisonOperator; | ||
| } & (ApplicationSignalsMetricProps | CloudWatchMetricProps); | 
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.
Create actual interfaces, we do not support this while translating these types to other languages using JSII.
| return new RollingInterval(props); | ||
| } | ||
|  | ||
| abstract bind(): any; | 
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.
Make it _bind() and also annotated with @internal
| return { | ||
| attainmentGoal: this.props.attainmentGoal ?? DEFAULT_GOAL_CONFIG.ATTAINMENT_GOAL, | ||
| warningThreshold: this.props.warningThreshold ?? DEFAULT_GOAL_CONFIG.WARNING_THRESHOLD, | ||
| interval: this.props.interval._bind(), | 
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.
I believe this is wrong, you defined in the interface as bind not _bind
| return { | ||
| attainmentGoal: this.props.attainmentGoal ?? DEFAULT_GOAL_CONFIG.ATTAINMENT_GOAL, | ||
| warningThreshold: this.props.warningThreshold ?? DEFAULT_GOAL_CONFIG.WARNING_THRESHOLD, | ||
| interval: this.props.interval._bind(), | 
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.
This should be consistent with the interface method name
| startTime: this.startTime, | ||
| }, | ||
| }; | ||
| } | 
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.
What is the returning type?
| })); | ||
| } | ||
|  | ||
| protected getMetricComparisonOperator(metric: PeriodBasedAppSignalsMetricProps | PeriodBasedCloudWatchMetricProps | RequestBasedAppSignalsMetricProps | RequestBasedCloudWatchMetricProps): ComparisonOperator { | 
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.
if it will be internal function, so it is Ok to use union, but if the plan is to export it to function, so replace the union type with a parent type for all of these concrete types
| /** | ||
| * Interface defining SLO behavior and runtime properties | ||
| */ | ||
| export interface ISlo { | 
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.
I believe this is the L2 construct interface, so I prefer use the I<> format. So, it should be IServiceLevelObjective. Also, in comment, mention that this is the Interface for L2 construct of the resource AWS::ApplicationSignals::ServiceLevelObjective
| * | ||
| * @returns The L1 construct properties | ||
| */ | ||
| _bind(): any; | 
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.
I believe we do not need this. If this is the L2, we usually will create the L1 construct in the L2 class' constructor. If I am wrong, and this is needed, please add @internal annotation to it, so we do not expose this function to external customers, and skip adding it in docs.
| * | ||
| * @required | ||
| */ | ||
| readonly name: string; | 
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.
Is it a good idea to auto generate it somehow?
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.
I am going to close the original PR
| This PR has been in the BUILD FAILING state for 3 weeks, and looks abandoned. Note that PRs with failing linting check or builds are not reviewed, please ensure your build is passing To prevent automatic closure: 
 This PR will automatically close in 14 days if no action is taken. | 
| This PR has been deemed to be abandoned, and will be automatically closed. Please create a new PR for these changes if you think this decision has been made in error. | 
| Comments on closed issues and PRs are hard for our team to see. | 
Issue # (if applicable)
Description of changes
This PR adds L2 constructs to simplify the Application Signals slo process. See aws/aws-cdk-rfcs#673 for more details.
Description of how you validated changes
Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license