Skip to content

Commit

Permalink
Add more metrics to frontend (#1326)
Browse files Browse the repository at this point in the history
Signed-off-by: Joshua Li <[email protected]>
  • Loading branch information
joshuali925 authored Dec 8, 2022
1 parent 58a3838 commit 43a8cfe
Show file tree
Hide file tree
Showing 15 changed files with 128 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ export const Search = (props: any) => {
className={`ppl-link ${
uiSettingsService.get('theme:darkMode') ? 'ppl-link-dark' : 'ppl-link-light'
}`}
data-click-metric-element="common.search.ppl_reference"
color="hollow"
onClick={() => showFlyout()}
onClickAriaLabel={'pplLinkShowFlyout'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -414,11 +414,13 @@ exports[`Datagrid component Renders data grid component 1`] = `
>
<EuiButtonIcon
className="euiButtonIcon euiButtonIcon--text"
data-click-metric-element="event_analytics.events_view.toggle_details"
iconType="arrowRight"
onClick={[Function]}
>
<button
className="euiButtonIcon euiButtonIcon--primary euiButtonIcon--empty euiButtonIcon--xSmall euiButtonIcon euiButtonIcon--text"
data-click-metric-element="event_analytics.events_view.toggle_details"
disabled={false}
onClick={[Function]}
type="button"
Expand Down Expand Up @@ -642,11 +644,13 @@ exports[`Datagrid component Renders data grid component 1`] = `
>
<EuiButtonIcon
className="euiButtonIcon euiButtonIcon--text"
data-click-metric-element="event_analytics.events_view.toggle_details"
iconType="arrowRight"
onClick={[Function]}
>
<button
className="euiButtonIcon euiButtonIcon--primary euiButtonIcon--empty euiButtonIcon--xSmall euiButtonIcon euiButtonIcon--text"
data-click-metric-element="event_analytics.events_view.toggle_details"
disabled={false}
onClick={[Function]}
type="button"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ exports[`Datagrid Doc viewer row component Renders Doc viewer row component 1`]
>
<EuiButtonIcon
className="euiButtonIcon euiButtonIcon--text"
data-click-metric-element="event_analytics.events_view.toggle_details"
iconType="arrowRight"
onClick={[Function]}
>
<button
className="euiButtonIcon euiButtonIcon--primary euiButtonIcon--empty euiButtonIcon--xSmall euiButtonIcon euiButtonIcon--text"
data-click-metric-element="event_analytics.events_view.toggle_details"
disabled={false}
onClick={[Function]}
type="button"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export const DocViewRow = forwardRef((props: IDocViewRowProps, ref) => {
<td className="osdDocTableCell__toggleDetails" key={uniqueId('grid-td-')}>
<EuiButtonIcon
className="euiButtonIcon euiButtonIcon--text"
data-click-metric-element="event_analytics.events_view.toggle_details"
onClick={() => {
toggleDetailOpen();
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,12 @@ export const Home = (props: IHomeProps) => {
Use Events Analytics to monitor, correlate, analyze and visualize machine
generated data through Piped Processing Language. Save frequently searched queries
and visualizations for quick access{' '}
<EuiLink external={true} href={EVENT_ANALYTICS_DOCUMENTATION_URL} target="blank">
<EuiLink
data-click-metric-element="event_analytics.learn_more"
external={true}
href={EVENT_ANALYTICS_DOCUMENTATION_URL}
target="blank"
>
Learn more
</EuiLink>
</EuiText>
Expand Down
45 changes: 21 additions & 24 deletions dashboards-observability/server/common/metrics/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,43 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { ComponentType, CounterType } from './types';
import _ from 'lodash';
import { CounterType } from './types';

export const WINDOW = 3600;
export const INTERVAL = 60;
export const CAPACITY = (WINDOW / INTERVAL) * 2;
export const MILLIS_MULTIPLIER = 1000;

export const COMPONENTS = [
'application_analytics',
'operational_panels',
'event_analytics',
'notebooks',
'trace_analytics',
'metrics_analytics',
] as const;
export const REQUESTS = ['create', 'get', 'update', 'delete'] as const;
const commonRequests = ['create', 'get', 'update', 'delete', 'add_samples'] as const;

// object of each component and its specific requests
export const COMPONENTS = {
application_analytics: commonRequests,
operational_panels: [...commonRequests, 'fetch_visualization'],
event_analytics: commonRequests,
notebooks: [...commonRequests, 'run_sql_query', 'run_ppl_query', 'fetch_visualization'],
trace_analytics: commonRequests,
metrics_analytics: commonRequests,
} as const;

export const GLOBAL_BASIC_COUNTER: CounterType = (() => {
const counter = {} as CounterType;
COMPONENTS.forEach((component) => {
counter[component] = {} as CounterType[ComponentType];
REQUESTS.forEach((request) => {
counter[component][request] = {
total: 0,
};
Object.entries(COMPONENTS).forEach(([component, requests]) => {
requests.forEach((request) => {
_.set(counter, [component, request, 'total'], 0);
});
});
return counter;
})();

export const DEFAULT_ROLLING_COUNTER: CounterType = (() => {
const counter = {} as CounterType;
COMPONENTS.forEach((component) => {
counter[component] = {} as CounterType[ComponentType];
REQUESTS.forEach((request) => {
counter[component][request] = {
count: 0,
system_error: 0,
user_error: 0,
};
Object.entries(COMPONENTS).forEach(([component, requests]) => {
requests.forEach((request) => {
_.set(counter, [component, request, 'count'], 0);
_.set(counter, [component, request, 'system_error'], 0);
_.set(counter, [component, request, 'user_error'], 0);
});
});
return counter;
Expand Down
22 changes: 12 additions & 10 deletions dashboards-observability/server/common/metrics/metrics_helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,19 @@ export function addClickToMetric(element: string, counter: CounterNameType = 'co
time2CountWin.set(timeKey, rollingCounter);
}

export function addRequestToMetric(
component: ComponentType,
request: RequestType,
export function addRequestToMetric<T extends ComponentType>(
component: T,
request: RequestType<T>,
error: { statusCode: number }
): void;
export function addRequestToMetric(
component: ComponentType,
request: RequestType,
export function addRequestToMetric<T extends ComponentType>(
component: T,
request: RequestType<T>,
counter: CounterNameType
): void;
export function addRequestToMetric(
component: ComponentType,
request: RequestType,
export function addRequestToMetric<T extends ComponentType>(
component: T,
request: RequestType<T>,
counterNameOrError: CounterNameType | { statusCode: number }
) {
const counter =
Expand All @@ -64,8 +64,10 @@ export function addRequestToMetric(
const timeKey = getKey(Date.now());
const rollingCounter = time2CountWin.get(timeKey) || _.cloneDeep(DEFAULT_ROLLING_COUNTER);

// @ts-ignore not sure why 'request' can't be indexed
rollingCounter[component][request][counter]!++;
if (counter === 'count') {
// @ts-ignore
GLOBAL_BASIC_COUNTER[component][request]['total']!++;
}

Expand Down Expand Up @@ -106,7 +108,7 @@ const getPreKey = (milliseconds: number) => {
};

const isComponent = (arg: string): arg is ComponentType => {
return COMPONENTS.includes(arg as ComponentType);
return Object.keys(COMPONENTS).includes(arg);
};

const buildMetrics = (rollingCounters?: CounterType) => {
Expand Down
8 changes: 4 additions & 4 deletions dashboards-observability/server/common/metrics/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { COMPONENTS, REQUESTS } from './constants';
import { COMPONENTS } from './constants';

export type ComponentType = typeof COMPONENTS[number];
export type RequestType = typeof REQUESTS[number];
export type ComponentType = keyof typeof COMPONENTS;
export type RequestType<T extends ComponentType> = typeof COMPONENTS[T][number];
export type CounterNameType = 'count' | 'system_error' | 'user_error' | 'total';

// counter to track user click actions
Expand All @@ -19,7 +19,7 @@ type ClickCounterType = {
// counter to track requests to OpenSearch
type RequestCounterType = {
[component in ComponentType]: {
[request in RequestType]: {
[request in RequestType<component>]: {
[counter in CounterNameType]?: number;
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import { APP_ANALYTICS_API_PREFIX as API_PREFIX } from '../../../common/constants/application_analytics';
import { ApplicationType } from '../../../common/types/application_analytics';
import { AppAnalyticsAdaptor } from '../../../server/adaptors/application_analytics/app_analytics_adaptor';
import { addRequestToMetric } from '../../common/metrics/metrics_helper';

export function registerAppAnalyticsRouter(router: IRouter) {
const appAnalyticsBackend = new AppAnalyticsAdaptor();
Expand All @@ -29,6 +30,7 @@ export function registerAppAnalyticsRouter(router: IRouter) {
request,
response
): Promise<IOpenSearchDashboardsResponse<any | ResponseError>> => {
addRequestToMetric('application_analytics', 'get', 'count');
const opensearchClient: ILegacyScopedClusterClient = context.observability_plugin.observabilityClient.asScoped(
request
);
Expand All @@ -41,6 +43,7 @@ export function registerAppAnalyticsRouter(router: IRouter) {
},
});
} catch (err: any) {
addRequestToMetric('application_analytics', 'get', err);
console.error('Error occurred while fetching applications', err);
return response.custom({
statusCode: err.statusCode || 500,
Expand All @@ -65,6 +68,7 @@ export function registerAppAnalyticsRouter(router: IRouter) {
request,
response
): Promise<IOpenSearchDashboardsResponse<any | ResponseError>> => {
addRequestToMetric('application_analytics', 'get', 'count');
const opensearchClient: ILegacyScopedClusterClient = context.observability_plugin.observabilityClient.asScoped(
request
);
Expand All @@ -77,6 +81,7 @@ export function registerAppAnalyticsRouter(router: IRouter) {
body: appObject,
});
} catch (err: any) {
addRequestToMetric('application_analytics', 'get', err);
console.error('Error occurred while fetching application', err);
return response.custom({
statusCode: err.statusCode || 500,
Expand Down Expand Up @@ -106,6 +111,7 @@ export function registerAppAnalyticsRouter(router: IRouter) {
request,
response
): Promise<IOpenSearchDashboardsResponse<any | ResponseError>> => {
addRequestToMetric('application_analytics', 'create', 'count');
const opensearchClient: ILegacyScopedClusterClient = context.observability_plugin.observabilityClient.asScoped(
request
);
Expand All @@ -119,6 +125,7 @@ export function registerAppAnalyticsRouter(router: IRouter) {
},
});
} catch (err: any) {
addRequestToMetric('application_analytics', 'get', err);
console.error('Error occurred while creating a new application', err);
return response.custom({
statusCode: err.statusCode || 500,
Expand All @@ -144,6 +151,7 @@ export function registerAppAnalyticsRouter(router: IRouter) {
request,
response
): Promise<IOpenSearchDashboardsResponse<any | ResponseError>> => {
addRequestToMetric('application_analytics', 'update', 'count');
const opensearchClient: ILegacyScopedClusterClient = context.observability_plugin.observabilityClient.asScoped(
request
);
Expand All @@ -160,6 +168,7 @@ export function registerAppAnalyticsRouter(router: IRouter) {
},
});
} catch (err: any) {
addRequestToMetric('application_analytics', 'update', err);
console.error('Error occurred while renaming an existing application', err);
return response.custom({
statusCode: err.statusCode || 500,
Expand Down Expand Up @@ -192,6 +201,7 @@ export function registerAppAnalyticsRouter(router: IRouter) {
request,
response
): Promise<IOpenSearchDashboardsResponse<any | ResponseError>> => {
addRequestToMetric('application_analytics', 'update', 'count');
const opensearchClient: ILegacyScopedClusterClient = context.observability_plugin.observabilityClient.asScoped(
request
);
Expand All @@ -209,6 +219,7 @@ export function registerAppAnalyticsRouter(router: IRouter) {
},
});
} catch (err: any) {
addRequestToMetric('application_analytics', 'update', err);
console.error('Error occurred while updating an existing application', err);
return response.custom({
statusCode: err.statusCode || 500,
Expand All @@ -233,6 +244,7 @@ export function registerAppAnalyticsRouter(router: IRouter) {
request,
response
): Promise<IOpenSearchDashboardsResponse<any | ResponseError>> => {
addRequestToMetric('application_analytics', 'delete', 'count');
const opensearchClient: ILegacyScopedClusterClient = context.observability_plugin.observabilityClient.asScoped(
request
);
Expand All @@ -245,6 +257,7 @@ export function registerAppAnalyticsRouter(router: IRouter) {
body: delResponse,
});
} catch (err: any) {
addRequestToMetric('application_analytics', 'delete', err);
return response.custom({
statusCode: err.statusCode || 500,
body: err.message,
Expand Down
Loading

0 comments on commit 43a8cfe

Please sign in to comment.