cdk-monitoring-constructs
Version:
[](https://badge.fury.io/js/cdk-monitoring-constructs) [](https://m
71 lines • 12.6 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApiGatewayMetricFactory = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const common_1 = require("../../common");
const ApiGatewayNamespace = "AWS/ApiGateway";
class ApiGatewayMetricFactory extends common_1.BaseMetricFactory {
constructor(metricFactory, props) {
super(metricFactory, props);
this.fillTpsWithZeroes = props.fillTpsWithZeroes ?? true;
this.rateComputationMethod =
props.rateComputationMethod ?? common_1.RateComputationMethod.AVERAGE;
this.dimensionsMap = {
ApiName: props.api.restApiName,
Stage: props.apiStage ?? props.api.deploymentStage?.stageName ?? "prod",
...(props.apiMethod && { Method: props.apiMethod }),
...(props.apiResource && { Resource: props.apiResource }),
};
}
/**
* @deprecated use metricInvocationRate
*/
metricTps() {
return this.metricInvocationRate(common_1.RateComputationMethod.PER_SECOND);
}
metricInvocationRate(rateComputationMethod) {
return this.metricFactory.toRate(this.metricInvocationCount(), rateComputationMethod ?? this.rateComputationMethod, false, "requests", this.fillTpsWithZeroes);
}
metricInvocationCount() {
return this.metricFactory.createMetric("Count", common_1.MetricStatistic.SUM, "Count", this.dimensionsMap, undefined, ApiGatewayNamespace, undefined, this.region, this.account);
}
metric4XXErrorCount() {
return this.metricFactory.createMetric("4XXError", common_1.MetricStatistic.SUM, "4XX Error", this.dimensionsMap, undefined, ApiGatewayNamespace, undefined, this.region, this.account);
}
metric4XXErrorRate() {
return this.metricFactory.toRate(this.metric4XXErrorCount(), this.rateComputationMethod, false, "errors");
}
metric5XXFaultCount() {
return this.metricFactory.createMetric("5XXError", common_1.MetricStatistic.SUM, "5XX Fault", this.dimensionsMap, undefined, ApiGatewayNamespace, undefined, this.region, this.account);
}
metric5XXFaultRate() {
return this.metricFactory.toRate(this.metric5XXFaultCount(), this.rateComputationMethod, false, "faults");
}
/**
* @deprecated Use {@link metricLatencyInMillis} instead.
*/
metricLatencyP99InMillis() {
return this.metricLatencyInMillis(common_1.LatencyType.P99);
}
/**
* @deprecated Use {@link metricLatencyInMillis} instead.
*/
metricLatencyP90InMillis() {
return this.metricLatencyInMillis(common_1.LatencyType.P90);
}
/**
* @deprecated Use {@link metricLatencyInMillis} instead.
*/
metricLatencyP50InMillis() {
return this.metricLatencyInMillis(common_1.LatencyType.P50);
}
metricLatencyInMillis(latencyType) {
const label = (0, common_1.getLatencyTypeLabel)(latencyType);
return this.metricFactory.createMetric("Latency", (0, common_1.getLatencyTypeStatistic)(latencyType), label, this.dimensionsMap, undefined, ApiGatewayNamespace, undefined, this.region, this.account);
}
}
exports.ApiGatewayMetricFactory = ApiGatewayMetricFactory;
_a = JSII_RTTI_SYMBOL_1;
ApiGatewayMetricFactory[_a] = { fqn: "cdk-monitoring-constructs.ApiGatewayMetricFactory", version: "10.2.0" };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXBpR2F0ZXdheU1ldHJpY0ZhY3RvcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJBcGlHYXRld2F5TWV0cmljRmFjdG9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUdBLHlDQVNzQjtBQUV0QixNQUFNLG1CQUFtQixHQUFHLGdCQUFnQixDQUFDO0FBNkI3QyxNQUFhLHVCQUF3QixTQUFRLDBCQUFpQjtJQUs1RCxZQUNFLGFBQTRCLEVBQzVCLEtBQW1DO1FBRW5DLEtBQUssQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFNUIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxpQkFBaUIsSUFBSSxJQUFJLENBQUM7UUFDekQsSUFBSSxDQUFDLHFCQUFxQjtZQUN4QixLQUFLLENBQUMscUJBQXFCLElBQUksOEJBQXFCLENBQUMsT0FBTyxDQUFDO1FBQy9ELElBQUksQ0FBQyxhQUFhLEdBQUc7WUFDbkIsT0FBTyxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsV0FBVztZQUM5QixLQUFLLEVBQUUsS0FBSyxDQUFDLFFBQVEsSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBRSxTQUFTLElBQUksTUFBTTtZQUN2RSxHQUFHLENBQUMsS0FBSyxDQUFDLFNBQVMsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDbkQsR0FBRyxDQUFDLEtBQUssQ0FBQyxXQUFXLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDO1NBQzFELENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxTQUFTO1FBQ1AsT0FBTyxJQUFJLENBQUMsb0JBQW9CLENBQUMsOEJBQXFCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVELG9CQUFvQixDQUFDLHFCQUE2QztRQUNoRSxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUM5QixJQUFJLENBQUMscUJBQXFCLEVBQUUsRUFDNUIscUJBQXFCLElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUNuRCxLQUFLLEVBQ0wsVUFBVSxFQUNWLElBQUksQ0FBQyxpQkFBaUIsQ0FDdkIsQ0FBQztJQUNKLENBQUM7SUFFRCxxQkFBcUI7UUFDbkIsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FDcEMsT0FBTyxFQUNQLHdCQUFlLENBQUMsR0FBRyxFQUNuQixPQUFPLEVBQ1AsSUFBSSxDQUFDLGFBQWEsRUFDbEIsU0FBUyxFQUNULG1CQUFtQixFQUNuQixTQUFTLEVBQ1QsSUFBSSxDQUFDLE1BQU0sRUFDWCxJQUFJLENBQUMsT0FBTyxDQUNiLENBQUM7SUFDSixDQUFDO0lBRUQsbUJBQW1CO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQ3BDLFVBQVUsRUFDVix3QkFBZSxDQUFDLEdBQUcsRUFDbkIsV0FBVyxFQUNYLElBQUksQ0FBQyxhQUFhLEVBQ2xCLFNBQVMsRUFDVCxtQkFBbUIsRUFDbkIsU0FBUyxFQUNULElBQUksQ0FBQyxNQUFNLEVBQ1gsSUFBSSxDQUFDLE9BQU8sQ0FDYixDQUFDO0lBQ0osQ0FBQztJQUVELGtCQUFrQjtRQUNoQixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUM5QixJQUFJLENBQUMsbUJBQW1CLEVBQUUsRUFDMUIsSUFBSSxDQUFDLHFCQUFxQixFQUMxQixLQUFLLEVBQ0wsUUFBUSxDQUNULENBQUM7SUFDSixDQUFDO0lBRUQsbUJBQW1CO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQ3BDLFVBQVUsRUFDVix3QkFBZSxDQUFDLEdBQUcsRUFDbkIsV0FBVyxFQUNYLElBQUksQ0FBQyxhQUFhLEVBQ2xCLFNBQVMsRUFDVCxtQkFBbUIsRUFDbkIsU0FBUyxFQUNULElBQUksQ0FBQyxNQUFNLEVBQ1gsSUFBSSxDQUFDLE9BQU8sQ0FDYixDQUFDO0lBQ0osQ0FBQztJQUVELGtCQUFrQjtRQUNoQixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUM5QixJQUFJLENBQUMsbUJBQW1CLEVBQUUsRUFDMUIsSUFBSSxDQUFDLHFCQUFxQixFQUMxQixLQUFLLEVBQ0wsUUFBUSxDQUNULENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCx3QkFBd0I7UUFDdEIsT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCx3QkFBd0I7UUFDdEIsT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCx3QkFBd0I7UUFDdEIsT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsb0JBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBRUQscUJBQXFCLENBQUMsV0FBd0I7UUFDNUMsTUFBTSxLQUFLLEdBQUcsSUFBQSw0QkFBbUIsRUFBQyxXQUFXLENBQUMsQ0FBQztRQUMvQyxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUNwQyxTQUFTLEVBQ1QsSUFBQSxnQ0FBdUIsRUFBQyxXQUFXLENBQUMsRUFDcEMsS0FBSyxFQUNMLElBQUksQ0FBQyxhQUFhLEVBQ2xCLFNBQVMsRUFDVCxtQkFBbUIsRUFDbkIsU0FBUyxFQUNULElBQUksQ0FBQyxNQUFNLEVBQ1gsSUFBSSxDQUFDLE9BQU8sQ0FDYixDQUFDO0lBQ0osQ0FBQzs7QUFySUgsMERBc0lDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSVJlc3RBcGkgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWFwaWdhdGV3YXlcIjtcbmltcG9ydCB7IERpbWVuc2lvbnNNYXAgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2hcIjtcblxuaW1wb3J0IHtcbiAgQmFzZU1ldHJpY0ZhY3RvcnksXG4gIEJhc2VNZXRyaWNGYWN0b3J5UHJvcHMsXG4gIGdldExhdGVuY3lUeXBlTGFiZWwsXG4gIGdldExhdGVuY3lUeXBlU3RhdGlzdGljLFxuICBMYXRlbmN5VHlwZSxcbiAgTWV0cmljRmFjdG9yeSxcbiAgTWV0cmljU3RhdGlzdGljLFxuICBSYXRlQ29tcHV0YXRpb25NZXRob2QsXG59IGZyb20gXCIuLi8uLi9jb21tb25cIjtcblxuY29uc3QgQXBpR2F0ZXdheU5hbWVzcGFjZSA9IFwiQVdTL0FwaUdhdGV3YXlcIjtcblxuZXhwb3J0IGludGVyZmFjZSBBcGlHYXRld2F5TWV0cmljRmFjdG9yeVByb3BzIGV4dGVuZHMgQmFzZU1ldHJpY0ZhY3RvcnlQcm9wcyB7XG4gIC8qKlxuICAgKiBBUEkgdG8gbW9uaXRvclxuICAgKi9cbiAgcmVhZG9ubHkgYXBpOiBJUmVzdEFwaTtcbiAgLyoqXG4gICAqIEBkZWZhdWx0IC0gcHJvZFxuICAgKi9cbiAgcmVhZG9ubHkgYXBpU3RhZ2U/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBPbiB1bmRlZmluZWQgdmFsdWUgaXMgbm90IHNldCBpbiBkaW1lbnNpb25zXG4gICAqL1xuICByZWFkb25seSBhcGlNZXRob2Q/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBPbiB1bmRlZmluZWQgdmFsdWUgaXMgbm90IHNldCBpbiBkaW1lbnNpb25zXG4gICAqL1xuICByZWFkb25seSBhcGlSZXNvdXJjZT86IHN0cmluZztcbiAgLyoqXG4gICAqIEBkZWZhdWx0IC0gdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgZmlsbFRwc1dpdGhaZXJvZXM/OiBib29sZWFuO1xuICAvKipcbiAgICogQGRlZmF1bHQgLSBhdmVyYWdlXG4gICAqL1xuICByZWFkb25seSByYXRlQ29tcHV0YXRpb25NZXRob2Q/OiBSYXRlQ29tcHV0YXRpb25NZXRob2Q7XG59XG5cbmV4cG9ydCBjbGFzcyBBcGlHYXRld2F5TWV0cmljRmFjdG9yeSBleHRlbmRzIEJhc2VNZXRyaWNGYWN0b3J5IHtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGZpbGxUcHNXaXRoWmVyb2VzOiBib29sZWFuO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcmF0ZUNvbXB1dGF0aW9uTWV0aG9kOiBSYXRlQ29tcHV0YXRpb25NZXRob2Q7XG4gIHByb3RlY3RlZCByZWFkb25seSBkaW1lbnNpb25zTWFwOiBEaW1lbnNpb25zTWFwO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIG1ldHJpY0ZhY3Rvcnk6IE1ldHJpY0ZhY3RvcnksXG4gICAgcHJvcHM6IEFwaUdhdGV3YXlNZXRyaWNGYWN0b3J5UHJvcHMsXG4gICkge1xuICAgIHN1cGVyKG1ldHJpY0ZhY3RvcnksIHByb3BzKTtcblxuICAgIHRoaXMuZmlsbFRwc1dpdGhaZXJvZXMgPSBwcm9wcy5maWxsVHBzV2l0aFplcm9lcyA/PyB0cnVlO1xuICAgIHRoaXMucmF0ZUNvbXB1dGF0aW9uTWV0aG9kID1cbiAgICAgIHByb3BzLnJhdGVDb21wdXRhdGlvbk1ldGhvZCA/PyBSYXRlQ29tcHV0YXRpb25NZXRob2QuQVZFUkFHRTtcbiAgICB0aGlzLmRpbWVuc2lvbnNNYXAgPSB7XG4gICAgICBBcGlOYW1lOiBwcm9wcy5hcGkucmVzdEFwaU5hbWUsXG4gICAgICBTdGFnZTogcHJvcHMuYXBpU3RhZ2UgPz8gcHJvcHMuYXBpLmRlcGxveW1lbnRTdGFnZT8uc3RhZ2VOYW1lID8/IFwicHJvZFwiLFxuICAgICAgLi4uKHByb3BzLmFwaU1ldGhvZCAmJiB7IE1ldGhvZDogcHJvcHMuYXBpTWV0aG9kIH0pLFxuICAgICAgLi4uKHByb3BzLmFwaVJlc291cmNlICYmIHsgUmVzb3VyY2U6IHByb3BzLmFwaVJlc291cmNlIH0pLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgdXNlIG1ldHJpY0ludm9jYXRpb25SYXRlXG4gICAqL1xuICBtZXRyaWNUcHMoKSB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljSW52b2NhdGlvblJhdGUoUmF0ZUNvbXB1dGF0aW9uTWV0aG9kLlBFUl9TRUNPTkQpO1xuICB9XG5cbiAgbWV0cmljSW52b2NhdGlvblJhdGUocmF0ZUNvbXB1dGF0aW9uTWV0aG9kPzogUmF0ZUNvbXB1dGF0aW9uTWV0aG9kKSB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljRmFjdG9yeS50b1JhdGUoXG4gICAgICB0aGlzLm1ldHJpY0ludm9jYXRpb25Db3VudCgpLFxuICAgICAgcmF0ZUNvbXB1dGF0aW9uTWV0aG9kID8/IHRoaXMucmF0ZUNvbXB1dGF0aW9uTWV0aG9kLFxuICAgICAgZmFsc2UsXG4gICAgICBcInJlcXVlc3RzXCIsXG4gICAgICB0aGlzLmZpbGxUcHNXaXRoWmVyb2VzLFxuICAgICk7XG4gIH1cblxuICBtZXRyaWNJbnZvY2F0aW9uQ291bnQoKSB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljRmFjdG9yeS5jcmVhdGVNZXRyaWMoXG4gICAgICBcIkNvdW50XCIsXG4gICAgICBNZXRyaWNTdGF0aXN0aWMuU1VNLFxuICAgICAgXCJDb3VudFwiLFxuICAgICAgdGhpcy5kaW1lbnNpb25zTWFwLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgQXBpR2F0ZXdheU5hbWVzcGFjZSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHRoaXMucmVnaW9uLFxuICAgICAgdGhpcy5hY2NvdW50LFxuICAgICk7XG4gIH1cblxuICBtZXRyaWM0WFhFcnJvckNvdW50KCkge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY0ZhY3RvcnkuY3JlYXRlTWV0cmljKFxuICAgICAgXCI0WFhFcnJvclwiLFxuICAgICAgTWV0cmljU3RhdGlzdGljLlNVTSxcbiAgICAgIFwiNFhYIEVycm9yXCIsXG4gICAgICB0aGlzLmRpbWVuc2lvbnNNYXAsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICBBcGlHYXRld2F5TmFtZXNwYWNlLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdGhpcy5yZWdpb24sXG4gICAgICB0aGlzLmFjY291bnQsXG4gICAgKTtcbiAgfVxuXG4gIG1ldHJpYzRYWEVycm9yUmF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNGYWN0b3J5LnRvUmF0ZShcbiAgICAgIHRoaXMubWV0cmljNFhYRXJyb3JDb3VudCgpLFxuICAgICAgdGhpcy5yYXRlQ29tcHV0YXRpb25NZXRob2QsXG4gICAgICBmYWxzZSxcbiAgICAgIFwiZXJyb3JzXCIsXG4gICAgKTtcbiAgfVxuXG4gIG1ldHJpYzVYWEZhdWx0Q291bnQoKSB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljRmFjdG9yeS5jcmVhdGVNZXRyaWMoXG4gICAgICBcIjVYWEVycm9yXCIsXG4gICAgICBNZXRyaWNTdGF0aXN0aWMuU1VNLFxuICAgICAgXCI1WFggRmF1bHRcIixcbiAgICAgIHRoaXMuZGltZW5zaW9uc01hcCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIEFwaUdhdGV3YXlOYW1lc3BhY2UsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB0aGlzLnJlZ2lvbixcbiAgICAgIHRoaXMuYWNjb3VudCxcbiAgICApO1xuICB9XG5cbiAgbWV0cmljNVhYRmF1bHRSYXRlKCkge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY0ZhY3RvcnkudG9SYXRlKFxuICAgICAgdGhpcy5tZXRyaWM1WFhGYXVsdENvdW50KCksXG4gICAgICB0aGlzLnJhdGVDb21wdXRhdGlvbk1ldGhvZCxcbiAgICAgIGZhbHNlLFxuICAgICAgXCJmYXVsdHNcIixcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgbWV0cmljTGF0ZW5jeUluTWlsbGlzfSBpbnN0ZWFkLlxuICAgKi9cbiAgbWV0cmljTGF0ZW5jeVA5OUluTWlsbGlzKCkge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY0xhdGVuY3lJbk1pbGxpcyhMYXRlbmN5VHlwZS5QOTkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgbWV0cmljTGF0ZW5jeUluTWlsbGlzfSBpbnN0ZWFkLlxuICAgKi9cbiAgbWV0cmljTGF0ZW5jeVA5MEluTWlsbGlzKCkge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY0xhdGVuY3lJbk1pbGxpcyhMYXRlbmN5VHlwZS5QOTApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgbWV0cmljTGF0ZW5jeUluTWlsbGlzfSBpbnN0ZWFkLlxuICAgKi9cbiAgbWV0cmljTGF0ZW5jeVA1MEluTWlsbGlzKCkge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY0xhdGVuY3lJbk1pbGxpcyhMYXRlbmN5VHlwZS5QNTApO1xuICB9XG5cbiAgbWV0cmljTGF0ZW5jeUluTWlsbGlzKGxhdGVuY3lUeXBlOiBMYXRlbmN5VHlwZSkge1xuICAgIGNvbnN0IGxhYmVsID0gZ2V0TGF0ZW5jeVR5cGVMYWJlbChsYXRlbmN5VHlwZSk7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljRmFjdG9yeS5jcmVhdGVNZXRyaWMoXG4gICAgICBcIkxhdGVuY3lcIixcbiAgICAgIGdldExhdGVuY3lUeXBlU3RhdGlzdGljKGxhdGVuY3lUeXBlKSxcbiAgICAgIGxhYmVsLFxuICAgICAgdGhpcy5kaW1lbnNpb25zTWFwLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgQXBpR2F0ZXdheU5hbWVzcGFjZSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHRoaXMucmVnaW9uLFxuICAgICAgdGhpcy5hY2NvdW50LFxuICAgICk7XG4gIH1cbn1cbiJdfQ==