-
Notifications
You must be signed in to change notification settings - Fork 8.3k
/
Copy pathusage_stats_client.ts
117 lines (107 loc) · 4.32 KB
/
usage_stats_client.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { Headers, ISavedObjectsRepository } from 'src/core/server';
import type { CopyOptions, ResolveConflictsOptions } from '../lib/copy_to_spaces/types';
import { SPACES_USAGE_STATS_ID, SPACES_USAGE_STATS_TYPE } from './constants';
import type { UsageStats } from './types';
interface BaseIncrementOptions {
headers?: Headers;
}
export type IncrementCopySavedObjectsOptions = BaseIncrementOptions &
Pick<CopyOptions, 'createNewCopies' | 'overwrite'>;
export type IncrementResolveCopySavedObjectsErrorsOptions = BaseIncrementOptions &
Pick<ResolveConflictsOptions, 'createNewCopies'>;
export const COPY_STATS_PREFIX = 'apiCalls.copySavedObjects';
export const RESOLVE_COPY_STATS_PREFIX = 'apiCalls.resolveCopySavedObjectsErrors';
export const DISABLE_LEGACY_URL_ALIASES_STATS_PREFIX = 'apiCalls.disableLegacyUrlAliases';
const ALL_COUNTER_FIELDS = [
`${COPY_STATS_PREFIX}.total`,
`${COPY_STATS_PREFIX}.kibanaRequest.yes`,
`${COPY_STATS_PREFIX}.kibanaRequest.no`,
`${COPY_STATS_PREFIX}.createNewCopiesEnabled.yes`,
`${COPY_STATS_PREFIX}.createNewCopiesEnabled.no`,
`${COPY_STATS_PREFIX}.overwriteEnabled.yes`,
`${COPY_STATS_PREFIX}.overwriteEnabled.no`,
`${RESOLVE_COPY_STATS_PREFIX}.total`,
`${RESOLVE_COPY_STATS_PREFIX}.kibanaRequest.yes`,
`${RESOLVE_COPY_STATS_PREFIX}.kibanaRequest.no`,
`${RESOLVE_COPY_STATS_PREFIX}.createNewCopiesEnabled.yes`,
`${RESOLVE_COPY_STATS_PREFIX}.createNewCopiesEnabled.no`,
`${DISABLE_LEGACY_URL_ALIASES_STATS_PREFIX}.total`,
];
export class UsageStatsClient {
constructor(
private readonly debugLogger: (message: string) => void,
private readonly repositoryPromise: Promise<ISavedObjectsRepository>
) {}
public async getUsageStats() {
this.debugLogger('getUsageStats() called');
let usageStats: UsageStats = {};
try {
const repository = await this.repositoryPromise;
const result = await repository.incrementCounter<UsageStats>(
SPACES_USAGE_STATS_TYPE,
SPACES_USAGE_STATS_ID,
ALL_COUNTER_FIELDS,
{ initialize: true }
);
usageStats = result.attributes;
} catch (err) {
// do nothing
}
return usageStats;
}
public async incrementCopySavedObjects({
headers,
createNewCopies,
overwrite,
}: IncrementCopySavedObjectsOptions) {
const isKibanaRequest = getIsKibanaRequest(headers);
const counterFieldNames = [
'total',
`kibanaRequest.${isKibanaRequest ? 'yes' : 'no'}`,
`createNewCopiesEnabled.${createNewCopies ? 'yes' : 'no'}`,
...(!createNewCopies ? [`overwriteEnabled.${overwrite ? 'yes' : 'no'}`] : []), // the overwrite option is ignored when createNewCopies is true
];
await this.updateUsageStats(counterFieldNames, COPY_STATS_PREFIX);
}
public async incrementResolveCopySavedObjectsErrors({
headers,
createNewCopies,
}: IncrementResolveCopySavedObjectsErrorsOptions) {
const isKibanaRequest = getIsKibanaRequest(headers);
const counterFieldNames = [
'total',
`kibanaRequest.${isKibanaRequest ? 'yes' : 'no'}`,
`createNewCopiesEnabled.${createNewCopies ? 'yes' : 'no'}`,
];
await this.updateUsageStats(counterFieldNames, RESOLVE_COPY_STATS_PREFIX);
}
public async incrementDisableLegacyUrlAliases() {
const counterFieldNames = ['total'];
await this.updateUsageStats(counterFieldNames, DISABLE_LEGACY_URL_ALIASES_STATS_PREFIX);
}
private async updateUsageStats(counterFieldNames: string[], prefix: string) {
const options = { refresh: false };
try {
const repository = await this.repositoryPromise;
await repository.incrementCounter(
SPACES_USAGE_STATS_TYPE,
SPACES_USAGE_STATS_ID,
counterFieldNames.map((x) => `${prefix}.${x}`),
options
);
} catch (err) {
// do nothing
}
}
}
function getIsKibanaRequest(headers?: Headers) {
// The presence of these two request headers gives us a good indication that this is a first-party request from the Kibana client.
// We can't be 100% certain, but this is a reasonable attempt.
return headers && headers['kbn-version'] && headers.referer;
}