-
Notifications
You must be signed in to change notification settings - Fork 153
Maintenance: Metrics types and Implementation #1373
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
Comments
Hey Niko, thanks for raising this issue 👍. I assume this is a collection of observations you gained when working on metric resolution PR recently, right? I will dive a bit deeper into the area and will follow up with specifics to untangle all your points. |
Hey Alexander , yes it is from the contribution perspective , in the role of contributor experience . And for 6 there is an existing issue for testing in backlog : #163 . let me know how you would like handle the observations and any further information needed . |
Alexander i have updated the description of 1,2,3,4,5,6 regarding the observations from my metric resolution PR. So 3,4,6 are test observations that provided also as input information to the issue that has focus on testing Nr. 163. and 1,2 relative to types and 5 relative to code comments. |
Hi Niko, thank you for your patience. I'm going to address the different points one by one: 1I see your points and I think there's an opportunity to revisit all the types, their placement, their naming (i.e.
Aside from the larger discussion that I have mentioned above, the linked PR makes 2The While it's true that the method does a number of things, none of these are side effect and all of them are necessary to achieve the final goal: serializing the metrics that are stored into an EMF-compliant blob. For this reason I would prefer not exposing any internal implementation detail in the name nor in the docstrings. As part of the linked PR however I have added some comments to the method and tried to simplify its logic & types used a bit. 3As you mentioned, the When the metric is new - i.e. a metric with the same name is not present in the buffer - then we create a new entry complete with As part of the For instance, let's take the JavaScript code below: const { Metrics, MetricUnits } = require('@aws-lambda-powertools/metrics');
const metrics = new Metrics({ namespace: 'test' });
export const handler = async () => {
metrics.addMetric('test', MetricUnits.Bits, 1); // Using `MetricUnits`
metrics.addMetric('test', 'Bit', 1); // Writing the unit as a string "manually"
metrics.publishStoredMetrics();
}; I don't have visibility over the amount of customers who use JavaScript and don't use an IDE that would flag this, however even if they might be a minority, the example above is why we need that check. 4You are right, it appears that in the case of optional or extra properties, the interface doesn't help. For instance, this correctly warns the user: interface Something {
myMethod(paramA: string): void
}
class Stuff implements Something {
myMethod(paramA: string, paramB: number): void { // IDE complains as `paramB` is not part of the interface
...
}
} While this (which is similar to the case we are discussing), doesn't: interface Something {
myMethod(paramA: string, paramB: number): void
}
class Stuff implements Something {
myMethod(paramA: string): void { // IDE complains
...
}
} I have to admit that I am not 100% sure why this happens. I think it might be related to the If there's a solution, I'd be open to discuss it, but the one you suggest (adding the For now I'd like to defer the discussion to a later time, I have taken note in #617 to see if 5You are right. Comments in this utility are not uniform and could use improvement. Contributors are expected to add comments and maintain existing ones up to date as they change the implementation. Priority is however given to public methods, while private methods are a strongly suggested nice-to-have. The linked PR addresses this point entirely and adds docs for all methods of the class. Hope this helps. 6I acknowledge and accept your feedback about the unit tests not being approachable enough for new contributors. As you have already noticed, there's another ongoing work stream to improve the unit tests structure and style. This is a work that I have decided to prioritize as I considered that before making further improvements/changes, it was important to bring all unit tests to a common baseline. After that PR is merged, we can potentially discuss adding more helper functions and even custom matchers - however I want to be clear since the beginning about a few aspects:
In the future, please consider opening issues that are more focused and clear in their intent. This will definitely help us maintainers and other community members to engage in a more timely manner. In this case however team and I will assume part of the fault for failing to point this out early on and making you wait long. We'll try to do better in the future and either suggest to refine the issue or telling you early on that we are not planning on addressing it. While many of the points brought up in the original issue were valid and valuable, they required a lot of heavy lifting from the reader to be understood, contextualized, and made actionable. It took me almost 5 hours of work to parse everything and come up with this response. |
|
Hello, just wanted to update the discussion to reflect the fact that the team has had a conversation with Niko and agreed that we will try to improve our processes around deciding what kind of topics/discussions are better suited for issues vs discussions. We'll be updating our |
This is now released under v1.9.0 version! |
Summary
High level overview , can be described with details in a time point.
contributor has the intention to extend the functionality of Metrics
Comments of code in areas of Metrics lack of consistency and a contributor cannot derive a pattern to write comments in code when the intention is to add new functionality with comments in code .
Unit Tests of Metrics lack of utilities that can be reused when the intention is to introduce a new test when extending functionality of Metrics
Why is this needed?
High level description of maintenance improvements
e.g: EMF Data Model that is used in Metrics.
Why is needed ? purpose:
It will improve readability and learning for contribution when the EMF Schema as typescript
interface
ortype
is provided.It will also protect from
type/interface explosion
, given a contributor can create similartypes
in the types/Metrics.ts .Use case :
By introducing the
high-resolution
metrics implementation a new type is introduced intypes/Metrics.ts
which is imported inMetrics.ts
implementation .https://github.com/awslabs/aws-lambda-powertools-typescript/blob/79a321b199ef51a024dc25b83673baf2eb03de69/packages/metrics/src/types/Metrics.ts#L71-L75
This
MetricDefinition
type which is in thetypes/Metrics.ts
is referenced in theEmfOutput
typehttps://github.com/awslabs/aws-lambda-powertools-typescript/blob/79a321b199ef51a024dc25b83673baf2eb03de69/packages/metrics/src/types/Metrics.ts#L17-L27
This is a decision made by understanding a pattern during the implementation. The
MetricUnits
were referenced in the EmfOutput type, and as result the MetricDefinition type is created .However the MetricDefinition type has the same meaning as MetricDefinition of EMF Data Model .
The same can happen by combing other properties of Emf Data Model and introduce new type aliases with the same meaning as Emf . That will mean type explosion .
Also a contributor by reading the types/Metrics.ts expects to read about types that support the mechanics of Metrics.ts .
Is the MetricDefinition a type imported in Metrics.ts used in public methods ? Does the MetricDefinition type belong to the types/Metrics.ts ?
Is the mutable EmfOutput type used in Metrics.ts ? As is defined today it is mutable or does the
Output
mean readonly ? . Does the EmfOutput type belong to the types/Metrics.ts ?The index Type
https://github.com/awslabs/aws-lambda-powertools-typescript/blob/79a321b199ef51a024dc25b83673baf2eb03de69/packages/metrics/src/types/Metrics.ts#L67-L69
And the mapReducer
https://github.com/awslabs/aws-lambda-powertools-typescript/blob/79a321b199ef51a024dc25b83673baf2eb03de69/packages/metrics/src/Metrics.ts#L370
And the return Type
EmfOutput
that is produced from serialize can be improved for readability and consistency.not equal
) is used for old metrics.However the units are implemented with structural typing support (enum and type combination). Can a unit of an old metric be inconsistent ?
https://github.com/awslabs/aws-lambda-powertools-typescript/blob/79a321b199ef51a024dc25b83673baf2eb03de69/packages/metrics/src/Metrics.ts#L477-L480
contributor has the intention to extend the functionality of Metrics
Which area does this relate to?
Metrics
Solution
The Emf type could be introduced in a separate artifact Emf.ts
The Emf type could be treated as given in pure Emf format without introducing inside this type new types created in powertools like the use case by introducing new types with the same meaning , MetricDefiniton.
Is a property from emf needed in powertools , then it would improve handling the external dependency to the emf data model and improve readability when the property from the emf type is extracted directly from emf.
Does the MetricDefinition type belong to the types/Metrics.ts ?
This type could be defined inside the Metrics.ts implementation or in a location where it is not exported as part of the types of the metrics package .
Additional
Is the mutable EmfOutput type used in Metrics.ts ? As is defined today it is mutable or does the
Output
mean readonly ?The type of EmfOutput could be made explicit by refactoring as example to :
ReadOnly<Emf>
where Emf is the pure Data Model of EMF as defined by the EMF Schema and ReadOnly is a typerscript utility type (immutalble).Does the
ReadOnly<Emf>
or EmfOutput type belong to the types/Metrics.ts ?This type could be defined inside the Metrics.ts implementation or in a location where it is not exported as part of the types of the metrics package .
considerations:
The index Type for Stored Metrics can be refactored to a Record utility Type from Typescript with static structural support at compilation time.
https://github.com/awslabs/aws-lambda-powertools-typescript/blob/79a321b199ef51a024dc25b83673baf2eb03de69/packages/metrics/src/types/Metrics.ts#L67-L69
And the mapReducer can be made more readable with a Record utility type for Stored Metrics, acting in a role of Store that can be used for mapping to an Emf result.
https://github.com/awslabs/aws-lambda-powertools-typescript/blob/79a321b199ef51a024dc25b83673baf2eb03de69/packages/metrics/src/Metrics.ts#L370
And the return Type
EmfOutput
can be ReadOnly, is produced from serialize, improves readability and consistency.consideration:
Tests for isNewMetric , comparing old and new mertics . Can a unit of an old metric be inconsistent ?
The isNew Metric is implemented as below . The if statement comparison (
not equal
) is used for old metrics.However the units are implemented with structural typing support (enum and type combination).
https://github.com/awslabs/aws-lambda-powertools-typescript/blob/79a321b199ef51a024dc25b83673baf2eb03de69/packages/metrics/src/Metrics.ts#L477-L480
considerations:
addMetric
of Metrics which is defined in the interfaceMetricsInterface
is extended with the new parameter resolution which is optional. The class Metrics that implements theMetricsInterface
does not provide visual feedback about the new optional parameterresolution
, hence optional.However the IDE could have provided visual feedback if in the Metrics Tests, the metrics object is of type MetricsInterface. Hence the abstraction of MetricInterface is expected when extending the unit tests because of the introduction of new functionality that should be implemented in the concrete implementation of Metrics.
considerations:
considerations :
helper functions that can be called in one line for prepare of
unit tests
with meaningful name, likecreateMetric()
,addHighResolutionMetric()
that can be reused in tests and contributors can read the encapsulated code . That can improve readability and learning .Acknowledgment
Future readers
Please react with 👍 and your use case to help us understand customer demand.
The text was updated successfully, but these errors were encountered: