Skip to content

Commit

Permalink
chore: remove usage for stats endpoint (#151082)
Browse files Browse the repository at this point in the history
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Alejandro Fernández Haro <afharo@gmail.com>
  • Loading branch information
3 people committed Feb 27, 2023
1 parent e2219e0 commit fa0a29f
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ describe('Files usage telemetry', () => {
request.post(root, `/api/files/shares/${fileKind}/${file3.id}`).send({}).expect(200),
]);

const { body } = await request.get(root, `/api/stats?extended=true&legacy=true`);
const { body } = await request
.post(root, '/api/telemetry/v2/clusters/_stats')
.send({ unencrypted: true });

expect(body.usage.files).toMatchInlineSnapshot(`
expect(body[0].stats.stack_stats.kibana.plugins.files).toMatchInlineSnapshot(`
Object {
"countByExtension": Array [
Object {
Expand Down
6 changes: 3 additions & 3 deletions src/plugins/usage_collection/server/routes/stats/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ However, the information detailed above can be extended, with the combination of

| Query Parameter | Default value | Description |
|:----------------|:-------------:|:------------|
|`extended`|`false`|When `true`, it adds `clusterUuid` and `usage`. The latter contains the information reported by all the Usage Collectors registered in the Kibana server. It may throw `503 Stats not ready` if any of the collectors is not fully initialized yet.|
|`legacy`|`false`|By default, when `extended=true`, the key names of the data in `usage` are transformed into API-friendlier `snake_case` format (i.e.: `clusterUuid` is transformed to `cluster_uuid`). When this parameter is `true`, the data is returned as-is.|
|`exclude_usage`|`false`|When `true`, and `extended=true`, it will report `clusterUuid` but no `usage`.|
|`extended`|`false`|When `true`, it adds `clusterUuid`.|
|`legacy`|`false`|By default, when `extended=true`, the key names are transformed into API-friendlier `snake_case` format (i.e.: `clusterUuid` is transformed to `cluster_uuid`). When this parameter is `true`, the data is returned as-is.|
|`exclude_usage`|`true`| Deprecated. Only kept for backward-compatibility. Setting this to `false` has no effect. Usage is always excluded. |

## Known use cases

Expand Down
73 changes: 14 additions & 59 deletions src/plugins/usage_collection/server/routes/stats/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@

import { schema } from '@kbn/config-schema';
import { i18n } from '@kbn/i18n';
import defaultsDeep from 'lodash/defaultsDeep';
import { firstValueFrom, Observable } from 'rxjs';

import {
ElasticsearchClient,
IRouter,
type MetricsServiceSetup,
SavedObjectsClientContract,
ServiceStatus,
ServiceStatusLevels,
} from '@kbn/core/server';
Expand Down Expand Up @@ -51,14 +49,6 @@ export function registerStatsRoute({
metrics: MetricsServiceSetup;
overallStatus$: Observable<ServiceStatus>;
}) {
const getUsage = async (
esClient: ElasticsearchClient,
savedObjectsClient: SavedObjectsClientContract
): Promise<UsageObject> => {
const usage = await collectorSet.bulkFetchUsage(esClient, savedObjectsClient);
return collectorSet.toObject(usage);
};

const getClusterUuid = async (asCurrentUser: ElasticsearchClient): Promise<string> => {
const body = await asCurrentUser.info({ filter_path: 'cluster_uuid' });
const { cluster_uuid: uuid } = body;
Expand All @@ -77,69 +67,34 @@ export function registerStatsRoute({
extended: schema.oneOf([schema.literal(''), schema.boolean()], { defaultValue: false }),
legacy: schema.oneOf([schema.literal(''), schema.boolean()], { defaultValue: false }),
exclude_usage: schema.oneOf([schema.literal(''), schema.boolean()], {
defaultValue: false,
defaultValue: true,
}),
}),
},
},
async (context, req, res) => {
const isExtended = req.query.extended === '' || req.query.extended;
const isLegacy = req.query.legacy === '' || req.query.legacy;
const shouldGetUsage = req.query.exclude_usage === false;

let extended;
if (isExtended) {
const core = await context.core;
const { asCurrentUser } = core.elasticsearch.client;
const savedObjectsClient = core.savedObjects.client;

const [usage, clusterUuid] = await Promise.all([
shouldGetUsage
? getUsage(asCurrentUser, savedObjectsClient)
: Promise.resolve<UsageObject>({}),
getClusterUuid(asCurrentUser),
]);

let modifiedUsage = usage;
if (isLegacy) {
// In an effort to make telemetry more easily augmented, we need to ensure
// we can passthrough the data without every part of the process needing
// to know about the change; however, to support legacy use cases where this
// wasn't true, we need to be backwards compatible with how the legacy data
// looked and support those use cases here.
modifiedUsage = Object.keys(usage).reduce((accum, usageKey) => {
if (usageKey === 'kibana') {
accum = {
...accum,
...usage[usageKey],
};
} else if (usageKey === 'reporting') {
accum = {
...accum,
xpack: {
...accum.xpack,
reporting: usage[usageKey],
},
};
} else {
// I don't think we need to it this for the above conditions, but do it for most as it will
// match the behavior done in monitoring/bulk_uploader
defaultsDeep(accum, { [usageKey]: usage[usageKey] });
}

return accum;
}, {} as UsageObject);
const usage = {} as UsageObject;
const clusterUuid = await getClusterUuid(asCurrentUser);

extended = {
usage: modifiedUsage,
clusterUuid,
};
} else {
extended = collectorSet.toApiFieldNames({
usage: modifiedUsage,
clusterUuid,
});
}
// In an effort to make telemetry more easily augmented, we need to ensure
// we can passthrough the data without every part of the process needing
// to know about the change; however, to support legacy use cases where this
// wasn't true, we need to be backwards compatible with how the legacy data
// looked and support those use cases here.
extended = isLegacy
? { usage, clusterUuid }
: collectorSet.toApiFieldNames({
usage,
clusterUuid,
});
}

// Guaranteed to resolve immediately due to replay effect on getOpsMetrics$
Expand Down
3 changes: 3 additions & 0 deletions test/api_integration/apis/stats/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export default function ({ getService }) {
.then(({ body }) => {
expect(body.cluster_uuid).to.be.a('string');
expect(body.usage).to.be.an('object'); // no usage collectors have been registered so usage is an empty object
expect(body.usage).to.eql({});
assertStatsAndMetrics(body);
});
});
Expand All @@ -103,6 +104,7 @@ export default function ({ getService }) {
.then(({ body }) => {
expect(body.cluster_uuid).to.be.a('string');
expect(body.usage).to.be.an('object');
expect(body.usage).to.eql({});
assertStatsAndMetrics(body);
});
});
Expand All @@ -116,6 +118,7 @@ export default function ({ getService }) {
.then(({ body }) => {
expect(body.clusterUuid).to.be.a('string');
expect(body.usage).to.be.an('object'); // no usage collectors have been registered so usage is an empty object
expect(body.usage).to.eql({});
assertStatsAndMetrics(body, true);
});
});
Expand Down

0 comments on commit fa0a29f

Please sign in to comment.