[Infra] Replace MetricsUIAggregation in favor of estypes.AggregationsAggregate#190495
Conversation
🤖 GitHub commentsExpand to view the GitHub comments
Just comment with:
|
|
/ci |
6467553 to
97610bd
Compare
…-favor-of-estypesaggregationsaggregate
|
/ci |
|
/ci |
crespocarlos
left a comment
There was a problem hiding this comment.
Thanks for this refactoring! I know it's still a draft, but I've left some comments.
Nice that the files in the snapshot folder are already reflecting the changes without having to change them.
| @@ -6,15 +6,12 @@ | |||
| */ | |||
There was a problem hiding this comment.
Apparently, this endpoint is used nowhere 🤔
There was a problem hiding this comment.
Interesting - maybe it was replaced at one point. I will check if I can remove it.
| export const hasAggregations = ( | ||
| aggregations?: Record<string, estypes.AggregationsAggregate> | ||
| ): aggregations is Record<string, estypes.AggregationsAggregate> => { | ||
| return !!(aggregations as Record<string, estypes.AggregationsAggregate>); | ||
| }; | ||
|
|
||
| export const MetricsUIAggregationRT = rt.record(rt.string, ESAggregationRT); | ||
| export type MetricsUIAggregation = rt.TypeOf<typeof MetricsUIAggregationRT>; | ||
| export const hasSnapshotTermsWithAggregation = ( | ||
| termWithAggregation?: unknown | ||
| ): termWithAggregation is SnapshotTermsWithAggregation => { | ||
| return !!(termWithAggregation as SnapshotTermsWithAggregation); | ||
| }; |
There was a problem hiding this comment.
Could these be moved to a helper/utils file?
There was a problem hiding this comment.
Those are removed now as we use the previous rt types for alerts
| @@ -5,35 +5,38 @@ | |||
| * 2.0. | |||
There was a problem hiding this comment.
Can we remove this file? It's a duplicate from metrics_api in metrics_data_access.
| export interface TimeRange { | ||
| from: number; | ||
| to: number; | ||
| interval: string; | ||
| } | ||
|
|
||
| export interface MetricsAPIMetric { | ||
| id: string; | ||
| aggregations: MetricsUIAggregation; | ||
| } | ||
|
|
||
| export interface MetricsAPIRequest { | ||
| timerange: TimeRange; | ||
| indexPattern: string; | ||
| metrics: MetricsAPIMetric[]; | ||
| includeTimeseries: boolean | undefined; | ||
| groupBy?: Array<string | null | undefined>; | ||
| groupInstance?: Array<string | null | undefined>; | ||
| modules?: string[]; | ||
| afterKey?: Record<string, string | null> | null; | ||
| limit?: number | null; | ||
| filters?: Array<Record<string, unknown>>; | ||
| dropPartialBuckets?: boolean; | ||
| alignDataToEnd?: boolean; | ||
| } |
There was a problem hiding this comment.
Perhaps we can leave this typed with io-ts, wdyt? We just need to change aggregations to be an rt.UnkonwnRecord.
I wouldn't be so worried about it being an UnknownRecord because /infra/metrics/metrics_api doesn't seem to be used, so this is just used internally by /metrics_explorer and /snapshot endpoints when they call the query function.
/metrics_explorer builds the object manually in the convertMetricToMetricsAPIMetric function and /snapshot, except for custom metrics, gets the aggregations from inventory_models/<entity_type>/snapshot/ folder. Those metrics will be typed correctly
There was a problem hiding this comment.
I changed that, thanks for the suggestion!
|
|
||
| export type MetricsAPISeries = rt.TypeOf<typeof MetricsAPISeriesRT>; | ||
|
|
||
| export type MetricsAPIRequest = rt.TypeOf<typeof MetricsAPIRequestRT>; |
There was a problem hiding this comment.
Alternatively, if you decide to keep MetricsAPIRequestRT, you can do the following:
export type MetricsAPIRequest = Omit<rt.OutputOf<typeof MetricsAPIRequestRT>, 'metrics'> & {
metrics: Array<MetricsAPIMetric>; // ts type
};It will generate the same typescript type you defined above. This way, internally, anywhere that uses MetricsAPIRequest will be forced to be compatible with MetricsUIAggregation type.
The MetricsAPIRequestRT type in this case is more to validate the request body for the metrics_api endpoint.
There was a problem hiding this comment.
Good point! Changed 👍
| if (hasAggregations(aggregations)) { | ||
| return { id: metric.type, aggregations }; | ||
| } |
There was a problem hiding this comment.
If the aggregation comes from snapshot object, which is a catalog of metrics aggregations we maintain, and it's properly typed, I would say we don't need this if. If it's not a SnapshotCustomMetricInputRT.is(metric) we can return { id: metric.type, aggregations } without this check.
| if (hasAggregations(metric) || metric === undefined) { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
Q: Isn't hasAggregations(metric) redundant, considering the metric is already defined as MetricUIAggregation? Perhaps we could leave just the undefined check here?
There was a problem hiding this comment.
I left only the undefined check 👍
| const values = Object.values(metric); | ||
| return ( | ||
| values.some((agg) => ESTermsWithAggregationRT.is(agg)) && | ||
| values.some((agg) => hasSnapshotTermsWithAggregation(agg)) && |
There was a problem hiding this comment.
Wdyt if we keep ESTermsWithAggregationRT for alerting stuff?
There was a problem hiding this comment.
I was trying that but the issue I faced is that ESTermsWithAggregationRT is still using the aggregation type we replace and if we try to still use it then SnapshotTermsWithAggregation is using already the new MetricsUIAggregation which depends on the estypes (Record<string, estypes.AggregationsAggregate>) and there will be incompatible with the "old" type.
I will think about another way to keep them compatible but so far what I tried was not working
There was a problem hiding this comment.
So I used the old es types and SnapshotTermsWithAggregation renamed to SnapshotTermsWithAggregationForAlerts to keep them the same as before but this will also need refactoring in the future I guess
…place-metricsuiaggregation-in-favor-of-estypesaggregationsaggregate
…-favor-of-estypesaggregationsaggregate
|
Pinging @elastic/obs-ux-infra_services-team (Team:obs-ux-infra_services) |
crespocarlos
left a comment
There was a problem hiding this comment.
Hey! Thanks for the applying the suggestions. I've got a few more. Overall, it's looking good.
| return metrics.reduce((aggs, metric, index) => { | ||
| const aggregation = metricToAggregation(options.nodeType, metric, index); | ||
| if (!MetricsUIAggregationRT.is(aggregation)) { | ||
| if (!!(aggregation as Record<string, estypes.AggregationsAggregate>)) { |
There was a problem hiding this comment.
I guess here we can just check if aggregation is undefined. The only way for aggregation to not be valid is if the metric doesn't exist in the snapshot object for the nodeType.
There was a problem hiding this comment.
it makes sense, changed 👍
| export interface TimeRange { | ||
| from: number; | ||
| to: number; | ||
| interval: string; | ||
| } |
There was a problem hiding this comment.
Is this used? We can remove it in favor of MetricsAPITimerange, wdyt?
| export interface MetricsAPIMetric { | ||
| id: string; | ||
| aggregations: MetricsUIAggregation; | ||
| } |
There was a problem hiding this comment.
Do we need to export this?
There was a problem hiding this comment.
Yes, it is used as a type in different places.
| export interface SnapshotTermsWithAggregationForAlerts { | ||
| terms: { field: string }; | ||
| aggregations: rt.TypeOf<typeof MetricsUIAggregationRT>; | ||
| } |
There was a problem hiding this comment.
We could probably remove this at this point if we change the ESTermsWithAggregationRT and ESAggregationRT types as suggested
| export const ESTermsWithAggregationRT: rt.Type<SnapshotTermsWithAggregationForAlerts> = | ||
| rt.recursion('SnapshotModelRT', () => | ||
| rt.type({ | ||
| terms: rt.type({ field: rt.string }), | ||
| aggregations: MetricsUIAggregationRT, | ||
| }) | ||
| ); | ||
| ); |
There was a problem hiding this comment.
Suggestion: I think we can simplify this and even remove a few things
export const ESTermsWithAggregationRT = rt.type({
terms: rt.type({ field: rt.string }),
aggregations: rt.UnknownRecord,
});We only need the ESTermsWithAggregationRT type to validate one thing in the is_rate function.
is_rate just needs to know whether the object is a terms agg and I think this can be inferred by whether the object has terms and aggregations attributes. So I'd say that it doesn't need to deeply validate the shape of aggregations.
Once that's changed, these could be removed, leaving only those types that is_rate is using.
ESPercentileAggRTESBucketScriptAggRTESCumulativeSumAggRTESCaridnalityAggRTESTopMetricsAggRTESMaxPeriodFilterExistsAggRT
We could even remove ESAggregationRT and MetricsUIAggregationRT altogether because there will be nowhere else using them. Wdyt?
There was a problem hiding this comment.
It gives us the possibility to get rid of a lot of the old aggregation types which is good. As this is not the only validation there and we also check for ESSumBucketAggRT it should be fine to only validate that we have term and aggregations attributes. I applied the suggestion 👍
There was a problem hiding this comment.
Nice! I think now we can safely remove these, can't we?
ESPercentileAggRT
ESBucketScriptAggRT
ESCumulativeSumAggRT
ESCaridnalityAggRT
ESTopMetricsAggRT
ESMaxPeriodFilterExistsAggRT
There was a problem hiding this comment.
Yes, I removed all of the types that are no longer used 👍
|
|
||
| export const isInterfaceRateAgg = (metric: MetricsUIAggregation | undefined) => { | ||
| if (!MetricsUIAggregationRT.is(metric)) { | ||
| if (metric === undefined) { |
There was a problem hiding this comment.
Maybe?
| if (metric === undefined) { | |
| if (!metric) { |
|
|
||
| export const isMetricRate = (metric: MetricsUIAggregation | undefined): boolean => { | ||
| if (!MetricsUIAggregationRT.is(metric)) { | ||
| if (metric === undefined) { |
There was a problem hiding this comment.
Maybe?
| if (metric === undefined) { | |
| if (!metric) { |
…stypesaggregationsaggregate' of https://github.com/jennypavlova/kibana into 190311-infra-replace-metricsuiaggregation-in-favor-of-estypesaggregationsaggregate
…-favor-of-estypesaggregationsaggregate
…-favor-of-estypesaggregationsaggregate
💚 Build Succeeded
Metrics [docs]Module Count
Public APIs missing comments
Async chunks
Public APIs missing exports
Page load bundle
History
To update your PR or re-run it, just comment with: |
crespocarlos
left a comment
There was a problem hiding this comment.
LGTM 💯 ! Thanks for this PR.
kdelemme
left a comment
There was a problem hiding this comment.
ux-logs-management code change looks good to me!
Closes #190311
Summary
This PR replaces
MetricsUIAggregationin favor ofestypes.AggregationsAggregate. Now theMetricsUIAggregationuses estypes.AggregationsAggregate and theMetricsUIAggregationRTis removed which also allows us to remove theESAggregationRT. Instead of maintaining the runtime types we now rely on the types provided by elasticsearch.A follow-up issue will be linked here to address the other aggregation types related changes: #190497
Testing