Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add otel metrics #1314

Merged
merged 21 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,22 @@
suppressResizeObserverIssue();
});

describe('Check data source picker', () => {
it('Index picker should be only available under Otel metric datasource', () => {
cy.get('[data-test-subj="metricsDataSourcePicker"]').click();
cy.get('[data-test-subj="prometheusOption"]').click();
cy.get('[data-test-subj="metricsIndexPicker"]').should('not.exist');

cy.get('[data-test-subj="metricsDataSourcePicker"]').click();
cy.get('[data-test-subj="openTelemetryOption"]').click();
cy.get('[data-test-subj="metricsIndexPicker"]').should('exist');
});
});

describe('Search for metrics in search bar', () => {
it('Search for metrics in search bar from available metrics', () => {
cy.get('[data-test-subj="metricsDataSourcePicker"]').click();
cy.get('[data-test-subj="prometheusOption"]').click();
cy.get('[data-test-subj="metricsSearch"]').type('metric', { wait: 50 });

cy.get('[data-test-subj="metricsListItems_availableMetrics"]')
Expand All @@ -76,6 +90,8 @@

describe('Select and unselect metrics in sidebar', () => {
it('Select and unselect metrics in sidebar', () => {
cy.get('[data-test-subj="metricsDataSourcePicker"]').click();
cy.get('[data-test-subj="prometheusOption"]').click();
cy.get('[data-test-subj="metricsListItems_availableMetrics"]')
.contains(PPL_METRICS_NAMES[0])
.trigger('mouseover')
Expand All @@ -84,7 +100,7 @@
.contains(PPL_METRICS_NAMES[1])
.trigger('mouseover')
.click();
cy.wait(50);
cy.wait(delay/2);
cy.get('[data-test-subj="metricsListItems_selectedMetrics"]')
.contains(PPL_METRICS_NAMES[0])
.should('exist');
Expand All @@ -99,7 +115,7 @@
.contains(PPL_METRICS_NAMES[1])
.trigger('mouseover')
.click();
cy.wait(50);
cy.wait(delay/2);
cy.get('[data-test-subj="metricsListItems_availableMetrics"]')
.contains(PPL_METRICS_NAMES[0])
.trigger('mouseover')
Expand All @@ -113,61 +129,33 @@

describe('Test Metric Visualizations', () => {
beforeEach(() => {
cy.get('[data-test-subj="metricsDataSourcePicker"]').click();
cy.get('[data-test-subj="prometheusOption"]').click();
cy.get('[data-test-subj="metricsListItems_availableMetrics"]')
.contains(PPL_METRICS_NAMES[0])
.trigger('mouseover')
.click();
});

it.only('Resize a Metric visualization in edit mode', () => {
cy.get('[data-test-subj="metrics__editView"]')
.contains('Edit view')
.trigger('mouseover')
.click();
cy.wait(delay);
cy.get('.react-resizable-handle-se')
// .eq(1)
.trigger('mousedown', { which: 1 })
.trigger('mousemove', { clientX: 2000, clientY: 800 })
.trigger('mouseup', { force: true });
cy.wait(delay);
cy.get('[data-test-subj="metrics__saveView"]').trigger('mouseover').click();
cy.wait(delay * 3);
cy.get('div.react-grid-layout>div').invoke('height').should('match', new RegExp('790'));
cy.wait(delay);
});

it('Drag and drop a Metric visualization in edit mode', () => {
cy.get('[data-test-subj="metricsListItems_availableMetrics"]')
.contains(PPL_METRICS_NAMES[1])
.trigger('mouseover')
.click();
cy.get('[data-test-subj="metrics__editView"]')
.contains('Edit view')
.trigger('mouseover')
.click();
cy.wait(delay);
cy.get('h5')

Check warning on line 145 in .cypress/integration/metrics_analytics_test/metrics_analytics.spec.js

View workflow job for this annotation

GitHub Actions / Lint

Do not use force on click and type calls
.contains(PPL_METRICS_NAMES[0])
.trigger('mousedown', { which: 1, force: true })
.trigger('mousemove', { clientX: 415, clientY: 500 })
.trigger('mouseup', { force: true });
cy.wait(delay);
cy.get('[data-test-subj="metrics__saveView"]')
.trigger('mouseover')
.click({ force: true })
.then(() => {
cy.wait(delay * 3);
cy.get('div.react-grid-layout>div')
.eq(1)
.invoke('attr', 'style')
.should('match', new RegExp('(.*)transform: translate((.*)10px)(.*)'));
cy.wait(delay);
});
cy.wait(delay * 3);
cy.get('div.react-grid-layout>div')
.eq(1)
.invoke('attr', 'style')
.should('match', new RegExp('(.*)transform: translate((.*)10px)(.*)'));
});

it('Change date filter of the Metrics home page', () => {
cy.get('.euiButtonEmpty[data-test-subj="superDatePickerToggleQuickMenuButton"]').click({

Check warning on line 158 in .cypress/integration/metrics_analytics_test/metrics_analytics.spec.js

View workflow job for this annotation

GitHub Actions / Lint

Do not use force on click and type calls
force: true,
});
cy.get('.euiLink').contains('This year').trigger('mouseover').click();
Expand All @@ -175,7 +163,6 @@
cy.get('.euiSuperDatePicker__prettyFormat[data-test-subj="superDatePickerShowDatesButton"]')
.contains('This year')
.should('exist');
cy.wait(delay);
});

it('Saves metrics to an existing panel', () => {
Expand All @@ -188,10 +175,10 @@
cy.wait(delay * 3);
moveToMetricsHome();
cy.get('[data-test-subj="metrics__saveManagementPopover"]').trigger('mouseover').click();
cy.get('[data-test-subj="comboBoxSearchInput"]')

Check warning on line 178 in .cypress/integration/metrics_analytics_test/metrics_analytics.spec.js

View workflow job for this annotation

GitHub Actions / Lint

Do not use force on click and type calls
.focus()
.type(TESTING_PANEL, { force: true });
cy.get('[data-test-subj="metrics__SaveConfirm"]').click({ force: true });

Check warning on line 181 in .cypress/integration/metrics_analytics_test/metrics_analytics.spec.js

View workflow job for this annotation

GitHub Actions / Lint

Do not use force on click and type calls
cy.get('.euiToastHeader__title').contains('successfully').should('exist');
});
});
Expand Down Expand Up @@ -228,22 +215,20 @@
delay: 50,
});
cy.get('.euiButton__text').contains('Refresh').trigger('mouseover').click();
cy.wait(delay);
suppressResizeObserverIssue();
cy.get('button[id="main-content-vis"]').contains('Visualizations').trigger('mouseover').click();
cy.wait(delay * 2);
cy.get('[data-test-subj="comboBoxToggleListButton"]').click();
cy.get('[data-test-subj="comboBoxSearchInput"]').focus().type(VIS_TYPE_LINE, { force: true });

Check warning on line 222 in .cypress/integration/metrics_analytics_test/metrics_analytics.spec.js

View workflow job for this annotation

GitHub Actions / Lint

Do not use force on click and type calls
cy.get('[data-test-subj="eventExplorer__saveManagementPopover"]').click({ force: true });

Check warning on line 223 in .cypress/integration/metrics_analytics_test/metrics_analytics.spec.js

View workflow job for this annotation

GitHub Actions / Lint

Do not use force on click and type calls
cy.get('[data-test-subj="eventExplorer__querySaveName"]')

Check warning on line 224 in .cypress/integration/metrics_analytics_test/metrics_analytics.spec.js

View workflow job for this annotation

GitHub Actions / Lint

Do not use force on click and type calls
.focus()
.type(PPL_METRICS_NAMES[metricIndex], { force: true });
cy.get('[data-test-subj="eventExplorer__metricSaveName"]').click({ force: true });

Check warning on line 227 in .cypress/integration/metrics_analytics_test/metrics_analytics.spec.js

View workflow job for this annotation

GitHub Actions / Lint

Do not use force on click and type calls
cy.wait(1000);
cy.wait(delay * 10);
cy.get('[data-test-subj="eventExplorer__querySaveConfirm"]', {
timeout: COMMAND_TIMEOUT_LONG,
}).click();
cy.wait(delay);
cy.get('.euiToastHeader__title').contains('successfully').should('exist');
};

Expand Down
2 changes: 0 additions & 2 deletions .cypress/integration/panels_test/panels.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,6 @@ const createSavedObjectPanel = (newName = TEST_PANEL) => {
};

const addVisualizationsToPanel = (panel, additionalVisualizationIds: string[]) => {
console.log('addVisualizationsToPanel', additionalVisualizationIds);
const additionalVisualizations = additionalVisualizationIds.map((id, idx) => {
return {
savedVisualizationId: `observability-visualization:${id}`,
Expand All @@ -791,7 +790,6 @@ const addVisualizationsToPanel = (panel, additionalVisualizationIds: string[]) =
...panel.attributes.visualizations,
...additionalVisualizations,
];
console.log(panel.attributes);
cy.request({
method: 'PUT',
failOnStatusCode: false,
Expand Down
6 changes: 6 additions & 0 deletions .cypress/utils/metrics_constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@ export const PPL_METRICS = [

export const VIS_TYPE_LINE = 'Time Series';
export const TESTING_PANEL = 'Mock Testing Panels for Metrics';

export const OTEL_METRICS_NAMES = [
'[Otel Metric] ss4o_metrics-otel-dp.duration',
'[Otel Metric] ss4o_metrics-otel-dp.http.client.duration',
'[Otel Metric] ss4o_metrics-otel-dp.rpc.client.duration',
];
19 changes: 19 additions & 0 deletions common/constants/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const PPL_DATASOURCES_REQUEST =
// redux

export const OBSERVABILITY_CUSTOM_METRIC = 'CUSTOM_METRICS';
export const OPEN_TELEMETRY = 'OpenTelemetry';
export const REDUX_SLICE_METRICS = 'metrics';

export const resolutionOptions = [
Expand All @@ -33,3 +34,21 @@ export const AGGREGATION_OPTIONS = [
{ value: 'min', text: 'min()' },
{ value: 'max', text: 'max()' },
];

export const DATASOURCE_OPTIONS = [
{
label: 'Prometheus',
'data-test-subj': 'prometheusOption',
},
{
label: 'OpenTelemetry',
'data-test-subj': 'openTelemetryOption',
},
];
export const DATA_PREPPER_INDEX_NAME = 'ss4o_metrics-*-*';
export const METRICS_ANALYTICS_DATA_PREPPER_INDICES_ROUTE =
'/api/observability/metrics_analytics/data_prepper_indices';

// Regex pattens
export const INDEX_DOCUMENT_NAME_PATTERN = /\[Otel Metric\]\s(\S+?-\S+?)\.(\S+)/;
export const SPAN_RESOLUTION_REGEX = /'(\d+)([smhdwMy])'/;
4 changes: 3 additions & 1 deletion common/constants/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
import CSS from 'csstype';

// Client route
export const PPL_BASE = '/api/ppl';
Expand Down Expand Up @@ -77,9 +76,11 @@ export const PPL_PATTERNS_DOCUMENTATION_URL =
'https://github.com/opensearch-project/sql/blob/2.x/docs/user/ppl/cmd/patterns.rst#description';
export const UI_DATE_FORMAT = 'MM/DD/YYYY hh:mm A';
export const PPL_DATE_FORMAT = 'YYYY-MM-DD HH:mm:ss.SSSSSS';
export const OTEL_DATE_FORMAT = 'YYYY-MM-DDTHH:mm:ss';
export const SPAN_REGEX = /span/;

export const PROMQL_METRIC_SUBTYPE = 'promqlmetric';
export const OTEL_METRIC_SUBTYPE = 'openTelemetryMetric';
export const PPL_METRIC_SUBTYPE = 'metric';

export const PPL_SPAN_REGEX = /by\s*span/i;
Expand Down Expand Up @@ -131,6 +132,7 @@ export enum VIS_CHART_TYPES {
Pie = 'pie',
HeatMap = 'heatmap',
Text = 'text',
Histogram = 'histogram',
}

export const NUMERICAL_FIELDS = ['short', 'integer', 'long', 'float', 'double'];
Expand Down
5 changes: 3 additions & 2 deletions common/types/explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { History } from 'history';
import Plotly from 'plotly.js-dist';
import { QueryManager } from 'common/query_manager';
import { VIS_CHART_TYPES } from '../../common/constants/shared';
import { OTEL_METRIC_SUBTYPE, VIS_CHART_TYPES } from '../../common/constants/shared';
import {
AGGREGATIONS,
AVAILABLE_FIELDS,
Expand Down Expand Up @@ -174,12 +174,13 @@ export interface SavedVisualization extends SavedObjectAttributes {
selected_fields: { text: string; tokens: [] };
selected_timestamp: IField;
type: string;
subType?: 'metric' | 'visualization' | typeof PROMQL_METRIC_SUBTYPE; // exists if sub type is metric
subType?: 'metric' | 'visualization'; // exists if sub type is metric
user_configs?: string;
units_of_measure?: string;
application_id?: string;
dataSources: string; // list of type SelectedDataSources that is stringified
queryLang: string;
metricType?: typeof PROMQL_METRIC_SUBTYPE | typeof OTEL_METRIC_SUBTYPE; // exists if sub type is metric
}

export interface ExplorerDataType {
Expand Down
8 changes: 7 additions & 1 deletion common/types/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import { VisualizationType } from './custom_panels';
type MetricTypes = 'savedCustomMetric' | 'prometheusMetric' | 'openTelemetryMetric';

export interface MetricType extends VisualizationType {
id: string;
Expand All @@ -13,10 +14,15 @@ export interface MetricType extends VisualizationType {
w: number;
h: number;
query: {
type: 'savedCustomMetric' | 'prometheusMetric';
type: MetricTypes;
aggregation: string;
attributesGroupBy: string[];
catalog: string;
availableAttributes?: string[];
};
}

export interface OptionType {
label: string;
'data-test-subj': string;
}
2 changes: 1 addition & 1 deletion public/components/application_analytics/helpers/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ export const calculateAvailability = async (
for (let i = 0; i < savedVisualizationsIds.length; i++) {
const visualizationId = savedVisualizationsIds[i];
// Fetches data for visualization
const visData = await fetchVisualizationById(http, visualizationId, (value: string) =>
const visData = await fetchVisualizationById(visualizationId, (value: string) =>
console.error(value)
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ describe('Query Utils', () => {
span: '1',
resolution: 'h',
};

describe('updateCatalogVisualizationQuery', () => {
it('should build plain promQL series query', () => {
const query = updateCatalogVisualizationQuery(defaultQueryMetaData);
Expand All @@ -125,12 +126,14 @@ describe('Query Utils', () => {
it('should set timestamps and default resolution', () => {
const [startDate, endDate] = ['2023-11-11', '2023-12-11'];
const [start, end] = [1699660800, 1702252800]; // 2023-11-11 to 2023-12-11
const query = preprocessMetricQuery({
metaData: { queryMetaData: defaultQueryMetaData },
const currentQuery =
"source = test_catalog.query_range('count by(one,two) (metric)', 1699660800, 1702252800, '1d')";
const expectedQuery = preprocessMetricQuery({
metaData: { query: currentQuery, queryMetaData: defaultQueryMetaData },
startTime: startDate,
endTime: endDate,
});
expect(query).toMatch(new RegExp(`, ${start}, ${end}, '1d'`));
expect(expectedQuery).toMatch(new RegExp(`, ${start}, ${end}, '1d'`));
});
});
});
Expand Down
Loading
Loading